#include<bits/stdc++.h>
using namespace std;
struct node{
int x;
int y;
};
int n,m,ans;
int dir[4][2]={0,1, 1,0, -1,0, 0,-1};
int mp[1005][1005];
int vis[1005][1005];
queue<node> q;
bool bfs(int mid){
while(!q.empty()){
node p = q.front();
q.pop();
for(int i=0;i<4;i++){
int nx=p.x+dir[i][0];
int ny=p.y+dir[i][1];
if(nx>0&&nx<=n&&ny>0&&ny<=m&&vis[nx][ny]==0&&mp[nx][ny]<=mid){
vis[nx][ny] = 1;
q.push({nx,ny});
}
}
}
for(int i=1;i<=m;i++){
if(vis[n][i]==1){
continue;
}else{
return false;
}
}
return true;
}
bool check(int mid){
for(int i=1;i<=m;i++){
q.push({1,i});
vis[1][i] = 1;
}
if(!bfs(mid)){
memset(vis,0,sizeof(vis));
return 0;
}
memset(vis,0,sizeof(vis));
return 1;
}
int main(){
cin>>n>>m;
int l=21474836,r=-1,mid;
for(int i=1;i<=n;i++){
for(int j =1;j<=m;j++){
cin>>mp[i][j];
l = min(l,mp[i][j]);
r = max(r,mp[i][j]);
}
}
while(l<=r){
mid = (l+r)/2;
if(check(mid)){
ans = mid;
r = mid-1;
}else{
l = mid+1;
}
}
cout<<ans;
return 0;
}