#include<cstdio>
#include<queue>
#include<memory.h>
#include<vector>
#define din1(a) scanf("%d", &a);
using namespace std;
const int M = 333;
const int dr[] = { 0,0,1,-1 };
const int dc[] = { 1,-1, 0,0 };
int ROW, COL;
int im[M][M];
bool chk[M][M];
int year;
struct pos {
int R, C;
pos(int ir, int ic) : R(ir), C(ic) {}
};
void bfs(int RO, int CO) {
queue<pos> Q;
Q.push(pos(RO, CO));
chk[RO][CO] = true;
while (!Q.empty()) {
int hr = Q.front().R;
int hc = Q.front().C;
Q.pop();
for (int i = 0; i < 4; i++) {
int tr = hr + dr[i];
int tc = hc + dc[i];
if (tr < 0 || ROW <= tr || tc < 0 || COL < tc) continue;
if (!chk[tr][tc] && (im[tr][tc] > 0)) {
chk[tr][tc] = true;
Q.push(pos(tr, tc));
}
}
}
}
int main() {
din1(ROW); din1(COL);
vector<pos> v;
for (int r = 0; r < ROW; r++) {
for (int c = 0; c < COL; c++) {
din1(im[r][c]);
if (im[r][c]) v.push_back(pos(r, c));
}
} // input
bool is_end = false;
while (1) {
int ans = 0;
/*
for (int r = 0; r < ROW; r++) {
for (int c = 0; c < COL; c++) {
if (im[r][c] > 0) {
if (chk[r][c]) continue;
ans++;
bfs(r, c);
}
}
}
*/
for (int i = 0; i < v.size(); i++) {
int r = v[i].R;
int c = v[i].C;
if (chk[r][c] == 0) {
if (im[r][c] < 1) continue;
ans++;
bfs(r, c);
}
}
/*
for (int r = 0; r < ROW; r++) {
for (int c = 0; c < COL; c++) {
if (!chk[r][c]) {
for (int i = 0; i < 4; i++) {
int tr = r + dr[i];
int tc = c + dc[i];
if (tr < 0 || ROW <= tr || tc < 0 || COL <= tc) continue;
if (im[tr][tc] > 0) im[tr][tc]--;
}
}
}
}
*/
for (int i = 0; i < v.size(); i++) {
int r = v[i].R;
int c = v[i].C;
for (int i = 0; i < 4; i++) {
int tr = r + dr[i];
int tc = c + dc[i];
if (tr < 0 || ROW <= tr || tc < 0 || COL <= tc) continue;
if (chk[tr][tc] == 0 && im[r][c] > 0) im[r][c]--;
}
}
if (ans == 0) puts("0"), is_end = true;
else if (ans > 1) printf("%d\n", year), is_end = true;
if (is_end) break;
year++;
memset(chk, 0, sizeof(chk));
}
return 0;
}