#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std; //用queue一定要用std;
int dir1[4][2]={{0,1},{1,0},{0,-1},{-1,0}},vis[50][50];
int dir2[4][2]={{0,1},{-1,0},{0,-1},{1,0}},r0,c0,rn,cn,row,col;
char maze[50][100];
structpath
{
int rr,cc,step;
};
int DFS (int r0,int c0,int to,int dir[][2])
{
if (r0==rn && c0==cn)
return 1;
int i,way,a,b;
for (i=0;i<4;i++)
{
way=(to+i)%4;
a=r0+dir[way][0];
b=c0+dir[way][1];
if (a>=0 && a<row && b>=0 && b<col && maze[a][b]!='#')
break;
}
return DFS(a,b,(way+3)%4,dir)+1;
}
int BFS()
{
int a,b,i;
memset(vis,0,sizeof (vis));
queue<path> Q;
path curr,next;
curr.cc=c0;
curr.rr=r0;
curr.step=1;
vis[r0][c0]=1;
Q.push(curr);
while (!Q.empty())
{
curr=Q.front();
Q.pop();
if (curr.rr==rn && curr.cc==cn) //第一个满足条件的肯定是最短路径
return curr.step;
for (i=0;i<4;i++) //用队列确实能很好的体现广搜的思想
{
a=curr.rr+dir1[i][0];
b=curr.cc+dir1[i][1];
if (a>=0 && a<row && b>=0 && b<col && maze[a][b]!='#' && !vis[a][b])
{
vis[a][b]=1;
next.rr=a;
next.cc=b;
next.step=curr.step+1;
Q.push(next);
}
}
}
return 90; //貌似这里只是需要一个返回值,多少无所谓。就是少了一个这个,才WA了好几次。
}
int main()
{
int n,i,j;
scanf("%d",&n);
while (n--)
{
scanf("%d%d",&col,&row);getchar();
for (i=0;i<row;i++)
{
scanf("%s",maze[i]);
for (j=0;j<col;j++)
{
if (maze[i][j]=='S')
{r0=i;c0=j;}
if (maze[i][j]=='E')
{rn=i;cn=j;}
}
}
printf("%d %d %d\n",DFS(r0,c0,0,dir1),DFS(r0,c0,0,dir2),BFS());
}
return 0;
}