/*
给一个n*m的图,F代表起点,G代表充电池,一个充电池只能用一次,但可以用多个充电池,只能把电池充到最大(原始的电量),可以走过不用,D不能走,
问的是把所有的Y走一遍的原始的电量是多少
dp+状态压缩+二分+bfs
dp[i][j]表示的状态是在i状态到达j的最大的电量
*/
给一个n*m的图,F代表起点,G代表充电池,一个充电池只能用一次,但可以用多个充电池,只能把电池充到最大(原始的电量),可以走过不用,D不能走,
问的是把所有的Y走一遍的原始的电量是多少
dp+状态压缩+二分+bfs
dp[i][j]表示的状态是在i状态到达j的最大的电量
*/
#include<stdio.h>
#include<string.h>
#include<queue>
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
using namespace std;
char Map[20][20];
int Map1[20][20],bu[4][2]= {0,1,0,-1,1,0,-1,0},dis[20][20],ac,fis,n,m,dp[1<<16][16],len;//ac记录的是经过起点和所有Y的状态,fis记录的是起点
struct node
{
int x,y,step;
} Node[20];
int bfs(int a,int b)
{
memset(Map1,0,sizeof(Map1));
node l,r,s;
queue<node> v;
s=Node[a];
s.step=0;
Map1[s.x][s.y]=1;
v.push(s);
while(!v.empty())
{
l=v.front();
v.pop();
if(l.x==Node[b].x&&l.y==Node[b].y)
return l.step;
for(int i=0;i<4;i++)
{
int aa=l.x+bu[i][0];
int bb=l.y+bu[i][1];
if(aa>=0&&aa<n&&bb>=0&&bb<m&&Map[aa][bb]!='D'&&Map1[aa][bb]==0)
{
Map1[aa][bb]=1;
r.x=aa;
r.y=bb;
r.step=l.step+1;
v.push(r);
}
}
}
return -1;
}
void Inint()
{
memset(dis,-1,sizeof(dis));
for(int i=0; i<len; i++)
for(int j=i; j<len; j++)
if(i==j)
{
dis[i][j]=0;
dis[j][i]=0;
}
else
{
dis[i][j]=bfs(i,j);
dis[j][i]=dis[i][j];
}
}
int check(int Min)
{
memset(dp,-1,sizeof(dp));
dp[1<<fis][fis]=Min;
for(int i=0;i<(1<<len);i++)//枚举所有的状态
{
for(int j=0;j<len;j++)
{
if((i&(1<<j))==0||dp[i][j]==-1) continue;//判断在i状态时是否经过j,如果不经过j,后者这个状态不能扩展就continue
if((i&ac)==ac&&dp[i][j]!=-1)//判断是否达到最终状态
return 1;
for(int k=0;k<len;k++)
{
if((i&(1<<k))) continue;//排除i状态已经经过k
if(dis[j][k]<0) continue;//j能到达k
int tep=dp[i][j]-dis[j][k];//到达k的后的电量
if(tep<0) continue;
dp[i|(1<<k)][k]=Max(dp[i|(1<<k)][k],tep);
if(Map[Node[k].x][Node[k].y]=='G')
dp[i|(1<<k)][k]=Min;
}
}
}
return 0;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF&&(n+m)!=0)
{
len=0;
ac=0;
for(int i=0; i<n; i++)
{
scanf("%s",Map[i]);
for(int j=0; j<m; j++)
{
if(Map[i][j]=='G')
{
Node[len].x=i;
Node[len++].y=j;
}
else if(Map[i][j]=='F')
{
fis=len;
ac=ac|(1<<len);
Node[len].x=i;
Node[len++].y=j;
}
else if(Map[i][j]=='Y')
{
ac=ac|(1<<len);
Node[len].x=i;
Node[len++].y=j;
}
}
}
Inint();
int l=1,r=225;
int ans=400;
while(l<r)
{
int mid=(l+r)/2;
if(check(mid))
{
ans=Min(ans,mid);
r=mid;
}
else
l=mid+1;
}
if(ans==400)
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}