#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
****************************************************************/