#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include
using namespacestd;
typedeflong longLL;
typedef unsignedlong longULL;#define MAXN 22
#define LLL 1000000000
#define INF 1000000009
#define eps 0.00000001
/*BFS 搜索,在读入图的时候记录abcde所需要的钥匙个数
先BFS一遍,找到所有能找到的钥匙。
然后对于所有的门,如果第一次搜索能到达而且钥匙足够。
把这个门加入队列再搜*/
structnode
{intx, y;
node()= default;
node(int _x,int_y):x(_x),y(_y){}
};
node start,aim;
vector door[5];int key[5], num[5], n, m;//需要的钥匙个数,n行m列
int x[4] = { 0,0,1,-1 }, y[4] = { 1,-1,0,0};boolbeen[MAXN][MAXN];charg[MAXN][MAXN];intcheck()
{for (int i = 0; i < 5; i++)
{if (key[i]>0&&num[i] ==key[i])
{for (int j = 0; j < door[i].size(); j++)
{if(been[door[i][j].x][door[i][j].y])returni;
}
}
}return -1;
}boolBFS(node s)
{
queueq;
been[s.x][s.y]= true;
q.push(s);while (!q.empty())
{
node tmp=q.front();
q.pop();//cout << tmp.x << ' ' << tmp.y << ' '<
if (tmp.x == aim.x&&tmp.y ==aim.y)return true;if ((g[tmp.x][tmp.y] - 'A' >= 0 && g[tmp.x][tmp.y] - 'A'<5)&&(key[g[tmp.x][tmp.y] - 'A']==0||num[g[tmp.x][tmp.y] - 'A'] != key[g[tmp.x][tmp.y] - 'A']))continue;for (int i = 0; i < 4; i++)
{int tx = tmp.x + x[i], ty = tmp.y +y[i];if (tx >= 0 && tx < n& ty >= 0 && ty <= m&&!been[tx][ty]&&((g[tx][ty]=='.'||g[tx][ty]=='G'||g[tx][ty]-'A'>=0&&g[tx][ty]-'A'<5)||(g[tx][ty]-'a'>=0&&g[tx][ty]-'a'<5)))
{if(g[tx][ty] - 'a' >= 0 && g[tx][ty] - 'a'<5)
num[g[tx][ty]- 'a']++;
been[tx][ty]= true;
q.push(node(tx, ty));
}
}
}return false;
}intmain()
{while (scanf("%d%d", &n, &m), n+m)
{bool f = false;
memset(been,false, sizeof(been));
memset(num,0, sizeof(num));
memset(key,0, sizeof(key));for (int i = 0; i < 5; i++)
{
door[i].clear();
}for (int i = 0; i < n; i++)
{
scanf("%s", g[i]);for (int j = 0; j < m; j++)
{if (g[i][j] - 'A' >= 0 && g[i][j] - 'A' < 5)
{
door[g[i][j]- 'A'].push_back(node(i, j));
}else if (g[i][j] - 'a' >= 0 && g[i][j] - 'a' < 5)
{
key[g[i][j]- 'a']++;
}else if (g[i][j] == 'S')
{
start.x= i, start.y =j;
}else if (g[i][j] == 'G')
{
aim.x= i, aim.y =j;
}
}
}if(BFS(start))
{
f= true;
printf("YES\n");continue;
}while (1)
{int k =check();if (k == -1) break;for (int j = 0; j < door[k].size(); j++)
{if(been[door[k][j].x][door[k][j].y])
{if(BFS(door[k][j]))
{
f= true;break;
}
door[k].erase(door[k].begin()+j);
}
}if(f)break;
}if (!f)
printf("NO\n");elseprintf("YES\n");
}return 0;
}