RT
#include<iostream>
#include<cstring>
using namespace std;
struct Node{int left,right,up,down,row,col;}node[1000006];//结点
struct ST{int id1,id2,id3,id4;};//决策(c,r,w)对应的列号
struct MP{int r,c,w;}mp[5005];//列号对应的决策
ST gt(int r,int c,int w)//转化
{
return {(r-1)*16+w,256+(c-1)*16+w,512+((r-1)/4*4+(c-1)/4)*16+w,768+(r-1)*16+c};
}
const int m=1024;
int cnt;
int row[50000];//每一行第一个元素
int lcnt[50000];//列元素个数
int rcnt;
void build()//初始化
{
for(int i=0;i<=m;++i)
node[i]={i-1,i+1,i,i,0,i};
node[0].left=m;
node[m].right=0;
cnt=m;
}
void finsert(int r,int c)//在DL的(r,c)插入结点
{
int p=++cnt;
node[p].row=r,node[p].col=c;
node[p].up=node[c].up;
node[p].down=c;
node[node[p].up].down=node[node[p].down].up=p;
++lcnt[c];
if(!row[r])
{
node[p].left=node[p].right=p;
row[r]=p;
}
else
{
node[p].left=node[row[r]].left;
node[p].right=row[r];
node[node[p].left].right=node[node[p].right].left=p;
}
}
void fpush(int r,int c,int w)//插入关于决策(r,c,w)的结点
{
ST s=gt(r,c,w);
++rcnt;
mp[rcnt]={r,c,w};
finsert(rcnt,s.id1);
finsert(rcnt,s.id2);
finsert(rcnt,s.id3);
finsert(rcnt,s.id4);
}
void fdel(int c)//删除c列
{
for(int i=node[c].down;i!=c;i=node[i].down)
for(int j=node[i].right;j!=i;j=node[j].right)
{
node[node[j].up].down=node[j].down;
node[node[j].down].up=node[j].up;
--lcnt[node[j].col];
}
node[node[c].left].right=node[c].right;
node[node[c].right].left=node[c].left;
}
void frec(int c)//恢复c列
{
node[node[c].left].right=node[node[c].right].left=c;
for(int i=node[c].down;i!=c;i=node[i].down)
for(int j=node[i].right;j!=i;j=node[j].right)
{
node[node[j].up].down=node[node[j].down].up=j;
++lcnt[node[j].col];
}
}
int ans[5005];
char arr[20][20];
int mxstep;
bool dance(int step)//工作
{
if(!node[0].right)
{
for(int i=1;i<step;++i)
arr[mp[ans[i]].r][mp[ans[i]].c]=mp[ans[i]].w+'A'-1;
return true;
}
int c=node[0].right;
for(int i=node[0].right;i;i=node[i].right)
if(lcnt[i]<lcnt[c])
c=i;
fdel(c);
for(int i=node[c].down;i!=c;i=node[i].down)
{
ans[step]=node[i].row;
for(int j=node[i].right;j!=i;j=node[j].right)
fdel(node[j].col);
if(dance(step+1))return true;
for(int j=node[i].right;j!=i;j=node[j].right)
frec(node[j].col);
}
frec(c);
return false;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
while(cin>>(arr[1]+1))
{
cnt=rcnt=0;
memset(row,0,sizeof row);
memset(lcnt,0,sizeof lcnt);
build();
for(int i=2;i<=16;++i)
cin>>(arr[i]+1);
for(int i=1;i<=16;++i)
for(int j=1;j<=16;++j)
{
if(arr[i][j]!='-')
fpush(i,j,arr[i][j]-'A'+1);//如果有字母了,那么只能有这一个决策
else
for(int k=1;k<=16;++k)
fpush(i,j,k);
}
dance(1);
for(int i=1;i<=16;++i)
cout<<(arr[i]+1)<<'\n';
cout<<'\n';
}
}