#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
#define MAX 11
int N,M,T;
int map[MAX][MAX];
int Left[MAX][MAX];
int srow,scol;
int erow,ecol;
int mintime;
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
class Node
{
public:
int row;
int col;
int left_time;
int cost_time;
};
int over(int row,int col)
{
if(row<0||col<0||row>=N||col>=M)
return 1;
return 0;
}
void bfs()
{
queue<Node> q;
Node start;Node N;Node M;
start.row=srow;start.col=scol;
start.left_time=6;start.cost_time=0;
q.push(start);
while(!q.empty())
{
N=q.front();
q.pop();
//如果到达结束,
if(N.row==erow&&N.col==ecol&&N.left_time>0)
{
if(mintime>N.cost_time||mintime==-1)
{
mintime=N.cost_time;
}
}
//如果没有到结束的地方
else
{
int i=0;
for(i=0;i<4;i++)
{
M.row=N.row+dir[i][0];
M.col=N.col+dir[i][1];
M.cost_time=N.cost_time+1;
M.left_time=N.left_time-1;
//如果不超出边界,不是墙的话
if (!over(M.row,M.col)&&map[M.row][M.col]!=0)
{
//如果是定时器
if(map[M.row][M.col]==4)
{
//到定时器的时候还有时间
if(M.left_time>0)
{
//如果费用小
if(Left[M.row][M.col]==-1||M.left_time>Left[M.row][M.col])
{
Left[M.row][M.col]=M.left_time;
M.left_time=6;
q.push(M);
}
}
}
//如果不是定时器
else
{
//如果费用小
if(Left[M.row][M.col]==-1||M.left_time>Left[M.row][M.col])
{
Left[M.row][M.col]=M.left_time;
q.push(M);
}
}
}
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
int i,j;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%d %d",&N,&M);
for(i=0;i<N;i++)
{
for(j=0;j<M;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==2)
{
srow=i;scol=j;
}
else if(map[i][j]==3)
{
erow=i;ecol=j;
}
}
}
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
Left[i][j]=-1;
mintime=-1;
Left[srow][scol]=6;
bfs();
printf("%d\n",mintime);
}
}
return 0;
}