/*大致上题意就是每个宝物最多有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; }