/*大致上题意就是每个宝物最多有12个点需要侍卫守护,仔细一看如果宝物地点为i,j,需要保护的点是x,y的话,那么(i+j)%2!=(x+y)%2,那么就可以按照棋盘奇偶划分,然后求一个最小点覆盖即可。*/
#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>
#include <vector>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
int r,c,g[60][60],x[60][60],ans,re[1600],vi[1600],n,m;
int dic[12][2]={-1,-2,-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,0,0,1,1,0,0,-1};
vector<int>vt[1501];
int inside(int x,int y)
{
return x>=1&&x<=r&&y>=1&&y<=c;
}
void gao(int i,int j,int v,int flag)
{
for(int k=0;k<12;k++)
{
if((v>>k)&1)
{
int tx=i+dic[k][0];
int ty=j+dic[k][1];
if(inside(tx,ty)&&g[tx][ty]!=-1)
{
if(flag)
vt[x[i][j]].push_back(x[tx][ty]);
else
vt[x[tx][ty]].push_back(x[i][j]);
}
}
}
}
int dfs(int y)
{
for(int i=0;i<vt[y].size();i++)
{
int j=vt[y][i];
if(!vi[j])
{
vi[j]=1;
if(re[j]==0||dfs(re[j]))
{
re[j]=y;
return 1;
}
}
}
return 0;
}
void match()
{
ans=0;
memset(re,0,sizeof(re));
for(int i=1;i<=n;i++)
{
memset(vi,0,sizeof(vi));
ans+=dfs(i);
}
return;
}
int main()
{
int pro=0;
while(scanf("%d%d",&r,&c),r||c)
{
n=0,m=0;
for(int i=1;i<=1500;i++)
vt[i].clear();
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
{
scanf("%d",&g[i][j]);
if(g[i][j]!=-1)
{
if((i+j)%2)
x[i][j]=++n;
else
x[i][j]=++m;
}
}
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
{
if(g[i][j]!=-1)
gao(i,j,g[i][j],(i+j)%2);
}
match();
printf("%d. %d\n",++pro,ans);
}
return 0;
}