#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N = 1010;
int n, m;
int g[N][N];
bool st[N][N];
int dx[] = {0,1,0}, dy[] = {1,0,-1};
bool dfs(int x, int y, int minv){
if(x == n-1) return true;
bool success = false;
for(int k = 0; k < 3; k++){
int a = x+dx[k], b = y+dy[k];
if(a >= 0 && a < n && b >= 0 && b < m && !st[a][b] && g[a][b] <= minv){
st[a][b] = true;
if(dfs(a, b, minv)) return true;
}
}
return success;
}
bool check(int mid){// 判断对于mid的伤害是否合法
for(int i = 0; i < m; i++){// 枚举第一行的起点,每个点都需要走一遍
memset(st, false, sizeof st);
if(dfs(0, i, mid)) return true;
}
return false;
}
int main(){
int maxv = 0;
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++){
scanf("%d", &g[i][j]);
maxv = max(maxv, g[i][j]);
}
int l = 0, r = maxv;
while(l < r){
int mid = (l+r)>>1;
if(check(mid)) r = mid;
else l = mid+1;
}
cout << l << endl;
return 0;
}