#include<bits/stdc++.h>
using namespace std;
const int N=17;
string s;
int LOG[1<<16],mx_dfs,popc[1<<16];
char a[N][N];
int can_put_in[N][N];
inline void put_a_number_in(int x,int y,int z){
for(int i=1;i<=16;i++){
can_put_in[x][i]&=~(1<<z);
can_put_in[i][y]&=~(1<<z);
}
int case_x=(x-1)/4*4+1,case_y=(y-1)/4*4+1;
for(int i=case_x;i<case_x+4;i++)for(int j=case_y;j<case_y+4;j++){
can_put_in[i][j]&=~(1<<z);
}
}
bool dfs(int last_block_cnt){
cout<<last_block_cnt<<"\n";
if(last_block_cnt==0){
for(int i=1;i<=16;i++)printf("%s\n",a[i]+1);
return 1;
}
int now_can_put_in[N][N];
memcpy(now_can_put_in,can_put_in,sizeof(now_can_put_in));
int the_best_cnt=16+1,the_best_x,the_best_y;
for(int i=1;i<=16;i++){
for(int j=1;j<=16;j++){
if(a[i][j]!='-')continue;
if(can_put_in[i][j]==0)return 0;
if(popc[can_put_in[i][j]]==1){
a[i][j]=LOG[can_put_in[i][j]]+'A';
put_a_number_in(i,j,LOG[can_put_in[i][j]]);
if(dfs(last_block_cnt-1))return 1;
a[i][j]='-';
memcpy(can_put_in,now_can_put_in,sizeof(now_can_put_in));
return 0;
}
if(popc[can_put_in[i][j]]<the_best_cnt){
the_best_cnt=popc[can_put_in[i][j]];
the_best_x=i;
the_best_y=j;
}
}
}
for(int i=1;i<=16;i++){
int this_col=0,need_to_solve=0;
for(int j=1;j<=16;j++){
if(a[i][j]=='-')need_to_solve++;
else this_col|=(1<<(a[i][j]-'A'));
}
if(need_to_solve==0)continue;
for(int x=0;x<16;x++){
if((this_col>>x)&1)continue;
int want_to_put=0,put_position=0;
for(int j=1;j<=16;j++){
if(a[i][j]!='-')continue;
if(((can_put_in[i][j]>>x)&1)==0)continue;
want_to_put++;
put_position=j;
if(want_to_put>1)break;
}
if(want_to_put==0)return 0;
if(want_to_put!=1)continue;
a[i][put_position]=x+'A';
put_a_number_in(i,put_position,x);
if(dfs(last_block_cnt-1))return 1;
a[i][put_position]='-';
memcpy(can_put_in,now_can_put_in,sizeof(now_can_put_in));
return 0;
}
}
for(int i=1;i<=16;i++){
int this_row=0,need_to_solve=0;
for(int j=1;j<=16;j++){
if(a[j][i]=='-')need_to_solve++;
else this_row|=(1<<(a[j][i]-'A'));
}
if(need_to_solve==0)continue;
for(int x=0;x<16;x++){
if((this_row>>x)&1)continue;
int want_to_put=0,put_position=0;
for(int j=1;j<=16;j++){
if(a[j][i]=='-')continue;
if(((can_put_in[j][i]>>x)&1)==0)continue;
want_to_put++;
put_position=j;
if(want_to_put>1)break;
}
if(want_to_put==0)return 0;
if(want_to_put!=1)continue;
a[put_position][i]=x+'A';
put_a_number_in(put_position,i,x);
if(dfs(last_block_cnt-1))return 1;
a[put_position][i]='-';
memcpy(can_put_in,now_can_put_in,sizeof(now_can_put_in));
return 0;
}
}
for(int x=1;x<=13;x+=4)for(int y=1;y<=13;y+=4){
int this_case=0,need_to_solve=0;
for(int i=x;i<x+4;i++)for(int j=y;j<y+4;j++){
if(a[i][j]=='-')need_to_solve++;
else this_case|=(1<<(a[i][j]-'A'));
}
if(need_to_solve==0)continue;
for(int k=0;k<16;k++){
if((this_case>>k)&1)continue;
int want_to_put=0,put_position_x=0,put_position_y=0;
for(int i=x;i<x+4;i++)for(int j=y;j<y+4;j++){
if(a[i][j]!='-')continue;
if(((can_put_in[i][j]>>k)&1)==0)continue;
want_to_put++;
put_position_x=i,put_position_y=j;
}
if(want_to_put==0)return 0;
if(want_to_put!=1)continue;
a[put_position_x][put_position_y]=k+'A';
put_a_number_in(put_position_x,put_position_y,k);
if(dfs(last_block_cnt-1))return 1;
a[put_position_x][put_position_y]='-';
memcpy(can_put_in,now_can_put_in,sizeof(now_can_put_in));
return 0;
}
}
for(int i=can_put_in[the_best_x][the_best_y];i;i-=i&-i){
int number=LOG[i&-i];
a[the_best_x][the_best_y]=number+'A';
put_a_number_in(the_best_x,the_best_y,number);
if(dfs(last_block_cnt-1))return 1;
a[the_best_x][the_best_y]='-';
memcpy(can_put_in,now_can_put_in,sizeof(now_can_put_in));
}
return 0;
}
int _;
int main(){
for(int i=0;i<16;i++)LOG[1<<i]=i;
for(int i=0;i<(1<<16);i++)for(int j=i;j;j-=j&-j)popc[i]++;
while(~scanf("%s",a[1]+1)){
if(_)puts("");
++_;
for(int j=2;j<=16;j++)scanf("%s",a[j]+1);
for(int i=1;i<=16;i++)for(int j=1;j<=16;j++)can_put_in[i][j]=(1<<16)-1;
mx_dfs=0;
for(int i=1;i<=16;i++)for(int j=1;j<=16;j++){
if(a[i][j]=='-')mx_dfs++;
else put_a_number_in(i,j,a[i][j]-'A');
}
dfs(mx_dfs);
}
return 0;
}