#include <iostream>
#include <cstdio>
#include <sstream>
#include <memory.h>
using namespace std;
const int MAX=100003;
typedef char State[24];
int head1[MAX],next1[MAX],
head2[MAX],next2[MAX];
State q1[MAX],q2[MAX],
ans={0,3,4,3,0,5,6,5,0,1,2,1,0,7,8,7,0,9,10,9,0,1,2,1};
int n,f1,e1,dir1[MAX],dir2[MAX],way1[MAX],way2[MAX],c1[MAX],c2[MAX],
f2,e2,cross;
bool revFlag;
long long maxVal,ttt;
void step1(State &t){
int x1=t[11],x2=t[10];
for(int i=11;i>=2;i--)
t[i]=t[i-2];
t[0]=x2;
t[1]=x1;
t[23]=t[11];
t[22]=t[10];
t[21]=t[9];
}
void step2(State &t){
int x1=t[12],x2=t[13];
for(int i=12;i<22;i++)
t[i]=t[i+2];
t[22]=x1;
t[23]=x2;
t[11]=t[23];
t[10]=t[22];
t[9]=t[21];
}
void step3(State &t){
int x1=t[0],x2=t[1];
for(int i=0;i<10;i++)
t[i]=t[i+2];
t[10]=x1;
t[11]=x2;
t[23]=t[11];
t[22]=t[10];
t[21]=t[9];
}
void step4(State &t){
int x1=t[23],x2=t[22];
for(int i=23;i>13;i--)
t[i]=t[i-2];
t[12]=x2;
t[13]=x1;
t[11]=t[23];
t[10]=t[22];
t[9]=t[21];
}
int hash(const State &t){
int v=0;
for(int i=0;i<24;i++){
v=v*10+t[i];
}
v=v%MAX;
if(v<0)
v+=MAX;
return v;
}
bool tryToInsert(const int &x){
int h=hash(q1[x]),u;
u=head1[h];
while(u){
if(!memcmp(q1[u],q1[x],sizeof(q1[u]))){
return 0;
}
u=next1[u];
}
next1[x]=head1[h];
head1[h]=x;
return 1;
}
bool tryToInsert2(const int &x){
int h=hash(q2[x]),u;
u=head2[h];
while(u){
if(!memcmp(q2[u],q2[x],sizeof(q2[u])))
return 0;
u=next2[u];
}
next2[x]=head2[h];
head2[h]=x;
return 1;
}
int find_res(int x){
int h=hash(q1[x]),u;
u=head2[h];
while(u){
if(!memcmp(q2[u],q1[x],sizeof(q2[u])))
return u;
u=next2[u];
}
return 0;
}
int find_res2(int x){
int h=hash(q2[x]),u;
u=head1[h];
while(u){
if(!memcmp(q2[x],q1[u],sizeof(q1[u]))){
return u;
}
u=next1[u];
}
return 0;
}
long long ansRes1(long long x,int s){
//cout<<"s: "<<s<<" "<<dir1[s]<<endl;
if(s<=1)
return x;
x=ansRes1(x,dir1[s])*10+way1[s];
return x;
}
long long ansRes2(long long x,int s){
if(s<=1)
return x;
x=x*10+way2[s];
return ansRes2(x,dir2[s]);
//ansRes2(dir2[x]);
}
void bfs(){
int t;
memset(head1,0,sizeof(head1));
memset(next1,0,sizeof(next1));
memset(head2,0,sizeof(head2));
memset(next2,0,sizeof(next2));
memset(dir1,0,sizeof(dir1));
memset(dir2,0,sizeof(dir2));
memset(c1,0,sizeof(c1));
memset(way1,0,sizeof(way1));
memset(c2,0,sizeof(c2));
memset(way2,0,sizeof(way2));
f1=1;
e1=2;
f2=1;
e2=2;
c1[1]=c2[1]=0;
memcpy(q2[f2],ans,sizeof(ans));
tryToInsert(f1);
tryToInsert2(f2);
if(find_res2(f2)){
cross=1;
return ;
}
while(c1[f1]+c2[f2]<16){
//if(e1-f1<=e2-f2){
if(c1[f1]<=c2[f2]){
//cout<<"you"<<endl;
memcpy(q1[e1],q1[f1],sizeof(q1[e1]));
step1(q1[e1]);
if(tryToInsert(e1)){
dir1[e1]=f1;
c1[e1]=c1[f1]+1;
way1[e1]=1;
t=find_res(e1);
if(t){
cross=1;
e2=t;
break;
}
++e1;
}
memcpy(q1[e1],q1[f1],sizeof(q1[e1]));
step2(q1[e1]);
if(tryToInsert(e1)){
dir1[e1]=f1;
c1[e1]=c1[f1]+1;
way1[e1]=2;
t=find_res(e1);
if(t){
cross=1;
e2=t;
break;
}
++e1;
}
memcpy(q1[e1],q1[f1],sizeof(q1[e1]));
step3(q1[e1]);
if(tryToInsert(e1)){
dir1[e1]=f1;
c1[e1]=c1[f1]+1;
way1[e1]=3;
t=find_res(e1);
if(t){
cross=1;
e2=t;
break;
}
++e1;
}
memcpy(q1[e1],q1[f1],sizeof(q1[e1]));
step4(q1[e1]);
if(tryToInsert(e1)){
dir1[e1]=f1;
c1[e1]=c1[f1]+1;
way1[e1]=4;
t=find_res(e1);
if(t){
cross=1;
e2=t;
break;
}
++e1;
}
f1++;
}
else{
memcpy(q2[e2],q2[f2],sizeof(q2[e2]));
step3(q2[e2]);
if(tryToInsert2(e2)){
dir2[e2]=f2;
c2[e2]=c2[f2]+1;
way2[e2]=1;
t=find_res2(e2);
if(t){
cross=1;
revFlag=1;
ttt=ansRes2(ansRes1(0,t),e2);
if(ttt<maxVal)
maxVal=ttt;
}
++e2;
}
memcpy(q2[e2],q2[f2],sizeof(q2[e2]));
step4(q2[e2]);
if(tryToInsert2(e2)){
dir2[e2]=f2;
c2[e2]=c2[f2]+1;
way2[e2]=2;
t=find_res2(e2);
if(t){
cross=1;
revFlag=1;
ttt=ansRes2(ansRes1(0,t),e2);
if(ttt<maxVal)
maxVal=ttt;
}
++e2;
}
memcpy(q2[e2],q2[f2],sizeof(q2[e2]));
step1(q2[e2]);
if(tryToInsert2(e2)){
dir2[e2]=f2;
c2[e2]=c2[f2]+1;
way2[e2]=3;
t=find_res2(e2);
if(t){
//cout<<"t1: "<<way1[t]<<endl;
cross=1;
revFlag=1;
ttt=ansRes2(ansRes1(0,t),e2);
if(ttt<maxVal)
maxVal=ttt;
//break;
}
++e2;
}
memcpy(q2[e2],q2[f2],sizeof(q2[e2]));
step2(q2[e2]);
if(tryToInsert2(e2)){
dir2[e2]=f2;
c2[e2]=c2[f2]+1;
way2[e2]=4;
t=find_res2(e2);
if(t){
revFlag=1;
cross=1;
//e1=t;
//cout<<"t4:";
ttt=ansRes2(ansRes1(0,t),e2);
if(ttt<maxVal)
maxVal=ttt;
//ansRes1(e1);
//ansRes2(e2);
//cout<<endl;
//break;
}
++e2;
}
f2++;
}
}
}
int main()
{
freopen("i.txt","r",stdin);
freopen("o","w",stdout);
int t1;
cin>>n;
while(n--){
maxVal=2305843009213693952LL;
cross=revFlag=0;
for(int i=0;i<24;i++){
cin>>t1;
q1[1][i]=t1;
}
bfs();
if(cross){
if(!revFlag&&c1[e1]+c2[e2]==0)
cout<<"PUZZLE ALREADY SOLVED"<<endl;
else{
//cout<<"plus: "<<c1[f1]<<endl;
//cout<<c2[f2]<<endl;
if(!revFlag)
cout<<ansRes2(ansRes1(0,e1),e2)<<endl;
else
cout<<maxVal<<endl;
}
}
else{
cout<<"NO SOLUTION WAS FOUND IN 16 STEPS"<<endl;
}
}
return 0;
}
双广+注意判smallest number