/*
IDA*直接TLE
队友说,双向BFS的复杂度是正常BFS的复杂度上开一个根号
改双向BFS的时候存在几个问题。
一,男人每次可以走三步怎么处理。对他这个队列进行三次BFS就可以
原队列里的元素扩展出的新节点往新队列里加,保证对于这一次BFS只走一步,这样三次BFS即走三步
二,鬼魂可以穿墙
三,如何判断鬼魂是否相遇。
如果这次遇不到,下一次进行BFS的时候需要判断当前节点会不会被鬼魂碰到,导致当前节点不能使用
在代码分别注释
*/
#include <bits/stdc++.h>
using namespace std;
#define inf (1000000007)
const int MAXN = 800 + 5;
char g[MAXN][MAXN];
int n, m;
struct Node
{
int x, y;
int flag;
Node(){}
Node(int _x, int _y, int _flag = 0) {x = _x, y = _y, flag = _flag;}
};
queue<Node>que, q[5];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int cost[MAXN][MAXN];
int color[MAXN][MAXN];
int zx[3], zy[3];
int Mahattan(int x1, int y1, int x2, int y2) {return abs(x1 - x2) + abs(y1 - y2);}
bool validPos(int x, int y){if(x >= 1 && x <= n && y >= 1 && y <= m ) return true; else return false;}
bool validZ(int x, int y, int cost)
{
if(2 * cost < Mahattan(x, y, zx[1], zy[1]) && 2 * cost < Mahattan(x, y, zx[2], zy[2])) return true;
else return false;
}
bool bfs(int mark, int dep)
{
while(!que.empty()) que.pop();
while(!q[mark].empty()) {
Node node = q[mark].front(); q[mark].pop();
if(!validZ(node.x, node.y, dep)) continue; ///问题三
for(int i = 0 ; i < 4 ; i++) {
int tx = dx[i] + node.x;
int ty = dy[i] + node.y;
if(!validPos(tx, ty) || g[tx][ty] == 'X' || validZ(tx, ty, dep) == 0) continue;
if(color[tx][ty] == 0) color[tx][ty] = mark, que.push(Node(tx, ty, mark));
else if(color[tx][ty] != mark){
// printf("mark = %d, tx = %d, ty = %d\n", mark, tx, ty);
// printf("s1 = %d, s2 = %d\n", Mahattan(tx, ty, zx[1], zy[1]), Mahattan(tx, ty, zx[2], zy[2]));
return true;
}
}
}
q[mark] = que;
return false;
}
int solve()
{
int ans = 1;
while(!q[1].empty() || !q[2].empty()) {
if(bfs(2, ans)) return ans; ///问题一
if(bfs(2, ans)) return ans;
if(bfs(2, ans)) return ans;
if(bfs(1, ans)) return ans;
ans++;
}
return inf;
}
int main()
{
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 1 ; i <= n ; i++) scanf("%s", g[i] + 1);
int bx, by;
int gx, gy;
zx[1] = -1;
for(int i = 1 ; i <= n ; i++) {
for(int j = 1 ; j <= m ; j++) {
if(g[i][j] == 'M') bx = i, by = j;
else if(g[i][j] == 'G') gx = i, gy = j;
else if(g[i][j] == 'Z') {
if(zx[1] == -1) zx[1] = i, zy[1] = j;
else zx[2] = i, zy[2] = j;
}
}
}
memset(color, 0, sizeof color);
color[bx][by] = 2, color[gx][gy] = 1;
while(!q[1].empty()) q[1].pop();
while(!q[2].empty()) q[2].pop();
q[1].push(Node(gx, gy, 1));
q[2].push(Node(bx, by, 2));
int ans = solve();
if(ans == inf) puts("-1");
else
printf("%d\n", ans);
}
return 0;
}