/*
一个基本的广搜题,事先搜出每个点的最早着火时间,然后对人走出迷宫进行搜索,只要此路可通并且 到达时间小于最小着火时间就可以走。
*/
#include<cstdio>
#include<cstring>#include<queue>
using namespace std;
char s[1010][1010];
int n,m,time[1010][1010];
char s1[1010][1010];
int vis[1010][1010];
int d[2][5]= {{0,0,-1,1},{1,-1,0,0}};
struct F
{
int x,y;
int time;
};
int bfs_time()
{
memset(vis,0,sizeof(vis));
for(int i = 0; i < n; i++)
strcpy(s1[i],s[i]);
queue<F> q;
F p;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
{
if(s1[i][j]=='F')
{
p.x = i;
p.y = j;
p.time = 0;
vis[i][j] = 1;
q.push(p);
}
}
while(!q.empty())
{
p = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int x = p.x+d[0][i];
int y = p.y+d[1][i];
int ti = p.time+1;
if(x >= 0 && y < m && x < n && y>= 0)
{
if(s1[x][y]=='#') continue;
if(!vis[x][y])
{
vis[x][y] = 1;
F ps;
ps.x=x;
ps.y=y;
ps.time = ti;
time[x][y] = min(ti,time[x][y]);
q.push(ps);
}
}
}
}
}
int bfs_solve(int jx,int jy)
{
for(int i = 0; i < n; i++)
strcpy(s1[i],s[i]);
memset(vis,0,sizeof(vis));
queue<F> q;
F p;
p.x = jx;
p.y = jy;
p.time = 0;
q.push(p);
vis[jx][jy] = 1;
while(!q.empty())
{
p = q.front();
q.pop();
if(p.x==0||p.y==0||p.x==n-1||p.y==m-1)
{
printf("%d\n",p.time+1);
return 0;
}
for(int i = 0; i < 4; i++)
{
int x = p.x+d[0][i];
int y = p.y+d[1][i];
int ti = p.time+1;
if(x >= 0 && y < m && x < n && y>= 0)
{
if(s1[x][y]=='.'&&time[x][y]>ti&&!vis[x][y])
{
vis[x][y] = 1;
F ps;
ps.x=x;
ps.y=y;
ps.time = ti;
q.push(ps);
}
}
}
}
printf("IMPOSSIBLE\n");
}
int main()
{
int t,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
for(int i = 0; i < n; i++)
{
scanf("%s",s[i]);
for(int j = 0; j < m; j++)
if(s[i][j]=='J')
{
x = i;
y = j;
break;
}
}
memset(time,0x3f,sizeof(time));
bfs_time();
bfs_solve(x,y);
}
return 0;
}