#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 3000;
struct DLXnode{
int Col,Row;
int u,d,l,r;
}node[N];
int cnt;
int row[N],lcnt[N];
int temp[N],ans[N],s = 0;
int id[N];
char w[8][8];
int op[N];
int d[4][4];
vector<int> t[N];
void init(int m)
{
for(int i=0;i<=m;i++)
node[i] = (DLXnode){0,0,i,i,i-1,i+1};
node[0].l = m;
node[m].r = 0;
cnt = m;
}
void addnode(int C,int R)
{
node[++cnt].Col = C;
node[cnt].Row = R;
node[cnt].u = node[C].u;
node[cnt].d = C;
node[node[C].u].d = cnt;
node[C].u = cnt;
if(!row[R])
{
row[R] = cnt;
node[cnt].l = node[cnt].r = cnt;
}
else
{
node[cnt].l = node[row[R]].l;
node[cnt].r = row[R];
node[node[row[R]].l].r = cnt;
node[row[R]].l = cnt;
}
lcnt[C]++;
}
void remove(int C)
{
for(int i=node[C].d;i!=C;i=node[i].d)
for(int j=node[i].r;j!=i;j=node[j].r)
{
node[node[j].d].u = node[j].u;
node[node[j].u].d = node[j].d;
lcnt[node[j].Col]--;
}
node[node[C].l].r = node[C].r;
node[node[C].r].l = node[C].l;
}
void resume(int C)
{
for(int i=node[C].d;i!=C;i=node[i].d)
for(int j=node[i].r;j!=i;j=node[j].r)
{
node[node[j].u].d = node[node[j].d].u = j;
lcnt[node[j].Col]++;
}
node[node[C].l].r = node[node[C].r].l = C;
}
int get(int i,int j)
{
return i*4 + j + 1;
}
int dance(int dep)
{
if(node[0].r == 0|| node[0].r > 16)
{
if(!s)
{
for(int i=1;i<dep;i++) ans[i] = temp[i];
s = dep;
}
return 1;
}
int res = 0;
int C = node[0].r;
for(int i=node[0].r;i;i=node[i].r)
if(lcnt[node[i].Col] < lcnt[C])
C = i;
remove(C);
for(int i=node[C].d;i!=C;i=node[i].d)
{
for(int j=node[i].r;j!=i;j=node[j].r)
remove(node[j].Col);
temp[dep] = node[i].Row;
res += dance(dep + 1);
if(res > 1) return 2;
for(int j=node[i].r;j!=i;j=node[j].r)
resume(node[j].Col);
}
resume(C);
return res;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
s = 0;
memset(row,0,sizeof row);
memset(lcnt,0,sizeof lcnt);
init(16 + n);
int rcnt = 0;
for(int i=1;i<=n;i++)
{
int r,c;
scanf("%d%d",&r,&c);
for(int j=0;j<r;j++) scanf("%s",w[j]);
for(int dx=0;dx<4;dx++)
for(int dy=0;dy<4;dy++)
{
bool flg = true;
int ct = 0;
for(int j=0;j<r;j++)
for(int k=0;k<c;k++)
if(w[j][k]=='1')
{
int x = dx + j,y = dy + k;
if(x>=4||y>=4)
{
flg = false;
break;
}
op[ct++] = get(x,y);
}
if(!flg) break;
id[++rcnt] = i;
t[rcnt].clear();
for(int k=0;k<ct;k++)
{
addnode(op[k],rcnt);
t[rcnt].push_back(op[k]-1);
}
addnode(16 + i,rcnt);
}
}
int res = dance(1);
if(res==1)
{
puts("Yes, only one!");
for(int i=1;i<s;i++)
{
int r = ans[i];
for(auto x:t[r])
{
int u = x/4,v = x%4;
d[u][v] = id[r];
}
}
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
printf("%d",d[i][j]);
puts("");
}
}
else if(res > 1) puts("Yes, many!");
else puts("No solution");
}
return 0;
}