Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze.
Given Joe’s location in the maze and which squares of the maze are on fire, you must determine whether Joe can exit the maze before the fire reaches him, and how fast he can do it.

Joe and the fire each move one square per minute, vertically or horizontally (not diagonally). The fire spreads all four directions from each square that is on fire. Joe may exit the maze from any square that borders the edge of the maze. Neither Joe nor the fire may enter a square that is occupied by a wall.

Input

The first line of input contains a single integer, the number of test cases to follow.
The first line of each test case contains the two integers RR and CC,separated by spaces, with 1R,C10001 ≤ R, C ≤ 1000. The following RR lines of the test case each contain one row of the maze. Each of these lines contains exactly CC characters, and each of these characters is one of:
• #, a wall
• ‘.’, a passable square
• ‘J’, Joe’s initial position in the maze, which is a passable square
• ‘F’, a square that is on fire
There will be exactly one J in each test case.

Output

For each test case, output a single line containing ‘IMPOSSIBLE’ if Joe cannot exit the maze before the fire reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.

Sample Input

2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
Sample Output
3
IMPOSSIBLE

Translation

给一张地图,一个人站在标为’J’的格点,一些格点标为’F’,是起始的着火点,火势会向上下左右蔓延,人也只能向上下左右四个方向逃窜,火和人每走一格都会消耗一分钟,问人最少花费几分钟逃出地图。

Idea

一次BFSBFS得到火走到地图上各个格子的时间,第二次BFSBFS找人的最短路径,每一个时刻,人要选择火势还没到的格子。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=1003;
//方向向量
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
char G[N][N];//存图
int r,c;
bool vis[N][N];
int step[2][N][N];
int ans;
struct node
{
int x,y;
};
node fire,person;
void bfs_fire()//找到各个点起火的最短时间
{
queue<node>q;
memset(vis,0,sizeof(vis));
int i,j;
for(i=1;i<=r;i++)
{
for(j=1;j<=c;j++)
{
switch(G[i][j])
{
case 'F':
vis[i][j]=1;
fire.x=i;
fire.y=j;
q.push(fire);//将所有起火点入队
break;
default: break;
}
}
}
while(!q.empty())
{
node now,nxt;
now=q.front();
int i;
//枚举四个方向
for(i=0;i<4;i++)
{
nxt.x=now.x+dx[i];
nxt.y=now.y+dy[i];
if(nxt.x<1||nxt.x>r) continue;
else if(nxt.y<1||nxt.y>c) continue;
else if(G[nxt.x][nxt.y]=='#') continue;
else if(vis[nxt.x][nxt.y]) continue;
else
{
q.push(nxt);
vis[nxt.x][nxt.y]=1;
step[0][nxt.x][nxt.y]=step[0][now.x][now.y]+1;
}
}
q.pop();
}
}
void bfs_person()
{
queue<node>q;
memset(vis,0,sizeof(vis));
vis[person.x][person.y]=1;
q.push(person);//起始点入队
while(!q.empty())
{
int i;
node now,nxt;
now=q.front();
for(i=0;i<4;i++)
{
//枚举四个方向
nxt.x=now.x+dx[i];
nxt.y=now.y+dy[i];
if(nxt.x<1||nxt.x>r) continue;
else if(nxt.y<1||nxt.y>c) continue;
else if(vis[nxt.x][nxt.y]) continue;
else if (G[nxt.x][nxt.y]=='#'||G[nxt.x][nxt.y]=='F') continue;
/*
如果step[0][nxt.x][nxt.y]==0说明不能走到
要在火来临前走到该格点,如果不能则continue
*/
if(step[0][nxt.x][nxt.y]!=0&&step[0][nxt.x][nxt.y]<=step[1][now.x][now.y]+1) continue;
else
{
step[1][nxt.x][nxt.y]=step[1][now.x][now.y]+1;
//走到边界
if(nxt.x==1||nxt.x==r||nxt.y==c||nxt.y==1)
{
ans=step[1][nxt.x][nxt.y]+1;
return;
}
else
{
vis[nxt.x][nxt.y]=1;
q.push(nxt);
}
}
}
q.pop();//出队
}
}
void init()//初始化
{
memset(step,0,sizeof(step));
ans=-1;
}
void solve()
{
init();
int i,j;
cin>>r>>c;
for(i=1;i<=r;i++)
{
for(j=1;j<=c;j++)
{
cin>>G[i][j];
switch(G[i][j])
{
case 'J':
person.x=i;
person.y=j;
step[1][i][j]=0;
break;
default: break;
}
}
}
if(person.x==1||person.x==r||person.y==c||person.y==1) ans=1;//特判
else//两次BFS
{
bfs_fire();
bfs_person();
}
if(ans==-1) puts("IMPOSSIBLE");//没有被更新
else cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}