#include <set>
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <queue>
using namespace std;
#define MAX 300
int map[MAX][MAX];
bool visit[MAX][MAX]; // 访问标记
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; // 方向向量 右,左,下,上
int num;
struct data // BFS队列中的状态数据结构
{
int x, y; // 坐标位置
int step; // 搜索步数统计器
int state;
}start, over;
void input_bfs(int row, int column)
{
int flag =0;
int state;
for(int i=1; i<=row; i++)
for(int j=1; j<=column; j++)
{
scanf("%d", &state);
if(state == 2)
{start.x = i; start.y = j; start.state = 2;}
else if(state == 3)
{over.x = i; over.y =j; over.state = 3;}
map[i][j] = state;
}
}
void initialize(int row, int column)
{
memset(map, 0, sizeof(map) );
memset(visit, false, sizeof(visit) );
for(int i=1; i<=row; i++)
for(int j=1; j<=column; j++)
visit[i][j] = true;
num = 0;
}
bool check_bfs(data temp)
{
if(visit[temp.x][temp.y] && map[temp.x][temp.y] ) // 满足条件,根据条件添加
return 1;
else return 0;
}
void bfs(data first)
{
queue<data> que; // BFS队列
data now, next; // 定义2个状态,当前和下一个
first.step = 0; // 计数器清零
int begin = 0;
que.push(first);
visit[first.x][first.y] = 0;
while(!que.empty() )
{
now = que.front(); // 取队首元素进行扩展
if(now.step !=begin) {begin = now.step; num++;}
if(now.x == over.x && now.y == over.y) // 出现目标态,此时为Step的最小值,可以退出即可
{
over.step = now.step; // 做相关处理
return ;
}
if(map[now.x][now.y] == 4 && now.step < 6)
now.step = 0;
for(int i=0; i<4; i++)
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
next.step = now.step +1;
if(check_bfs(next) ) // 如果状态满足约束条件则入队
{
que.push(next);
visit[next.x][next.y] = 0;
}
}
que.pop(); // 队首元素出队
}
return ;
}
int main()
{
freopen("read.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--)
{
int row, column;
scanf("%d%d", &row, &column);
initialize(row, column);
input_bfs(row, column);
bfs(start);
if(over.step < 6)
printf("%d
", num);
else printf("-1
");
}
return 0;
}