/*
ID: niepeng1
PROG: frameup
LANG: C++
*/
/*
类似拓扑排序问题,easy。
统计矩形的最左,最右,最上,最下。
并统计矩形的遮挡关系,记录下来。
(在该矩形的四个边上,如果有不同的字母
,则记录为该矩形被字母矩形遮挡。)
然后每一次输出一个没有被其他矩形遮挡的矩形
,取消已经输出的矩形对剩余矩形的遮挡,注意此
处需要逆向输出,于是把遮挡关系反着记录,于
是输出时就不用排序了。题目猥琐,方法巧妙。
*/
#include<stdio.h>
#include<memory.h>
#include<algorithm>
char a[32][32];
int h,w,count=0;
bool in[27]={false},yet[27];
int pos[27][4];
bool over[32][32];
char ans[27];
void Out(int num)
{
int i,j;
if( num == count){
ans[count]=0;
printf("%s",ans);
printf("/n");
return;
}
for(i=0;i<26;i++){
if(yet[i]||!in[i])//如果访问过了,或者该字母根本就不在图里面跳过
continue;
for(j=0;j<26;j++)
if(!yet[j] && over[i][j] )
break;//如果存在遮挡关系,放弃
if(j >=26)//如果没有遮挡输出,记录,标记访问过了
{
yet[i]=true;
ans[num]=i+'A';
Out(num+1);
yet[i]=false;
}
}
}
int main()
{
freopen("frameup.in","r",stdin);
freopen("frameup.out","w",stdout);
int i,j;
scanf("%d %d",&h,&w);
for(i=0;i<h;i++)
{
scanf("%s",&a[i]);
}
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
if( a[i][j]<='Z' && a[i][j]>='A'){
if(in[a[i][j]-'A']==false){//碰到新矩形
count++;
in[a[i][j]-'A']=true;
pos[a[i][j]-'A'][0]=pos[a[i][j]-'A'][1]=i;
pos[a[i][j]-'A'][2]=pos[a[i][j]-'A'][3]=j;
}
else{
if(pos[a[i][j]-'A'][0]>i) pos[a[i][j]-'A'][j]=i;//记录矩形的四个边
if(pos[a[i][j]-'A'][1]<i) pos[a[i][j]-'A'][1]=i;
if(pos[a[i][j]-'A'][2]>j) pos[a[i][j]-'A'][2]=j;
if(pos[a[i][j]-'A'][3]<j) pos[a[i][j]-'A'][3]=j;
}
}
}
memset(over,false,sizeof(over));
for(i=0;i<26;i++){//记录遮挡关系
if(in[i]==false)
continue;
for(j=pos[i][2];j<=pos[i][3];j++){
if( a[pos[i][0]][j]<='Z' && a[pos[i][0]][j] >= 'A' && a[pos[i][0]][j]-'A'!=i )
over[a[pos[i][0]][j]-'A'][i]=true;
if( a[pos[i][1]][j]<='Z' && a[pos[i][1]][j] >= 'A' && a[pos[i][1]][j]-'A'!=i )
over[a[pos[i][1]][j]-'A'][i]=true;
}
for(j=pos[i][0];j<=pos[i][1];j++){
if( a[j][pos[i][2]]<='Z' && a[j][pos[i][2]] >= 'A' && a[j][pos[i][2]]-'A'!=i)
over[a[j][pos[i][2]]-'A'][i]=true;
if( a[j][pos[i][3]]<='Z' && a[j][pos[i][3]] >= 'A' && a[j][pos[i][3]]-'A'!=i)
over[a[j][pos[i][3]]-'A'][i]=true;
}
}
memset(yet,false,sizeof(yet));
Out(0);
return 0;
}