参考:http://blog.csdn.net/wsx1754175/article/details/18980009
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define initial 1,n,1
#define CLR(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
template<typename X> inline bool minimize(X&p,X q){if(p<=q)return 0;p=q;return 1;}
template<typename X> inline bool maximize(X&p,X q){if(p>=q)return 0;p=q;return 1;}
const int MAXN=110,INF=0x3f3f3f3f;
struct Hopcroft_Carp{
int g[MAXN][MAXN];
int Mx[MAXN],My[MAXN],nx,ny;
int dx[MAXN],dy[MAXN],dis;
bool vst[MAXN],T[MAXN];
void init(int x,int y)
{
nx=x; ny=y;
memset(g,0,sizeof(g));
}
void adde(int u,int v)
{
g[u][v]++;
}
void dele(int u,int v)
{
g[u][v]--;
}
bool searchP()
{
queue<int>Q; dis=INF;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=0;i<nx;i++)
if(Mx[i]==-1)
{
Q.push(i);
dx[i]=0;
}
while(!Q.empty())
{
int u=Q.front();
Q.pop();
if(dx[u]>dis) break;
for(int v=0;v<ny;v++)
if(g[u][v]&&dy[v]==-1)
{
dy[v]=dx[u]+1;
if(My[v]==-1) dis=dy[v];
else
{
dx[My[v]]=dy[v]+1;
Q.push(My[v]);
}
}
}
return dis!=INF;
}
bool DFS(int u)
{
for(int v=0;v<ny;v++)
if(!vst[v]&&g[u][v]&&dy[v]==dx[u]+1)
{
vst[v]=1;
if(My[v]!=-1&&dy[v]==dis) continue;
if(My[v]==-1||DFS(My[v]))
{
My[v]=u;
Mx[u]=v;
return 1;
}
}
return 0;
}
int MaxMatch()
{
int res=0;
memset(Mx,-1,sizeof(Mx));
memset(My,-1,sizeof(My));
while(searchP())
{
memset(vst,0,sizeof(vst));
for(int i=0;i<nx;i++)
if(Mx[i]==-1&&DFS(i)) res++;
}
return res;
}
}it;
int row[MAXN],col[MAXN],ans[MAXN][MAXN];
char str[MAXN][MAXN];
int n;
void doit()
{ scanf("%d",&n);
CLR(row,0);CLR(col,0);
for (int i=0;i<n;i++)scanf("%s",str[i]);
it.init(n,n);
int r=0;
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)if (str[i][j]=='*')
{ it.adde(i,j);
row[i]++; col[j]++;
r=max(r,row[i]);
r=max(r,col[j]);
}
printf("%d\n",r);
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
if (row[i]<r&&col[j]<r)
{ int t1=min(r-row[i],r-col[j]);
while (t1--){
it.adde(i,j);
row[i]++;
col[j]++;}
}
CLR(ans,0);
for (int ii=1;ii<=r;ii++)
{
it.MaxMatch();
for (int i=0;i<n;i++)
if (it.Mx[i]!=-1)
{ it.dele(i,it.Mx[i]);
if (str[i][it.Mx[i]]=='*') ans[i][it.Mx[i]]=ii;
}
}
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
printf("%d%c",ans[i][j],(j!=n-1)?' ':'\n');
}
int main()
{ int cas;
scanf("%d",&cas);
while (cas--) doit();
}