

import java.io.*;
import java.util.*;
public class Main
{
static int T,n,m; //T组数据,每组数据是n行m列
static int[] dx = {-1,0,1,0};
static int[] dy = {0,1,0,-1}; //存储偏移量,用于广度优先搜索
static final int N = 210; //数据范围
static char[][] g = new char[N][N]; //用于存储每组数据的值
static int[][] dist = new int[N][N]; //用来表示从起点到dist[i][j]的距离
static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
public static int bfs(PII start)
{
//创建一个队列,进行广度优先搜索
Queue q = new LinkedList();
//先将start放入,再取出,再更新start周围的dist,
//将满足start周围四个数的地点放入队列中,再将这些书重复start的操作
q.offer(start);
//将数组默认赋值为-1
for(int i = 0;i < N;i ++)
for(int j = 0;j < N;j ++)
{
dist[i][j] = -1;
}
//起点为0
dist[start.x][start.y] = 0;
while(!q.isEmpty())
{
PII t = q.poll(); //每次都拿队头,对队头上下左右满足条件的地点更改dist
for(int i = 0;i < 4;i ++)
{
int x = t.x + dx[i];
int y = t.y + dy[i];
if(x < 0 || x >= n || y < 0 || y >= m) continue;
if(g[x][y] == '#') continue; //不需要管墙壁
if(dist[x][y] != -1) continue; //没遍历过才需要更改dist,
//第一次遍历到就是最小距离,不需要更改
dist[x][y] = dist[t.x][t.y] + 1; //将队头周围满足条件的左边更新
if(g[x][y] == 'E') return dist[x][y]; //找到元素后就可以结束循环
//一轮操作后,将队头取出后记得把它周围的点放入尾部
//周围的点也要重复队头的操作
q.offer(new PII(x,y));
}
}
return -1;
}
public static void main(String[] args) throws IOException
{
T = Integer.parseInt(in.readLine());
while(T -- > 0)
{
String[] init = in.readLine().split(" ");
n = Integer.parseInt(init[0]);
m = Integer.parseInt(init[1]);
PII start = null;
for(int i = 0;i < n;i ++)
{
g[i] = in.readLine().toCharArray();
for(int j = 0;j < m;j ++)
{
if(g[i][j] == 'S')
start = new PII(i,j);
}
}
int res = bfs(start);
if(res == -1) System.out.println("oop!");
else System.out.println(res);
}
in.close();
}
}
class PII
{
int x;
int y;
public PII(int x,int y)
{
this.x = x;
this.y = y;
}
}