#include <bits/stdc++.h>
using namespace std;
bool f[1100][1100];//标记
int q[1000100][3];//队列
int a[1100][1100];
int fx[5] = {0, 1, 0, -1, 0};
int fy[5] = {0, 0, 1, 0, -1};
int n,m;
//判断从xy点开始,在伤害值最大为mid的情况下能否走到最后一行
bool bfs(int x,int y,int mid){
int head=1,tail=1;
memset(f,0,sizeof(f));//标记所有点没有走过
int tx,ty;
//出发点
q[1][1] = x;
q[1][2] = y;
while(head <= tail){
for(int i = 1;i <= 4;i++){
tx = q[head][1] + fx[i];
ty = q[head][2] + fy[i];
// cout<<tx<<" "<<ty<<" "<<a[tx][ty]<<endl;
//不满足要求,尝试其他点
if(tx<1||tx>n||ty<1||ty>m||f[tx][ty]||a[tx][ty]>mid)
continue;
if(tx==n) return true;//到终点
else{
tail++;
q[tail][1] = tx;
q[tail][2] = ty;
f[tx][ty] = 1;//标记该点走过
}
}
head++;
}
return false;
}
int main(){
int l = INT_MAX,r = INT_MIN,mid,ans;
cin>>n>>m;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
cin>>a[i][j];
r = max(r,a[i][j]);
l = min(l,a[i][j]);
}
}
// cout<<bfs(1,1,2)<<endl;
// return 0;
//在伤害值的最大和最小之间找
while(l <= r){
mid = l + r >> 1;
//mid可行,说明mid还能再小
if(bfs(1,1,mid)){
r = mid - 1;
}else l = mid + 1;//mid不行,说明太小,放大mid
}
//找左边界
cout<<l;
return 0;
}
/**************************************************************
Problem: 1916
User: admin
Language: C++
Result: Accepted
Time:308 ms
Memory:19700 kb
****************************************************************/