#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define M 3
#define N (M*M)
#define SIZE 362880 //N!
typedef enum
{
LEFT, RIGHT, UP, DOWN
}Towards;
typedef struct
{
int up, down, left, right;
}MatrixStatus;
typedef struct S
{
int index, distance;
struct S *next;
}QueueNode, *QueuePtr;
typedef struct
{
QueuePtr front, rear;
}Queue, *LinkQueue;
void InitQueue(LinkQueue Q)
{
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QueueNode));
Q->front->next = NULL;
}
void DestroyQueue(LinkQueue Q)
{
while (Q->front)
{
Q->rear = Q->front->next;
free(Q->front);
Q->front = Q->rear;
}
}
int QueueEmpty(Queue Q)
{
return Q.front == Q.rear;
}
void EnQueue(LinkQueue Q, int index, int distance)
{
QueuePtr p = (QueuePtr)malloc(sizeof(QueueNode));
p->index = index;
p->distance = distance;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
}
void DeQueue(LinkQueue Q, int *index, int *distance)
{
QueuePtr p = Q->front->next;
*index = p->index;
*distance = p->distance;
Q->front->next = p->next;
if (Q->rear == p) Q->rear = Q->front;
free(p);
}
static int fac[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320 };
/*
* 康托展开
*/
int GetIndex(char *str)
{
int result = 0;
for (int i = 0; i < N; i++)
{
int count = 0;
for (int j = i + 1; j < N; j++)
{
count += str[i] > str[j];
}
result += count * fac[N - i - 1];
}
return result;
}
/*
* 逆康托展开
*/
void UnCantor(char a[N], int x)
{
int i, j, l, t;
char h[N + M] = {0};
for (i = 1; i <= N; i++)
{
t = x / fac[N - i];
x -= t * fac[N - i];
for (j = 1, l = 0; l <= t; j++)
if (!h[j]) l++;
h[--j] = 1;
a[i - 1] = j - 1 + '0';
}
}
void Swap(char *str, int ip, Towards flag)
{
char tmp;
switch (flag)
{
case LEFT:
tmp = str[ip], str[ip] = str[ip - 1], str[ip - 1] = tmp;
break;
case RIGHT:
tmp = str[ip], str[ip] = str[ip + 1], str[ip + 1] = tmp;
break;
case UP:
tmp = str[ip], str[ip] = str[ip - M], str[ip - M] = tmp;
break;
case DOWN:
tmp = str[ip], str[ip] = str[ip + M], str[ip + M] = tmp;
break;
}
}
int FindZero(char *str)
{
for (int i = 0; i < N; i++)
{
if ('0' == str[i]) return i;
}
return -1;
}
void InitArray(MatrixStatus *ans)
{
char str[N];
for (int i = 0; i < SIZE; i++)
{
UnCantor(str, i);
int ip = FindZero(str);
//LEFT
if (ip % M)
{
Swap(str, ip, LEFT);
ans[i].left = GetIndex(str);
Swap(str, ip, LEFT);
}
else ans[i].left = -1;
//RIGHT
if (M - 1 != ip % M)
{
Swap(str, ip, RIGHT);
ans[i].right = GetIndex(str);
Swap(str, ip, RIGHT);
}
else ans[i].right = -1;
//UP
if (M <= ip)
{
Swap(str, ip, UP);
ans[i].up = GetIndex(str);
Swap(str, ip, UP);
}
else ans[i].up = -1;
//DOWN
if (N - M > ip)
{
Swap(str, ip, DOWN);
ans[i].down = GetIndex(str);
Swap(str, ip, DOWN);
}
else ans[i].down = -1;
}
}
int BFS(MatrixStatus *ans, int a, int b)
{
Queue Q;
int tmp = a, index, distance, step = -1;
char *flag = calloc(SIZE, sizeof(char));
flag[tmp] = 1;
InitQueue(&Q);
EnQueue(&Q, tmp, 0);
while (!QueueEmpty(Q))
{
DeQueue(&Q, &index, &distance);
tmp = ans[index].left;
if (-1 != tmp && !flag[tmp])
{
if (tmp == b) break;
EnQueue(&Q, tmp, distance + 1);
flag[tmp] = 1;
}
tmp = ans[index].right;
if (-1 != tmp && !flag[tmp])
{
if (tmp == b) break;
EnQueue(&Q, tmp, distance + 1);
flag[tmp] = 1;
}
tmp = ans[index].up;
if (-1 != tmp && !flag[tmp])
{
if (tmp == b) break;
EnQueue(&Q, tmp, distance + 1);
flag[tmp] = 1;
}
tmp = ans[index].down;
if (-1 != tmp && !flag[tmp])
{
if (tmp == b) break;
EnQueue(&Q, tmp, distance + 1);
flag[tmp] = 1;
}
}
if (!QueueEmpty(Q)) step = distance + 1;
free(flag); DestroyQueue(&Q);
return step;
}
int main(int argc, char *argv[])
{
int a, b, T;
char str[N + 1];
MatrixStatus *ans = calloc(SIZE, sizeof(MatrixStatus));
InitArray(ans);
scanf("%d", &T);
while (T--)
{
scanf("%s", str), scanf("%s", str + 3), scanf("%s", str + 6);
a = GetIndex(str);
scanf("%s", str), scanf("%s", str + 3), scanf("%s", str + 6);
b = GetIndex(str);
printf("%d\n", (a == b) ? 0 : BFS(ans, a, b));
}
free(ans);
return 0;
}