#include <bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
node() {}
node(int _x,int _y)
{
x = _x;
y = _y;
}
}ghost[1005];
char a[1005][1005];
int vis[2][1005][1005];
int dx[] = {0,1,-1,0};
int dy[] = {1,0,0,-1};
int n,m,cnt;
queue<node>q[2];
bool check(int x,int y,int time)
{
for(int i=0;i<cnt;i++)
{
int tmp = abs(x-ghost[i].x)+abs(y-ghost[i].y);
if(tmp<=2*time)
return false;
}
return true;
}
bool bfs(int type,int time)
{
int res = q[type].size();
while(res--)
{
node now = q[type].front();
q[type].pop();
if(!check(now.x,now.y,time))
continue;
for(int i=0;i<4;i++)
{
int tx = now.x+dx[i];
int ty = now.y+dy[i];
if(tx<0 || tx>=n || ty<0 || ty>=m)
continue;
if(vis[type][tx][ty] || a[tx][ty]=='X')
continue;
if(check(tx,ty,time))
{
if(vis[type^1][tx][ty])
return true;
vis[type][tx][ty] = 1;
q[type].push(node(tx,ty));
}
}
}
return false;
}
int slove(int x1,int y1,int x2,int y2)
{
while(!q[0].empty()) q[0].pop();
while(!q[1].empty()) q[1].pop();
memset(vis,0,sizeof(vis));
q[0].push(node(x1,y1));
q[1].push(node(x2,y2));
vis[0][x1][y1] = 1;
vis[1][x2][y2] = 1;
int time = 0;
while(!q[0].empty() || !q[1].empty())
{
time++;
if(bfs(0,time))
return time;
if(bfs(0,time))
return time;
if(bfs(0,time))
return time;
if(bfs(1,time))
return time;
}
return -1;
}
int main(void)
{
int t;
scanf("%d",&t);
while(t--)
{
cnt = 0;
scanf("%d %d",&n,&m);
int x1,y1,x2,y2;
for(int i=0;i<n;i++)
{
scanf("%s",a[i]);
for(int j=0;j<m;j++)
{
if(a[i][j]=='Z')
ghost[cnt++]= node(i,j);
if(a[i][j]=='M')
x1 = i,y1 = j;
if(a[i][j]=='G')
x2 = i,y2 = j;
}
}
printf("%d\n",slove(x1,y1,x2,y2));
}
return 0;
}