#include <stdio.h>
int all; // 解答计数
// 保存组别和已设置字符
struct Mar{
char group;
char set;
}mar[6][6];
// 将组和行列分离判断
struct Group{
int count; // 记录指针
char set[6]; // 组内字符
}grp[6];
// 行列是否重复
int lc(int m, int n, char c){
int i;
for(i=0; i<6; i++){
if(mar[m][i].set==c)
return 0;
}
for(i=0; i<6; i++){
if(mar[i][n].set==c)
return 0;
}
return 1;
}
// 处理grp数组,判断组内是否重复
int gp(char gr, char c){
int i;
for(i=0; i<grp[gr-'0'].count; i++){
if(c==grp[gr-'0'].set[i])
return 0;
}
return 1;
}
// 打印
void print(){
printf("%d\n", ++all);
int i, j;
for(i=0; i<6; i++){
for(j=0; j<6; j++) printf("%c ", mar[i][j].set);
printf("\n");
}
}
// 回溯函数,试探赋值
void set(int m, int n){
// 满足输出
if(m>5){
print();
return;
}
int i;
// 区分固定已设置字符和可变动字符
if(mar[m][n].set=='0'){
for(i=0; i<6; i++){
if(lc(m, n, i+'A') && gp(mar[m][n].group, i+'A')){ // 判断
mar[m][n].set=i+'A'; // 试探
grp[mar[m][n].group-'0'].set[grp[mar[m][n].group-'0'].count++]=mar[m][n].set; // 对应组增加一个字符
set(m+(n+1)/6, (n+1)%6);
//mar[m][n].set='0'; //函数退出时必须还愿状态,由于不参与条件判断,常放于函数后面
grp[mar[m][n].group-'0'].set[--(grp[mar[m][n].group-'0'].count)]='0'; // 注意组设置字符时会影响下次试探的判断所以必须还原
}
}
mar[m][n].set='0';
}
else set(m+(n+1)/6, (n+1)%6);
}
int main(){
int i, j, n, t;
char c;
for(i=0; i<6; i++){
for(j=0; j<6; j++){
mar[i][j].group=getchar();
mar[i][j].set='0';
}
getchar();
}
scanf("%d", &n);
while(n--){
scanf("%d%c", &t,&c);
mar[t/10][t%10].set=c;
grp[mar[t/10][t%10].group-'0'].set[(grp[mar[t/10][t%10].group-'0'].count++)]=c;
}
set(0,0);
if(all==0) printf("0\n");
return 0;
}