#include<cstdio>
#include<algorithm>
#include<vector>
#include<deque>
#include<string>
#include<iostream>
#include<tuple>
#include<utility>
#include<set>
using namespace std;
typedef long long int llint;
const llint big=((llint)1<<(llint)30);
#define mt make_tuple
#define mp make_pair
#define fi first
#define se second
#define pub push_back
#define res resize
//JOI 2017 ho-3 kingdom
//5:20???
//????????¢?´¢
//JII
//JJI
//JJI?????????
int main(void){
	int H,W,i,j,maxh=0,minh=big,maxb,minb,gen;
	vector<vector<int>>high[4];
	cin>>H>>W;
	high[0].res(H);
	high[1].res(H);
	high[2].res(H);
	high[3].res(H);
	for(i=0;i<H;i++){
		high[0][i].res(W);
		high[1][i].res(W);
		high[2][i].res(W);
		high[3][i].res(W);
	}
	for(i=0;i<H;i++){
		
		for(j=0;j<W;j++){
			cin>>high[0][i][j];
			maxh=max(maxh,high[0][i][j]);
			minh=min(minh,high[0][i][j]);
			high[1][i][W-j-1]=high[0][i][j];
			high[2][H-i-1][j]=high[0][i][j];
			high[3][H-i-1][W-j-1]=high[0][i][j];
		}
	}
	maxb=(maxh-minh);
	minb=0;
	while(maxb-minb!=1){
		gen=(maxb+minb)/2;
		
		bool can=false;
		//printf("de%d\n",gen);
		for(int k=0;k<4;k++){
			int y=0,x=0;
			while(y<H&&x<W){
				//J????????????
				for(i=y;i<H;i++){
					if(high[k][i][x]<maxh-gen){break;}
				}
				
				if(i==H){x++;continue;}
				for(j=x;j<W;j++){
					if(high[k][y][j]>minh+gen){break;}
				}
				if(j==W){y++;continue;}
				else{break;}//??????
			}
			if(y==H||x==W){can=true;break;}
		}
		if(!can){minb=gen;}
		else{maxb=gen;}
	}
	cout<<maxb<<endl;
	return 0;
}