/*
#include <stdio.h>
#include <stdbool.h>
int count=0;
int a[21][21]={};
int dir[4][2]={{-1,+1},
{0,+1},
{+1,+1},
{+1,0}};
//
//x+dir[direction][0]
//y+dir[direction][1]
bool flag = false; // 승부가 났는지?
void dfs(int x, int y, int color, int d)
{
if(count>5||x<1||x>19||y<1||y>19||a[x][y]!=color) return;
count++;
if(count==5)
{
if(a[x+dir[d][0]][y+dir[d][1]]!=color) flag=true;
return;
}
dfs(x+dir[d][0],y+dir[d][1],color,d);
}
int main()
{
for(int i=1; i<=19; i++)
{
for(int j=1; j<=19; j++)
scanf("%d", &a[i][j]);
}
for(int i=1; i<=19; i++)
{
for(int j=1; j<=19; j++)
{
if(a[i][j]!=0)
{
for(int k=0; k<4; k++)
{
count=0;
if(a[i-dir[k][0]][j-dir[k][1]]!=a[i][j])
{
dfs(i,j,a[i][j],k);
}
if(flag==true)
{
printf("%d\n%d %d", a[i][j], i, j);
return 0;
}
}
}
}
}
printf("0");
}
*/
#include <stdio.h>
int day=0;
int n,m;
int k=-1;
int a[1001][1001]={};
typedef struct
{
int x;
int y;
}tomato;
tomato queue[1000000];
int f=-1, r=-1;
void enq(int x, int y)
{
if(x<1||x>n||y<1||y>m) return;
a[x][y]=1;
r++;
queue[r].x=x;
queue[r].y=y;
}
tomato deq()
{
f++;
return queue[f];
}
void bfs(int x, int y)
{
if(a[x][y+1]==0)
{
enq(x, y+1);
}
if(a[x][y-1]==0)
{
enq(x, y-1);
}
if(a[x+1][y]==0)
{
enq(x+1, y);
}
if(a[x-1][y]==0)
{
enq(x-1, y);
}
//k=r; //한번 퍼져나갔을 때의 rear를 k에 저장함
}
int main()
{
int count=0;
int x=0;
scanf("%d %d", &m, &n);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
scanf("%d", &a[i][j]);
if(a[i][j]==1) enq(i, j);
if(a[i][j]!=-1) x++;
}
}
k=r;
while(f!=r){
tomato t = deq();
//printf("f = %d r = %d x = %d y = %d\n",f,r,t.x,t.y);
bfs(t.x,t.y);
if(f==k)
{
//printf("day ++\n");
day++;
k=r;
}
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
if(a[i][j]==1) count++;
}
}
if(count==x) printf("%d", day-1);
if(count<x) printf("-1");
}



