/*
http://acm.pku.edu.cn/JudgeOnline/problem?id=3026
题目大意:求从集合(刚开始只有S点)出发到所有A,不计算重复路径,只要到达一个A,就把该A点加入到集合中。其实就是求一个包含所有点的最小生成树。
算法:把S点和A点当做一样,计算两两之间的最短距离,由于有路障“#”的存在,所以采用广搜进行计算。(本来觉得如果已经计算了i到j,则不用再计算j到i,但事实上用广搜的话,这个步骤是不能省的)。然后就用prim计算最小生成树,就可以了。
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<functional>
using namespace std;
const int INF=(1<<31)-1;
const double EPS=1e-8;
const int N=110;
int path[N][N];
char str[N][N];
bool v[N][N];
int n,m;
int num=0;
struct P
{
int x,y;
}p[N];
int X[3000];
int Y[3000];
int S[3000];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
int start;
bool check(int x,int y)
{
if(x<0||x>m||y<0||y>n)return false;
if(str[x][y]=='#')return false;
return true;
}
int prim(int s)
{
int ans=0;
int d[N];
for(int i=0;i<num;i++)d[i]=INF;
d[s]=0;
bool vv[num];
memset(vv,false,sizeof(vv));
for(int i=0;i<num;i++)
{
int mark=-1;
int Min=INF;
for(int j=0;j<num;j++)
if(!vv[j]&&d[j]<Min){Min=d[j];mark=j;}
if(mark==-1)return -1;
vv[mark]=true;
ans+=Min;
for(int j=0;j<num;j++)
if(!vv[j]&&d[j]>path[mark][j])d[j]=path[mark][j];
}
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
num=0;
gets(str[0]);
for(int i=0;i<m;i++)gets(str[i]);
for(int i=0;i<m;i++)
{
int len=strlen(str[i]);
for(int j=0;j<len;j++)
{
if(str[i][j]=='A')
{
p[num].x=i;
p[num++].y=j;
}
else if(str[i][j]=='S')
{
start=num;
p[num].x=i;
p[num++].y=j;
}
}
}
for(int i=0;i<num;i++)
for(int j=0;j<num;j++)
path[i][j]=INF;
for(int i=0;i<num;i++)//对每个节点i进行广搜
{
int front=0,end=1;
memset(v,false,sizeof(v));
v[p[i].x][p[i].y]=true;
X[front]=p[i].x;
Y[front]=p[i].y;
//cout<<p[i].x<<" "<<p[i].y<<endl;
S[front]=0;
int find=0;
while(front<end)
{
int xx=X[front];
int yy=Y[front];
for(int j=0;j<num;j++)
{
if(i!=j&&xx==p[j].x&&yy==p[j].y){path[i][j]=S[front];find++;break;}
}
if(find==num-1)break;
for(int j=0;j<4;j++)
{
int tx=xx+dx[j];
int ty=yy+dy[j];
if(check(tx,ty)&&!v[tx][ty])
{
X[end]=tx;
Y[end]=ty;
S[end]=S[front]+1;
end++;
v[tx][ty]=true;
}
}
front++;
}
}
/*
for(int i=0;i<num;i++)
{
for(int j=0;j<num;j++)
cout<<path[i][j]<<" ";
cout<<endl;
}
*/
cout<<prim(start)<<endl;
}
//system("pause");
return 0;
}