#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5;
const int maxn=1e3;
int e[N],ne[N],h[N],idx;
void add(int a,int b)
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int n,m,xN,yN;
int link[N],num[maxn][maxn],mp[maxn][maxn];
bool vis[N];
int dir[][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}};
bool dfs(int u) {
for(int i=h[u]; i!=-1; i=ne[i]) {
int t=e[i];
if(!vis[t]) {
vis[t]=true;
if(link[t]==-1||dfs(link[t])) {
link[t]=u;
return true;
}
}
}
return false;
}
int max_match() {
memset(link,-1,sizeof(link));
int ans=0;
for(int i=1; i<=xN; i++) {
memset(vis,false,sizeof(vis));
if(dfs(i)) ans++;
}
return ans;
}
bool check(int x,int y) {
if(x<=0||y<=0||x>n||y>m||mp[x][y]==-1) return false;
return true;
}
void init() {
idx=0;
memset(h,-1,sizeof h);
xN=yN=0;
}
int main() {
int cas=0;
while(~scanf("%d%d",&n,&m)&&n&&m) {
init();
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if((i+j)%2==0)
num[i][j]=++xN;
else
num[i][j]=++yN;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
scanf("%d",&mp[i][j]);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) {
if(mp[i][j]==-1)
continue;
for(int k=0; k<12; k++) {
if(mp[i][j]&(1<<k)) {
int x=i+dir[k][0];
int y=j+dir[k][1];
if(!check(x,y))
continue;
if((i+j)%2==0)
add(num[i][j],num[x][y]);
else
add(num[x][y],num[i][j]);
}
}
}
printf("%d. %d
",++cas,max_match());
}
return 0;
}