Problem:
Kingdom of JOIOI
The Kingdom of JOIOI is a rectangular grid of $H \times W$ cells. In the Kingdom of JOIOI, in order to improve efficiency of administrative institutions, the country will be divided into two regions called "JOI" and "IOI."
Since we do not want to divide it in a complicated way, the division must satisfy the following conditions:
Each region must contain at least one cell.
Each cell must belong to exactly one of two regions.
For every pair of cells in the JOI region, we can travel from one to the other by passing through cells belonging to the JOI region only. When move from a cell to another cell, the two cells must share an edge. The same is true for the IOI region.
For each row or column, if we take all the cells in that row or column, the cells belonging to each region must be connected. All the cells in a row or column may belong to the same region.
Each cell has an integer called the
altitude
. After we divide the country into two regions, it is expected that traveling in each region will be active. But, if the difference of the altitudes of cells are large, traveling between them becomes hard. Therefore, we would like to minimize the maximum of the difference of the altitudes between cells belonging to the same region. In other words, we would like to minimize the larger value of
the difference between the maximum and the minimum altitudes in the JOI region, and
the difference between the maximum and the minimum altitudes in the IOI region.
Task
Given the altitudes of cells in the Kingdom of JOIOI, write a program which calculates the minimum of the larger value of the difference between the maximum and the minimum altitudes in the JOI region and the difference between the maximum and the minimum altitudes in the IOI region when we divide the country into two regions.
Input
Read the following data from the standard input.
The first line of input contains two space separated integers $H$, $W$. This means the Kingdom of JOIOI is a rectangular grid of $H \times  W$ cells.
The $i$-th line ($1 \leq i \leq H$) of the following $H$ lines contains $W$ space separated integers $A_{i,1}, A_{i,2}, ..., A_{i,W}$. This means the cell in the $i$-th row from above and $j$-th column from left ($1 \leq j \leq W$) has altitude $A_{i,j}$.
Output
Write one line to the standard output. The output contains the minimum of the larger value of the difference between the maximum and the minimum altitudes in the JOI region and the difference between the maximum and the minimum altitudes in the IOI region when we divide the country into two regions.
Constraints
All input data satisfy the following conditions.
$2 \leq H \leq 2 000．$
$2 \leq W \leq 2 000．$
$1 \leq A_{i, j} \leq 1 000 000 000 (1 \leq i \leq H, 1 \leq j \leq W)．$
Sample Input and Output
Sample Input 1
4 4
1 12 6 11
11 10 2 14
10 1 9 20
4 17 19 10
Sample Output 1
11
For example, in this sample input, we divide the country into two regions as follows. Here, ‘J’ denotes the JOI region, and ‘
...(truncated)

Submitted solutions:

code_snippet: //new.cpp
/*
Author : Hocky Yudhiono
Sab 20 Apr 2019 03:27:38  WIB
Current Local Time : 15:27:38

getchar_unlocked > getchar > cin without sync > scanf > cin with sync
bool operator<(const MyStruct& rhs) const

On how to print Long Double to 5 decimal places :
printf("%.5Lf",ans);

On how to get random numbers :
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); //For int
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); //For LL
cout << rng() << endl;
shuffle(isi.begin(),isi.end(),rng);

__gcd(a,b)
__builtin_ffs(a) first on bit
__builtin_clz(a) count leading zero
__builtin_ctz(a) count trailing zero
__builtin_popcount(a) numbers of on bits

*/

//#include <unordered_map>
//#include <unordered_set>

//#include <random>
//#include <chrono>

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>

//using namespace __gnu_pbds;
using namespace std;

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize(3)
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
// #pragma GCC diagnostic error "-fwhole-program"
// #pragma GCC diagnostic error "-fcse-skip-blocks"
// #pragma GCC diagnostic error "-funsafe-loop-optimizations"
// #pragma GCC diagnostic error "-std=c++14"
// #pragma GCC target ("string"...)
#pragma GCC push_options
#pragma GCC pop_options
#pragma GCC reset_options
#pragma GCC optimize ("O3")

typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
// typedef tree<long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update> pbds;
//If the time limit is strict, try not to use long double


#define fbo find_by_order
#define ook order_of_key
#define mp make_pair
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define remove erase
//Remember to undefine if the problem is interactive
#define endl '\n'
#define DEBUG(X) cout << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << (X) << endl

const double eps = 1e-9;
const int INFMEM = 63;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const double DINF = numeric_limits<double>::infinity();
const LL MOD = 1000000007;
const int dx[8] = {1,0,-1,0,1,1,-1,-1};
const int dy[8] = {0,1,0,-1,1,-1,1,-1};
const double PI = 3.141592653589793;

#ifdef _WIN32
#define getchar_unlocked getchar
#endif
#define GETCHAR getchar_unlocked
inline void fastll(LL &input_number) 
{
    input_number = 0;
    int ch = GETCHAR();
    int sign = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') sign=-1;
        ch = GETCHAR();
    }
    while(ch >= '0' && ch <= '9'){
        input_number = (input_number << 3)+(input_number << 1) + ch-'0';
        ch = GETCHAR();
    }
    input_number *= sign;
}

inline void open(string a){
    freopen((a+".in").c_str(),"r",stdin);
    freopen((a+".out").c_str(),"w",stdout);
}

inline void fasterios(){
    //Do not use if interactive
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
}

struct dt{
	LL mini, maksi;
	bool operator==(const dt &other)const{
		return (mini == other.mini && maksi == other.maksi);
	}
};
dt minmax(dt a, dt b){
	dt ret = {min(a.mini,b.mini),max(a.maksi,b.maksi)};
	return ret;
}

dt awal;
LL cur[2005];
LL r,c,small,big;
LL isi[2005][2005];
dt pre[2005][2005];
dt suf[2005][2005];

void debug(){
	cout << "|------------------------------------|" << endl;
	cout << "ISI ARRAY " << endl;
	for(int i = 1;i <= r;i++){
		for(int j = 1;j <= c;j++){
			cout << isi[i][j] << " \n"[j == c];
		}
	}
	cout << "|------------------------------------|" << endl;
	cout << "|------------------------------------|" << endl;
	cout << "PRE ARRAY " << endl;
	for(int i = 1;i <= r;i++){
		for(int j = 1;j <= c;j++){
			cout << pre[i][j].maksi << " \n"[j == c];
		}
	}
	cout << "|------------------------------------|" << endl;
	cout << "|------------------------------------|" << endl;
	cout << "SUF ARRAY " << endl;
	for(int i = 1;i <= r;i++){
		for(int j = 1;j <= c;j++){
			cout << suf[i][j].maksi << " \n"[j == c];
		}
	}
	cout << "|------------------------------------|" << endl;
}

int main(){
	fasterios();
	awal = {INF,-INF};
	cin >> r >> c;
	for(int i = 0;i <= r+2;i++){
		for(int j = 0;j <= c+2;j++){
			pre[i][j] = suf[i][j] = {INF,-INF};
		}
	}
	small = INF;
	for(int i = 1;i <= r;i++){
		for(int j = 1;j <= c;j++){
			cin >> isi[i][j];
			small = min(small,isi[i][j]);
		}
	}
	for(int i = 1;i <= r;i++){
		for(int j = 1;j <= c;j++){
			isi[i][j] -= small;
			big = max(big,isi[i][j]);
			pre[i][j] = suf[i][j] = {isi[i][j],isi[i][j]};
		}
	}
	for(int j = 1;j <= c;j++){
		for(int i = r;i >= 1;i--){
			pre[i][j] = minmax(pre[i][j],pre[i+1][j]);
		}
		for(int i = 1;i <= r;i++){
			suf[i][j] = minmax(suf[i][j],suf[i-1][j]);
		}
	}
	// debug();
	//compute yang naik
	LL ans = big;
	LL kiri = 0;
	LL kanan = big;
	while(kiri < kanan){
		LL mid = (kiri+kanan)>>1;
		bool isvalid = 0;
		for(int j = 1;j <= c;j++){
			LL le = 1;
			LL ri = r+1;
			while(le < ri){
				LL mi = (le+ri)>>1;
				if(pre[mi][j].maksi > mid) le = mi+1;
				else ri = mi;
			}
			if(pre[le][j].mini == 0) isvalid = 1;
			cur[j] = le;
		}
		dt atas = {INF,-INF};
		dt bawah = {INF,-INF};
		if(!isvalid) kiri = mid+1;
		else{
			if(cur[c] == r+1){
				kiri = mid+1;
				continue;
			}
			LL curmaks = cur[c];
			for(int j = c;j >= 1;j--){
				cur[j] = max(curmaks,cur[j]);
				curmaks = cur[j];
			}
			for(int j = 1;j <= c;j++){
				atas = minmax(suf[cur[j]-1][j],atas);
				bawah = minmax(pre[cur[j]][j],bawah);
			}
			if(atas == awal) atas = {0,0};
			if(bawah.maksi-bawah.mini > mid || atas.maksi-atas.mini > mid){
				kiri = mid+1;
				continue;
			}
			kanan = mid;
		}
	}
	ans = min(ans,kiri);








	//compute yang turun dari bawah
	kiri = 0; kanan = big;
	while(kiri < kanan){
		LL mid = (kiri+kanan)>>1;
		bool isvalid = 0;
		for(int j = 1;j <= c;j++){
			LL le = 1;
			LL ri = r+1;
			while(le < ri){
				LL mi = (le+ri)>>1;
				if(pre[mi][j].maksi > mid) le = mi+1;
				else ri = mi;
			}
			if(pre[le][j].mini == 0) isvalid = 1;
			cur[j] = le;
		}
		dt atas = {INF,-INF};
		dt bawah = {INF,-INF};
		if(!isvalid) kiri = mid+1;
		else{
			if(cur[1] == r+1){
				kiri = mid+1;
				continue;
			}
			LL curmaks = cur[1];
			for(int j = 1;j <= c;j++){
				cur[j] = max(curmaks,cur[j]);
				curmaks = cur[j];
			}
			for(int j = 1;j <= c;j++){
				atas = minmax(suf[cur[j]-1][j],atas);
				bawah = minmax(pre[cur[j]][j],bawah);
			}
			if(atas == awal) atas = {0,0};
			if(bawah.maksi-bawah.mini > mid || atas.maksi-atas.mini > mid){
				kiri = mid+1;
				continue;
			}
			kanan = mid;
		}
	}
	ans = min(ans,kiri);











	kiri = 0; kanan = big;
	//Compute yang naik dari atas
	while(kiri < kanan){
		LL mid = (kiri+kanan)>>1;
		// cerr << "Computing " << mid << endl;
		bool isvalid = 0;
		for(int j = 1;j <= c;j++){
			LL le = 0;
			LL ri = r;
			while(le < ri){
				LL mi = (le+ri+1)>>1;
				if(suf[mi][j].maksi > mid) ri = mi-1;
				else le = mi;
			}
			if(suf[le][j].mini == 0) isvalid = 1;
			cur[j] = le;
		}
		dt atas = {INF,-INF};
		dt bawah = {INF,-INF};
		// cerr << "isvalid val " << isvalid << endl;
		if(!isvalid) kiri = mid+1;
		else{
			if(cur[c] == 0){
				kiri = mid+1;
				continue;
			}
			LL curmaks = cur[c];
			for(int j = c;j >= 1;j--){
				cur[j] = min(curmaks,cur[j]);
				curmaks = cur[j];
			}
			for(int j = 1;j <= c;j++){
				atas = minmax(suf[cur[j]][j],atas);
				bawah = minmax(pre[cur[j]+1][j],bawah);
			}
			if(bawah == awal) bawah = {0,0};
			if(bawah.maksi-bawah.mini > mid || atas.maksi-atas.mini > mid){
				kiri = mid+1;
				continue;
			}
			kanan = mid;
		}
	}
	ans = min(ans,kiri);







	//compute yang turun dari atas
	kiri = 0; kanan = big;
	while(kiri < kanan){
		LL mid = (kiri+kanan)>>1;
		// cerr << "Computing " << mid << endl;
		bool isvalid = 0;
		for(int j = 1;j <= c;j++){
			LL le = 0;
			LL ri = r;
			while(le < ri){
				LL mi = (le+ri+1)>>1;
				if(suf[mi][j].maksi > mid) ri = mi-1;
				else le = mi;
			}
			if(suf[le][j].mini == 0) isvalid = 1;
			cur[j] = le;
		}
		dt atas = {INF,-INF};
		dt bawah = {INF,-INF};
		// cout << isvalid << endl;
		if(!isvalid) kiri = mid+1;
		else{
			if(cur[1] == 0){
				kiri = mid+1;
				continue;
			}
			LL curmaks = cur[1];
			for(int j = 1;j <= c;j++){
				cur[j] = min(curmaks,cur[j]);
				curmaks = cur[j];
			}
			for(int j = 1;j <= c;j++){
				atas = minmax(suf[cur[j]][j],atas);
				bawah = minmax(pre[cur[j]+1][j],bawah);
			}
			if(bawah == awal) bawah = {0,0};
			if(bawah.maksi-bawah.mini > mid || atas.maksi-atas.mini > mid){
				kiri = mid+1;
				continue;
			}
			kanan = mid;
		}
	}
	ans = min(ans,kiri);

	cout << ans << endl;
    return 0;	
}
accuracy: 1
time_ms: 320
memory_kb: 160348
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define yoimiya int
const yoimiya nmax=2e3+163,inf=1e9,mod=1e9+7,MAX=4000000;
yoimiya n,m,a[nmax][nmax],b[nmax][nmax],a_min=inf,a_max=-inf,mn[nmax][nmax],mx[nmax][nmax];
void Rotate()
{
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            b[m-j+1][i]=a[i][j];
    swap(a,b); swap(n,m);
}
bool check(yoimiya val)
{
    for (int turn=1;turn<=4;turn++)
    {
        bool able=true;
        for (int i=1;i<=n;i++)
        {
            mn[i][0]=inf; mx[i][m+1]=-inf;
            for (int j=1;j<=m;j++) mn[i][j]=min(mn[i][j-1],a[i][j]);
            for (int j=m;j>=1;j--) mx[i][j]=max(mx[i][j+1],a[i][j]);
        }
        yoimiya j=0;
        for (int i=1;i<=n;i++)
        {
            while ((j<=m) and ((a_max-mn[i][j]>val) or (mx[i][j+1]-a_min>val)))
                j++;
            if (j>m) {able=false; break;}
        }
        if (able) return true;
        Rotate();
    }
    return false;
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    //freopen("yoimiya.INP","r",stdin);
    //freopen("yoimiya.OUT","w",stdout);
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            cin>>a[i][j];
            a_min=min(a_min,a[i][j]);
            a_max=max(a_max,a[i][j]);
        }
    }
    yoimiya d=0,c=1e9,ans=inf;
    while (d<=c)
    {
        yoimiya mid=(d+c)>>1;
        if (check(mid))
        {
            ans=mid;
            c=mid-1;
        }
        else d=mid+1;
    }
    cout<<ans<<'\n';
}
accuracy: 1
time_ms: 1380
memory_kb: 76552
final_rank: 9

code_snippet: #include <cstdio>
#include <algorithm>
#include <climits>
using namespace std;

const int INF = 1012345678;
int H, W, a[2009][2009], t[2009][2009], dp[2009][2009], pl[2009], pr[2009];

int main() {
    scanf("%d %d", &H, &W);
    int vl = INF, vr = -1;

    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            char c = getchar();
            while (c < '0' || '9' < c) c = getchar();
            while ('0' <= c && c <= '9') {
                a[i][j] = 10 * a[i][j] + c - '0';
                c = getchar();
            }
            vl = min(vl, a[i][j]);
            vr = max(vr, a[i][j]);
        }
    }

    int ret = INF;
    for (int i = 0; i < 4; i++) {
        pr[W] = 0;
        for (int j = 0; j < H; j++) {
            for (int k = 1; k <= W; k++) pl[k] = max(pl[k - 1], a[j][k - 1] - vl);
            for (int k = W - 1; k >= 0; k--) pr[k] = max(pr[k + 1], vr - a[j][k]);

            int curmin = INF;
            for (int k = 0; k <= W; k++) {
                curmin = min(curmin, dp[j][k]);
                dp[j + 1][k] = max({ curmin, pl[k], pr[k] });
            }
        }

        ret = min(ret, *min_element(dp[H], dp[H] + W + 1));

        for (int j = 0; j < H; j++) {
            for (int k = 0; k < W; k++) {
                t[k][H - j - 1] = a[j][k];
            }
        }
        swap(H, W);
        for (int j = 0; j < H; j++) {
            for (int k = 0; k < W; k++) {
                a[j][k] = t[j][k];
            }
        }
    }

    printf("%d\n", ret);
    return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 50200
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll INF = 1e9+7;
int h, w;
ll a[2020][2020], ma=0, mi=INF;

bool ok(ll now){
    
    int wa[2020];
    memset(wa, -1, sizeof(wa));
    for(int i=0;i<h;i++){
        int cnt=0;
        for(int j=0;j<w;j++){
            if(cnt==0){
                if(mi+now<a[i][j] || i>0&&wa[i-1]==j){
                    wa[i] = j;
                    cnt++;
                }
            }
            if(cnt==1){
                if(ma-now>a[i][j]) return false;
            }
        }
        if(wa[i]==-1) wa[i] = w;
    }
    
    return true;
}

bool slv(ll now){
    
    if(ok(now)) return true;
    
    for(int i=0;i<h;i++){
        for(int j=0;j<w/2;j++) swap(a[i][j], a[i][w-1-j]);
    }
    if(ok(now)) return true;
    
    for(int i=0;i<h/2;i++){
        for(int j=0;j<w;j++) swap(a[i][j], a[h-1-i][j]);
    }
    if(ok(now)) return true;
    
    for(int i=0;i<h;i++){
        for(int j=0;j<w/2;j++) swap(a[i][j], a[i][w-1-j]);
    }
    if(ok(now)) return true;
    
    return false;
}

int main(){
    
    cin >> h >> w;
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            cin >> a[i][j];
            ma = max(ma, a[i][j]);
            mi = min(mi, a[i][j]);
        }
    }
    
    ll l=0, r=INF;
    while(l<r){
        ll mid = (l+r)/2;
        if(slv(mid)) r = mid;
        else l = mid+1;
    }
    
    cout << r << endl;
    
    return(0);
}
accuracy: 1
time_ms: 1490
memory_kb: 34692
final_rank: 8

code_snippet: // #pragma GCC target("avx2")
#pragma GCC optimize("O3", "unroll-loops")

// #include <bits/extc++.h>
// using namespace __gnu_pbds;

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define double long double
// template <typename T>
// using pbds_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
using pii = pair<int, int>;
template<typename T>
using prior = priority_queue<T, vector<T>, greater<T>>;
template<typename T>
using Prior = priority_queue<T>;

#define X first
#define Y second
#define ALL(x) (x).begin(), (x).end()
#define eb emplace_back
#define pb push_back

#define fastIO() ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define RANDOM() random_device __rd; \
                 mt19937 __gen = mt19937(__rd()); \
                 uniform_int_distribution<int> __dis(0, 1); \
                 auto rnd = bind(__dis, __gen);

const int INF = 1E9;
const int mod = 1E9 + 7;

int32_t main() {
    fastIO();
    
    int h, w;
    cin >> h >> w;
    
    int _max = 0;
    vector<vector<int>> v(h, vector<int>(w));
    for (auto &x : v) for (auto &y : x) cin >> y, _max = max(_max, y);
    
    int lo = 0, hi = INF, mi, inMin, inMax;
    vector<int> heiL, heiR;
    while (lo < hi) {
        mi = lo + hi >> 1;
        
        heiL.clear(), heiR.clear();
        for (auto vec : v) {
            for (int i = 0; i < w; ++i) {
                if (vec[i] < _max - mi) {heiL.eb(i); break;}
                if (i == w-1) heiL.eb(w);
            }
            for (int i = w-1; i >= 0; --i) {
                if (vec[i] < _max - mi) {heiR.eb(i+1); break;}
                if (i == 0) heiR.eb(0);
            }
        }
        for (int i = 1; i < h; ++i) heiL[i] = min(heiL[i-1], heiL[i]);
        for (int i = 1; i < h; ++i) heiR[i] = max(heiR[i-1], heiR[i]);
        
        inMin = INF, inMax = 0;
        for (int i = 0; i < h; ++i) {
            for (int j = heiL[i]; j < w; ++j) inMax = max(inMax, v[i][j]), inMin = min(inMin, v[i][j]);
        }
        if (inMax - inMin <= mi) {hi = mi; continue;}
        
        inMin = INF, inMax = 0;
        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < heiR[i]; ++j) inMax = max(inMax, v[i][j]), inMin = min(inMin, v[i][j]);
        }
        if (inMax - inMin <= mi) {hi = mi; continue;}
        
        heiL.clear(), heiR.clear();
        for (auto vec : v) {
            for (int i = 0; i < w; ++i) {
                if (vec[i] < _max - mi) {heiL.eb(i); break;}
                if (i == w-1) heiL.eb(w);
            }
            for (int i = w-1; i >= 0; --i) {
                if (vec[i] < _max - mi) {heiR.eb(i+1); break;}
                if (i == 0) heiR.eb(0);
            }
        }
        for (int i = h-2; i >= 0; --i) heiL[i] = min(heiL[i+1], heiL[i]);
        for (int i = h-2; i >= 0; --i) heiR[i] = max(heiR[i+1], heiR[i]);
        
        inMin = INF, inMax = 0;
        for (int i = 0; i < h; ++i) {
            for (int j = heiL[i]; j < w; ++j) inMax = max(inMax, v[i][j]), inMin = min(inMin, v[i][j]);
        }
        if (inMax - inMin <= mi) {hi = mi; continue;}
        
        inMin = INF, inMax = 0;
        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < heiR[i]; ++j) inMax = max(inMax, v[i][j]), inMin = min(inMin, v[i][j]);
        }
        if (inMax - inMin <= mi) {hi = mi; continue;}
        
        lo = mi + 1;
    }
    
    cout << lo << "\n";
    
    return 0;
}
accuracy: 1
time_ms: 640
memory_kb: 34848
final_rank: 4

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
#include <limits>
using namespace std;

typedef vector<int> vec;
typedef vector<vec> mat;

int s_grid[2000][2000];
int t_grid[2000][2000];


bool is_ok(const mat& grid, int min_h, int max_h, int h) {
	int width = int(grid[0].size());
	int height = int(grid.size());

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			s_grid[y][x] = 0;
			t_grid[y][x] = 0;
		}

	}

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			if (grid[y][x] - min_h > h) {
				s_grid[y][x] = 1;
			}
			if (max_h - grid[y][x] > h) {
				t_grid[y][x] = 1;
			}
		}
	}

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			if (y + 1 < height) {
				t_grid[y + 1][x] |= t_grid[y][x];
			}
			if (x + 1 < width) {
				t_grid[y][x + 1] |= t_grid[y][x];
			}
		}
	}

	for (int y = height - 1; y >= 0; y--) {
		for (int x = width - 1; x >= 0; x--) {
			if (y - 1 >= 0) {
				s_grid[y - 1][x] |= s_grid[y][x];
			}
			if (x - 1 >= 0) {
				s_grid[y][x - 1] |= s_grid[y][x];
			}
		}
	}

	for (int y = 0; y < height; y++)
		for (int x = 0; x < width; x++)
			if (s_grid[y][x] && t_grid[y][x]) {
				return false;
			}

	return true;
}

int solve(const mat& grid, int min_h, int max_h) {
	int left = 0;
	int right = max_h - min_h;

	while (left < right) {
		int mid = (left + right) / 2;
		if (is_ok(grid, min_h, max_h, mid)) {
			right = mid;
		}
		else {
			left = mid + 1;
		}
	}
	return left;
}

void transform0(mat& grid) {
	int width = int(grid[0].size());
	int height = int(grid.size());
	mat r_grid(width, vec(height, 0));

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			r_grid[width - 1 - x][height - 1 - y] = grid[y][x];
		}
	}
	grid = r_grid;
	return;
}

void transform1(mat& grid) {
	int width = int(grid[0].size());
	int height = int(grid.size());

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width / 2; x++) {
			swap(grid[y][x], grid[y][width - 1 - x]);
		}
	}
	return;
}

int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	int height = -1;
	int width = -1;
	int min_h = numeric_limits<int>::max();
	int max_h = 0;

	cin >> height >> width;

	mat grid(height, vec(width, 0));
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			cin >> grid[i][j];
			min_h = min(min_h, grid[i][j]);
			max_h = max(max_h, grid[i][j]);
		}
	}

	int result = numeric_limits<int>::max();
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			result = min(result, solve(grid, min_h, max_h));
			if (j == 0) {
				transform0(grid);
			}
		}
		if (i == 0) {
			transform1(grid);
		}
	}

	cout << result << endl;
	return 0;
}
accuracy: 1
time_ms: 3460
memory_kb: 81220
final_rank: 15

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
#include <limits>
using namespace std;

typedef vector<int> vec;
typedef vector<vec> mat;

int s_grid[2000][2000];
int t_grid[2000][2000];


bool is_ok(const mat& grid, int min_h, int max_h, int h) {
	int width = int(grid[0].size());
	int height = int(grid.size());

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			s_grid[y][x] = 0;
			t_grid[y][x] = 0;
		}

	}

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			if (abs(min_h - grid[y][x]) > h) {
				s_grid[y][x] = 1;
			}
			if (abs(max_h - grid[y][x]) > h) {
				t_grid[y][x] = 1;
			}
		}
	}

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			if (y + 1 < height) {
				t_grid[y + 1][x] |= t_grid[y][x];
			}
			if (x + 1 < width) {
				t_grid[y][x + 1] |= t_grid[y][x];
			}
		}
	}

	for (int y = height - 1; y >= 0; y--) {
		for (int x = width - 1; x >= 0; x--) {
			if (y - 1 >= 0) {
				s_grid[y - 1][x] |= s_grid[y][x];
			}
			if (x - 1 >= 0) {
				s_grid[y][x - 1] |= s_grid[y][x];
			}
		}
	}

	for (int y = 0; y < height; y++)
		for (int x = 0; x < width; x++)
			if (s_grid[y][x] && t_grid[y][x]) {
				return false;
			}

	return true;
}

int solve(const mat& grid, int min_h, int max_h) {
	int left = 0;
	int right = max_h - min_h;

	while (left < right) {
		int mid = (left + right) / 2;
		if (is_ok(grid, min_h, max_h, mid)) {
			right = mid;
		}
		else {
			left = mid + 1;
		}
	}
	return left;
}

void transform0(mat& grid) {
	int width = int(grid[0].size());
	int height = int(grid.size());
	mat r_grid(width, vec(height, 0));

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			r_grid[width - 1 - x][height - 1 - y] = grid[y][x];
		}
	}
	grid = r_grid;
	return;
}

void transform1(mat& grid) {
	int width = int(grid[0].size());
	int height = int(grid.size());

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width / 2; x++) {
			swap(grid[y][x], grid[y][width - 1 - x]);
		}
	}
	return;
}

int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	int height = -1;
	int width = -1;
	int min_h = numeric_limits<int>::max();
	int max_h = 0;

	cin >> height >> width;

	mat grid(height, vec(width, 0));
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			cin >> grid[i][j];
			min_h = min(min_h, grid[i][j]);
			max_h = max(max_h, grid[i][j]);
		}
	}

	int result = numeric_limits<int>::max();
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			result = min(result, solve(grid, min_h, max_h));
			if (j == 0) {
				transform0(grid);
			}
		}
		if (i == 0) {
			transform1(grid);
		}
	}

	cout << result << endl;
	return 0;
}
accuracy: 1
time_ms: 3610
memory_kb: 81124
final_rank: 19

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
#include <limits>
using namespace std;


typedef vector<int> vec;
typedef vector<vec> mat;
int max_h = 0, min_h = 1e9;

int s[2000][2000];
int t[2000][2000];

bool is_ok(const mat& grid, int h) {
	int height = grid.size();
	int width = grid[0].size();
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			s[y][x] = 0;
			t[y][x] = 0;
		}

	}

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			if (abs(min_h - grid[y][x]) > h) {
				s[y][x] = 1;
			}
			if (abs(max_h - grid[y][x]) > h) {
				t[y][x] = 1;
			}
		}
	}

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			if (y + 1 < height)t[y + 1][x] |= t[y][x];
			if (x + 1 < width)t[y][x + 1] |= t[y][x];
		}
	}

	for (int y = height - 1; y >= 0; y--) {
		for (int x = width - 1; x >= 0; x--) {
			if (y - 1 >= 0)s[y - 1][x] |= s[y][x];
			if (x - 1 >= 0)s[y][x - 1] |= s[y][x];
		}
	}

	for (int y = 0; y < height; y++)
		for (int x = 0; x < width; x++)
			if (s[y][x] && t[y][x])return false;

	return true;
}

int solve(const mat& A) {
	int left = 0, right = 1e9, mid;
	while (left < right) {
		mid = (left + right) / 2;
		if (is_ok(A, mid))right = mid;
		else left = mid + 1;
	}
	return left;
}

void transform0(mat& grid) {
	int height = grid.size();
	int width = grid[0].size();
	mat r_grid(width, vec(height, 0));
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			r_grid[width - 1 - x][height - 1 - y] = grid[y][x];
		}
	}
	grid = r_grid;
	return;
}

void transform1(mat& grid) {
	int height = grid.size();
	int width = grid[0].size();
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width / 2; x++) {
			swap(grid[y][x], grid[y][width - 1 - x]);
		}
	}
	return;
}

int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	int height = -1;
	int width = -1;

	cin >> height >> width;

	mat grid(height, vec(width, 0));
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			cin >> grid[i][j];
			max_h = max(max_h, grid[i][j]);
			min_h = min(min_h, grid[i][j]);
		}
	}

	int result = numeric_limits<int>::max();
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			result = min(result, solve(grid));
			if (j == 0) {
				transform0(grid);
			}
		}
		if (i == 0) {
			transform1(grid);
		}
	}

	cout << result << endl;
	return 0;
}
accuracy: 1
time_ms: 3500
memory_kb: 81352
final_rank: 17

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
using namespace std;


typedef vector<int> vec;
typedef vector<vec> mat;
int maxm = 0, mini = 1e9;

int s[2000][2000];
int t[2000][2000];

bool check(const mat& A, int M) {
	int H = A.size();
	int W = A[0].size();
	for (int y = 0; y < H; y++) {
		for (int x = 0; x < W; x++) {
			s[y][x] = 0;
			t[y][x] = 0;
		}

	}

	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (abs(mini - A[i][j]) > M) {
				s[i][j] = 1;
			}
			if (abs(maxm - A[i][j]) > M) {
				t[i][j] = 1;
			}
		}
	}

	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (i + 1 < H)t[i + 1][j] |= t[i][j];
			if (j + 1 < W)t[i][j + 1] |= t[i][j];
		}
	}

	for (int i = H - 1; i >= 0; i--) {
		for (int j = W - 1; j >= 0; j--) {
			if (i - 1 >= 0)s[i - 1][j] |= s[i][j];
			if (j - 1 >= 0)s[i][j - 1] |= s[i][j];
		}
	}

	for (int i = 0; i < H; i++)
		for (int j = 0; j < W; j++)
			if (s[i][j] && t[i][j])return false;

	return true;
}

int solve(const mat& A) {
	int left = 0, right = 1e9, mid;
	while (left < right) {
		mid = (left + right) / 2;
		if (check(A, mid))right = mid;
		else left = mid + 1;
	}
	return left;
}

void f1(mat& A) {
	int H = A.size();
	int W = A[0].size();
	mat res(W, vec(H, 0));
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			res[W - 1 - j][H - 1 - i] = A[i][j];
		}
	}
	A = res;
}

void f2(mat& A) {
	int H = A.size();
	int W = A[0].size();
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W / 2; j++) {
			swap(A[i][j], A[i][W - 1 - j]);
		}
	}
}

int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif
	int H, W;
	cin >> H >> W;

	mat A(H, vec(W, 0));

	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			cin >> A[i][j];
			maxm = max(maxm, A[i][j]);
			mini = min(mini, A[i][j]);
		}
	}

	int ans = 1e9;
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			ans = min(ans, solve(A));
			if (j == 0)f1(A);
		}
		if (i == 0)f2(A);
	}

	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 3560
memory_kb: 81180
final_rank: 18

code_snippet: /* [Author : Hoang Duy Vu] - THPT Chuyen Nguyen Du    */
//#pragma GCC optimize(" unroll-loops")
//#pragma gcc optimize("Ofast")
//#pragma GCC optimization("Ofast")
//#pragma optimize(Ofast)
#include <bits/stdc++.h>
#define All(x) (x).begin(),(x).end()
#define ll long long
#define C make_pair
#define fi first
#define se second
#define two second.first
#define thr second.second
#define TASK "txt"
using namespace std;
template<typename T> bool maximize(T &res, const T &val) {
    if (res < val) { res = val; return true; } return false; }
template<typename T> bool minimize(T &res, const T &val) {
    if (res > val) { res = val; return true; } return false; }

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
const int LOG = 20;
const int INF = 1e9 + 7;
const ll LNF = 1e18 + 7;
const int mod = 1e9 + 7;
const int N = 2020;

int f[N] , a[2][N][N];
int n , m , maxt = 0 , mint = INF;

void input()
{
    cin >> n >> m;
    for (int i = 1 ; i <= n; i++)
        for (int j = 1 ; j <= m ; j++)
        {
            cin >> a[0][i][j];
            maximize(maxt,a[0][i][j]);
            minimize(mint,a[0][i][j]);
        }

    maxt -= mint;

    for (int i = 1 ; i <= n ; i++)
        for (int j = 1 ; j <= m ; j++)
        {
            a[0][i][j] -= mint;
            a[1][i][j] = maxt - a[0][i][j];
        }

}

bool case1(int h , int id)
{
    memset(f,0,sizeof(f));
    f[0] = m;
    for (int i = 1 ; i <= n ; i++)
    {
        int index = f[i - 1];
        for (int j = 1 ; j <= f[i - 1] ; j++)
            if (a[id][i][j] > h)
            {
                index = j - 1;
                break;
            }

        for (int j = index + 1 ; j <= m ; j++)
            if (maxt - a[id][i][j] > h) return false;

        f[i] = index;
    }

    int tt = 0;
    for (int i = 1 ; i <= n ; i++) tt += f[i];

    if (tt == 0) return false;
    if (tt == n*m) if (maxt - a[id][n][m] > h) return false;

    return true;
}

bool case2(int h , int id)
{
    memset(f,0,sizeof(f));
    f[n + 1] = m;
    for (int i = n ; i > 0 ; i--)
    {
        int index = f[i + 1];
        for (int j = 1 ; j <= f[i + 1] ; j++)
            if (a[id][i][j] > h)
            {
                index = j - 1;
                break;
            }

        for (int j = index + 1 ; j <= m ; j++)
            if (maxt - a[id][i][j] > h) return false;

        f[i] = index;

      //  cout << f[i] << " ";
    }

    int tt = 0;
    for (int i = 1 ; i <= n ; i++) tt += f[i];

    if (tt == 0) return false;
    if (tt == n*m) if (maxt - a[id][1][m] > h) return false;

    return true;
}

void solve()
{
    int l = 0 , r = 1e9 , res = 1e9;

    while (l <= r)
    {
        int mid = (l + r) >> 1;
        if ((case1(mid,0)|case1(mid,1)|case2(mid,0)|case2(mid,1)) == 1) 
        {
            res = mid;
            r = mid - 1;
        }
        else l = mid + 1;
    }

    cout << res << "\n";
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL); cout.tie(NULL);
    if(fopen(TASK".inp", "r")){
    freopen(TASK".inp","r",stdin);
    freopen(TASK".out","w",stdout);
    }

    int tk;
    tk = 1;
   //cin >> tk;
    while (tk--)
    {
        input();
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 35116
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int h, w, mx = 0, mn = 1 << 30;
    cin >> h >> w;
    vector<vector<int>> A(h, vector<int>(w));
    for(int y = 0; y < h; y++){
        for(int x = 0; x < w; x++){
            cin >> A[y][x];
            mx = max(mx, A[y][x]);
            mn = min(mn, A[y][x]);
        }
    }
    auto f = [&](int th){
        int p = 0;
        for(int y = 0; y < h; y++){
            for(int x = p; x < w; x++){
                if(A[y][x] > mn + th)p = x + 1;
            }
            for(int x = 0; x < p; x++){
                if(A[y][x] < mx - th)return false;
            }
        }
        return true;
    };
    auto Cswap = [&](){
        for(int y = 0; y < h; y++){
            for(int x = 0; 2 * x < w; x++){
                swap(A[y][x], A[y][w - 1 - x]);
            }
        }
    };
    auto Rswap = [&](){
        for(int x = 0; x < w; x++){
            for(int y = 0; 2 * y < h; y++){
                swap(A[y][x], A[h - 1 - y][x]);
            }
        }
    };
    auto search = [&](){
        int ng = -1, ok = 1 << 30;
        while(ng + 1 < ok){
            int mid = (ng + ok) / 2;
            if(f(mid))ok = mid;
            else ng = mid;
        }
        return ok;
    };
    int ans = 1 << 30;
    ans = min(ans, search());
    Cswap();
    ans = min(ans, search());
    Rswap();
    ans = min(ans, search());
    Cswap();
    ans = min(ans, search());
    cout << ans << '\n';
}
accuracy: 1
time_ms: 360
memory_kb: 18908
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int N = 2e3 + 5, oo = 1e9;

int m, n, a[N][N], b[N][N], mx[N][N], mn[N][N], v_max, v_min;

void rotate() {
	for (int i = 1; i <= m; ++i)
		for (int j = 1; j <= n; ++j)
			b[n - j + 1][i] = a[i][j];
	swap(a, b); swap(m, n);
}

bool check(int d) {
	for (int t = 4; t--;) {
		for (int i = 1; i <= m; ++i) 
			mx[i][n + 1] = -oo,
			mn[i][0] = oo;
		for (int i = 1; i <= m; ++i) {
			for (int j = n; j >= 1; --j)
				mx[i][j] = max(mx[i][j + 1], a[i][j]);
			for (int j = 1; j <= n; ++j)
				mn[i][j] = min(mn[i][j - 1], a[i][j]);
		}
		bool flag = 1; int j = 0;
		for (int i = 1; i <= m; ++i) {
			while (j <= n && (v_max - mn[i][j] > d || mx[i][j + 1] - v_min > d))
				++j;
			if (j > n) {
				flag = 0; break;
			}
		}
		if (flag) return 1;
		rotate();
	}
	return 0;
}

int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin >> m >> n; v_max = -oo; v_min = oo; 
	
	for (int i = 1; i <= m; ++i)
		for (int j = 1; j <= n; ++j)
			cin >> a[i][j], 
			v_min = min(v_min, a[i][j]), 
			v_max = max(v_max, a[i][j]);
	
	int lo = 0, hi = 1e9, res;
	while (lo <= hi) {
		int mi = (lo + hi) / 2;
		if (check(mi)) res = mi, hi = mi - 1;
		else lo = mi + 1;
	}
	cout << res << '\n';
	return 0;
}
accuracy: 1
time_ms: 1590
memory_kb: 66268
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
const long long MOD1 = 1000000007;
const long long MOD2 = 998244353;
typedef long long ll;
//typedef int ll;
typedef pair<long long, long long> P;
const long long INF = 1000000010;
template <typename T>
void input_arr(vector<T>& A, ll N) {
	for (ll i = 0; i < N; i++) {
		cin >> A[i];
	}
}
template <typename T, typename Q>
void input_arr(vector<pair<T, Q>>& A, ll N) {
	for (ll i = 0; i < N; i++) {
		cin >> A[i].first >> A[i].second;
	}
}
template <typename T>
void input_arr(vector<vector<T>>& A, ll H, ll W) {
	for (ll i = 0; i < H; i++) {
		for (ll j = 0; j < W; j++) {
			cin >> A[i][j];
		}
	}
}
void solve() {
    ll H, W; cin >> H >> W;
    vector<vector<ll>>A(2010, vector<ll>(2010)); input_arr(A, H, W);
    vector<vector<P>>J(2010, vector<P>(2010)), I(2010, vector<P>(2010));
    ll ans = INF;
    for (ll a = 0; a < 4; a++) {
            for (ll i = 0; i < W; i++) {
            J[0][i] = {A[0][i], A[0][i]};
            I[H - 1][i] = {A[H - 1][i], A[H - 1][i]};
        }
        //  J, I について、first : MAX, second : min
        for (ll i = 1; i < H; i++) {
            for (ll j = 0; j < W; j++) {
                J[i][j] = {max(J[i - 1][j].first, A[i][j]), min(J[i - 1][j].second, A[i][j])};
            }
        }
        for (ll i = H - 2; i >= 0; i--) {
            for (ll j = 0; j < W; j++) {
                I[i][j] = {max(I[i + 1][j].first, A[i][j]), min(I[i + 1][j].second, A[i][j])};
            }
        }
        ll ng = -1, ok = 1000000000;
        while (abs(ok - ng) > 1) {
            ll mid = (ok + ng) / 2;
            bool check1 = true, check2 = true;
            P all = {-INF, INF}, all2 = {-INF, INF};
            ll pos = H - 1;
            for (ll i = 0; i < W; i++) {
                if (pos < 0) {
                    all2 = {max(all2.first, I[pos + 1][i].first), min(all2.second, I[pos + 1][i].second)};
                    continue;
                }
                while (pos >= 0 && max(all.first, J[pos][i].first) - min(all.second, J[pos][i].second) > mid) {
                    pos--;
                }
                if (pos + 1 < H) all2 = {max(all2.first, I[pos + 1][i].first), min(all2.second, I[pos + 1][i].second)};
                if (pos >= 0) all = {max(all.first, J[pos][i].first), min(all.second, J[pos][i].second)};
            }
            if (all == make_pair(-INF, INF)) check1 = false;
            if (all2 == make_pair(-INF, INF)) all2 = {0, 0};
            if (max(all.first - all.second, all2.first - all2.second) > mid) check1 = false;
            all = {-INF, INF}, all2 = {-INF, INF};
            pos = 0;
            for (ll i = 0; i < W; i++) {
                if (pos >= H) {
                    all = {max(all.first, J[pos - 1][i].first), min(all.second, J[pos - 1][i].second)};
                    continue;
                }
                while (pos < H && max(all2.first, I[pos][i].first) - min(all2.second, I[pos][i].second) > mid) {
                    pos++;
                }
                if (pos - 1 >= 0) all = {max(all.first, J[pos - 1][i].first), min(all.second, J[pos - 1][i].second)};
                if (pos < H) all2 = {max(all2.first, I[pos][i].first), min(all2.second, I[pos][i].second)};
            }
            if (all2 == make_pair(-INF, INF)) check2 = false;
            if (all == make_pair(-INF, INF)) all = {0, 0};
            if (max(all.first - all.second, all2.first - all2.second) > mid) check2 = false;
            if (check1 || check2) ok = mid;
            else ng = mid;
        }
        ans = min(ans, ok);
        vector<vector<ll>>B(W, vector<ll>(H));
        for (ll i = 0; i < H; i++) {
            for (ll j = 0; j < W; j++) {
                B[j][H - i - 1] = A[i][j];
                J[j][H - i - 1] = J[i][j];
                I[j][H - i - 1] = I[i][j];
            }
        }
        A = B;
        swap(H, W);
    }
    cout << ans << endl;
}
int main() {
    ll T = 1; //cin >> T;
    while (T--) solve();
}
accuracy: 1
time_ms: 1290
memory_kb: 192336
final_rank: 16

code_snippet: #include<iostream>
#include<algorithm>    
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<ctime>
#include<fstream>
#include<functional>
#include<map>
#include<math.h>
#include<queue>
#include<set>
#include<stack>
#include<stdio.h>
#include<string>
#include<tuple>
#include<vector>
//#include<bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i, x) for(ll i = 0; i < x; i++)
#define rep2(i, x) for(ll i = 1; i <= x; i++)
#define rep3(i, x, y) for(ll i = x; i < y; i++)
#define rep4(i, x) for(ll i = x - 1; i >= 0; i--)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define puts(x) cout << (x) << "\n"
using ll = long long;
using ld = long double;
using namespace std;
const ll INF = 1000000000000000000;
const int intINF = 1000000000;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ld pi = 3.141592653589793238;
//const ld EPS = 1e-9;
typedef string::const_iterator State;
class ParseError {};

bool isprime(int p) {
	if (p == 1) return false;
	for (int i = 2; i < p; i++) {
		if (p % i == 0) return false;
	}
	return true;
}
ll gcd(ll a, ll b) {
	if (b == 0) { return a; }
	return gcd(b, a % b);
}
//ax + by = cが整数解をもつための必要十分条件は c が gcd(a,b) で割り切れること。
// 返り値: a と b の最大公約数
// ax + by = gcd(a, b) を満たす (x, y) が格納される
//main関数内に extGCD(a, b, x, y); でx, yに解が格納
ll extGCD(ll a, ll b, ll& x, ll& y) {
	if (b == 0) {
		x = 1;
		y = 0;
		return a;
	}
	ll d = extGCD(b, a % b, y, x);
	y -= a / b * x;
	return d;
}
ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}
ll keta(ll n) {
	ll res = 0;
	while (n >= 1) {
		//res++;
		res += n % 10;
		n /= 10;
	}
	return res;
}
ll modpow(ll x, ll y, ll m) {
	ll res = 1;
	while (y) {
		if (y % 2) { res *= x; res %= m; }
		x = x * x % m; y /= 2;
	}
	return res;
}
ll kaijyo[1000005];
void nCkinit(ll n, ll m) {
	ll cnt = 1; kaijyo[0] = 1;
	for (int h = 1; h <= n; h++) { cnt *= h; cnt %= m; kaijyo[h] = cnt; }
}
ll nCk(ll n, ll k, ll m) {
	/*ll a = 1, b = 1;
	for (int h = 1; h <= n; h++) { a *= h; a %= m; }
	for (int h = 1; h <= k; h++) { b *= h; b %= m; }
	for (int h = 1; h <= n - k; h++) { b *= h; b %= m; }*/
	ll a = kaijyo[n], b = kaijyo[k] * kaijyo[n - k] % m;
	return a * modpow(b, m - 2, m) % m;
}
//printf("%.10f\n", n);
typedef pair <ll, ll> P;
typedef pair <ld, ll> pp;
ll dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };
struct edge { ll to; ld cost; };


vector<ll> spf;
void smallest_prime_factors(ll n) {
	spf.resize(n + 1); spf[1] = 1;
	for (int i = 2; i <= n; i++) {
		if (!spf[i]) {
			for (int j = i; j < n; j += i) { spf[j] = i; }
		}
	}
}
std::map<int, int> high_speed_prime_factor(int n) {
	std::map<int, int> res;
	while (n != 1) {
		res[spf[n]]++;
		n /= spf[n];
	}
	return res;
}

struct Point {
	ll x, y;
};
bool operator<(const Point& a1, const Point& a2) {
	if (a1.x < a2.x) return true;
	if (a1.x > a2.x) return false;
	if (a1.y < a2.y) return true;
	return false;
}
struct status {
	ll a;
	ll b;
	ll c;

	bool operator<(const status& rhs) const { return c < rhs.c; };
	bool operator>(const status& rhs) const { return c > rhs.c; };
};

void yesno(bool ok) {
	if (ok) { cout << "Yes\n"; }
	else { cout << "No\n"; }
}

ll a[2005][2005];

int main() {
	srand((unsigned)time(NULL));
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	//cout << fixed << setprecision(15);

	ll n, m; cin >> n >> m;
	ll mi = INF, ma = 0;
	rep2(i, n) {
		rep2(j, m) {
			cin >> a[i][j];
			mi = min(mi, a[i][j]);
			ma = max(ma, a[i][j]);
		}
	}
	ll ok = -1, ng = ma - mi, mid = (ok + ng) / 2;
	while (ng - ok > 1) {
      mid = (ok + ng) / 2;
		ll ki = min(mi + mid, ma - mid - 1), ka = max(mi + mid + 1, ma - mid);
		//小さいほう:mi~ki、大きいほう:ka~ma
		//小さいほうが左、大きいほうが右
		//矛盾チェック
		vector<ll> l(n + 1), r(n + 1, INF);
		bool flag = true;
		rep2(i, n) {
			bool kf = false;
			rep2(j, m) {
				if (mi + mid < a[i][j] && a[i][j] < ma - mid) { flag = false; break; }
				if (ka <= a[i][j]) { kf = true; r[i] = min(r[i], j); }
				if (a[i][j] <= ki) {
					l[i] = max(l[i], j);
					if (kf) { flag = false; break; }
				}
			}
		}
      
		if (flag) {
			//単調増加できる？
			ll now = l[0]; bool ok = true;
			rep2(i, n) {
				if (r[i] <= now) { ok = false; break; }
				now = max(now, l[i]);
			}
			if (ok) { ng = mid; mid = (ok + ng) / 2; continue; }
			now = r[0]; ok = true;
			//単調減少できる？
			rep2(i, n) {
				if (now <= l[i]) { ok = false; break; }
				now = min(now, r[i]);
			}
			if (ok) { ng = mid; mid = (ok + ng) / 2; continue; }
		}
		//小さいほうが右、大きいほうが左
		//矛盾チェック
		rep2(i, n) { l[i] = 0; r[i] = INF; }
		flag = true;
		rep2(i, n) {
			bool kf = false;
			rep2(j, m) {
				if (mi + mid < a[i][j] && a[i][j] < ma - mid) { flag = false; break; }
				if (a[i][j] <= ki) { kf = true; r[i] = min(r[i], j); }
				if (ka <= a[i][j]) {
					l[i] = max(l[i], j);
					if (kf) { flag = false; break; }
				}
			}
		}
		if (flag) {
			//単調増加できる？
			ll now = l[0]; bool ok = true;
			rep2(i, n) {
				if (r[i] <= now) { ok = false; break; }
				now = max(now, l[i]);
			}
			if (ok) { ng = mid; mid = (ok + ng) / 2; continue; }
			now = r[0]; ok = true;
			//単調減少できる？
			rep2(i, n) {
				if (now <= l[i]) { ok = false; break; }
				now = min(now, r[i]);
			}
			if (ok) { ng = mid; mid = (ok + ng) / 2; continue; }
		}
		ok = mid; mid = (ok + ng) / 2; continue;
	}
	cout << ng << endl;
	return 0;
}
accuracy: 1
time_ms: 690
memory_kb: 36236
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint = long long;
#define rep(i, n) for(int i = 0; i < int(n); i++)
#define rep2(i, l, n) for(int i = int(l); i < int(n); i++)

lint mn, mx;

bool is_ok(int h, int w, const vector<vector<lint>> &a, lint k){
    vector<vector<bool>> is_min(h, vector<bool>(w));
    
    rep(i, h){
        rep(j, w){
            is_min[i][j] = (a[i][j] - mn <= k);
        }
    }
    
    lint mx_min = mx;
    int back_x = w;
    rep(i, h){
        int x = w;
        rep(j, w){
            if(!is_min[i][j]){
                x = j;
                break;
            }
        }
        x = min(x, back_x);
        
        rep2(j, x, w){
            mx_min = min(mx_min, a[i][j]);
        }
        
        back_x = x;
    }
    
    return mx - mx_min <= k;
}

lint solve(int h, int w, const vector<vector<lint>> &a){
    lint ng = -1, ok = mx - mn + 1;
    while(abs(ok - ng) > 1){
        lint mid = (ok + ng) / 2;
        
        if(is_ok(h, w, a, mid)){
            ok = mid;
        }else{
            ng = mid;
        }
    }
    
    return ok;
}

int main(){
    int h, w;
    cin >> h >> w;
    vector<vector<lint>> a(h, vector<lint>(w));
    rep(i, h){
        rep(j, w){
            cin >> a[i][j];
        }
    }
    
    mn = 1e18, mx = -1e18;
    rep(i, h){
        rep(j, w){
            mn = min(mn, a[i][j]);
            mx = max(mx, a[i][j]);
        }
    }
    
//    int k = 18;
//    rep(i, h){
//        rep(j, w){
//            cout << (a[i][j] - mn <= k) << " ";
//        }
//        cout << endl;
//    }
//    cout << endl;
//    rep(i, h){
//        rep(j, w){
//            cout << (mx - a[i][j] <= k) << " ";
//        }
//        cout << endl;
//    }
//    cout << endl;
    
    lint ans = mx - mn;
    rep(c, 4){
        ans = min(ans, solve(h, w, a));
//        cout << solve(h, w, a) << endl;
        
        vector<vector<lint>> a2(w, vector<lint>(h));
        rep(i, h) rep(j, w) a2[w - j - 1][i] = a[i][j];
        
        a = a2;
        swap(h, w);
    }
    
    cout << ans << endl;
}
accuracy: 1
time_ms: 2140
memory_kb: 96752
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint = long long;
#define rep(i, n) for(int i = 0; i < int(n); i++)
#define rep2(i, l, n) for(int i = int(l); i < int(n); i++)

lint mn, mx;

bool is_ok(int h, int w, const vector<vector<lint>> &a, lint k){
    vector<vector<bool>> is_min(h, vector<bool>(w));
    
    rep(i, h){
        rep(j, w){
            is_min[i][j] = (a[i][j] - mn <= k);
        }
    }
    
    lint mx_min = mx;
    int back_x = w;
    rep(i, h){
        int x = w;
        rep(j, w){
            if(!is_min[i][j]){
                x = j;
                break;
            }
        }
        x = min(x, back_x);
        
        rep2(j, x, w){
            mx_min = min(mx_min, a[i][j]);
        }
        
        back_x = x;
    }
    
    return mx - mx_min <= k;
}

lint solve(int h, int w, const vector<vector<lint>> &a){
    lint ng = -1, ok = mx - mn + 1;
    while(abs(ok - ng) > 1){
        lint mid = (ok + ng) / 2;
        
        if(is_ok(h, w, a, mid)){
            ok = mid;
        }else{
            ng = mid;
        }
    }
    
    return ok;
}

int main(){
    int h, w;
    cin >> h >> w;
    vector<vector<lint>> a(h, vector<lint>(w));
    rep(i, h){
        rep(j, w){
            cin >> a[i][j];
        }
    }
    
    mn = 1e18, mx = -1e18;
    rep(i, h){
        rep(j, w){
            mn = min(mn, a[i][j]);
            mx = max(mx, a[i][j]);
        }
    }
    
//    int k = 18;
//    rep(i, h){
//        rep(j, w){
//            cout << (a[i][j] - mn <= k) << " ";
//        }
//        cout << endl;
//    }
//    cout << endl;
//    rep(i, h){
//        rep(j, w){
//            cout << (mx - a[i][j] <= k) << " ";
//        }
//        cout << endl;
//    }
//    cout << endl;
    
    lint ans = mx - mn;
    rep(c, 4){
        ans = min(ans, solve(h, w, a));
//        cout << solve(h, w, a) << endl;
        
        vector<vector<lint>> a2(w, vector<lint>(h));
        rep(i, h) rep(j, w) a2[w - j - 1][i] = a[i][j];
        
        a = a2;
        swap(h, w);
    }
    
    cout << ans << endl;
}
accuracy: 1
time_ms: 2140
memory_kb: 96828
final_rank: 13

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

constexpr int INF = 1 << 30;

void solve() {
    int h, w;
    cin >> h >> w;

    auto grid = vector(h, vector(w, 0));
    int mi = INF, ma = 0;
    for (auto& v : grid) {
        for (auto& x : v) {
            cin >> x;
            mi = min(mi, x);
            ma = max(ma, x);
        }
    }

    int ok = ma - mi, ng = -1;
    while (ok - ng > 1) {
        int d = (ok + ng) / 2;

        bool valid = false;
        for (int q = 0; q < 2; ++q) {
            // IOIがmiを含まない側の場合
            {
                int l = 0;  // [0, l)はIOIに属する

                bool judge = true;
                for (const auto& v : grid) {
                    for (int i = 0; i < w; ++i) {
                        if (v[i] - mi > d) l = max(l, i + 1);
                    }
                    for (int i = 0; i < l; ++i) {
                        if (ma - v[i] > d) judge = false;
                    }
                }
                if (judge) valid = true;
            }

            // IOIがmaを含まない側の場合
            {
                int l = 0;  // [0, l)はIOIに属する

                bool judge = true;
                for (const auto& v : grid) {
                    for (int i = 0; i < w; ++i) {
                        if (ma - v[i] > d) l = max(l, i + 1);
                    }
                    for (int i = 0; i < l; ++i) {
                        if (v[i] - mi > d) judge = false;
                    }
                }
                if (judge) valid = true;
            }

            // 左右反転してもう一度
            for (auto& v : grid) reverse(v.begin(), v.end());
        }

        if (valid) {
            ok = d;
        } else {
            ng = d;
        }
    }

    cout << ok << "\n";
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 1310
memory_kb: 18920
final_rank: 6

code_snippet: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>

#include <algorithm>
#include <random>
#include <bitset>
#include <queue>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <chrono>
#include <iostream>
#include <limits>
#include <numeric>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

template <class T>
istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}

template <class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    if (!v.empty()) {
        os << v.front();
        for (int i = 1; i < v.size(); ++i) os << ' ' << v[i];
    }
    return os;
}

int main() {
#ifdef LBT
    freopen("test.in", "r", stdin);
    int nol_cl = clock();
#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, M;
    cin >> N >> M;
    vector<vector<int>> A(N, vector<int>(M));
    cin >> A;
    vector<pair<int, pair<int, int>>> pos;
    pos.reserve(N * M);
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < M; ++j) pos.emplace_back(A[i][j], make_pair(i, j));
    sort(pos.begin(), pos.end());
    int ans = numeric_limits<int>::max();
    for (int rep = 1; rep <= 4; ++rep) {
        int mx = numeric_limits<int>::min(), mn = numeric_limits<int>::max();
        vector<int> R(N);
        for (int i = 0; i < N * M - 1; ++i) {
            int x, y;
            tie(x, y) = pos[i].second;
            while (x >= 0 && R[x] <= y) {
                while (R[x] <= y) {
                    mx = max(mx, A[x][R[x]]);
                    mn = min(mn, A[x][R[x]]);
                    ++R[x];
                }
                --x;
            }
            ans = min(ans, max(pos.back().first - pos[i + 1].first, mx - mn));
        }
        if (rep & 1) {
            reverse(A.begin(), A.end());
            for (auto& pr : pos) pr.second.first = N - 1 - pr.second.first;
        } else if (rep & 2) {
            for (int i = 0; i < N; ++i) reverse(A[i].begin(), A[i].end());
            for (auto& pr : pos) pr.second.second = M - 1 - pr.second.second;
        }
    }
    cout << ans << '\n';

#ifdef LBT
    LOG("Time: %dms\n", int((clock() - nol_cl) / (double)CLOCKS_PER_SEC * 1000));
#endif
    return 0;
}
accuracy: 1
time_ms: 630
memory_kb: 65472
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T,class U> using P = pair<T,U>;
template<class T> using vec = vector<T>;
template<class T> using vvec = vector<vec<T>>;

constexpr int inf = 1e9+1;
int ma[4][2010][2010] = {};
int mi[4][2010][2010] = {};
int exist[4][2010] = {};
int A[4][2010][2010] = {};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int H,W;
    int M = 0;
    cin >> H >> W;
    for(int i=0;i<H;i++) for(int j=0;j<W;j++){
        cin >> A[0][i][j];
        A[1][W-j-1][i] = A[0][i][j];
        M = max(M,A[0][i][j]);
    }
    for(int i=0;i<H;i++) for(int j=0;j<W;j++) A[2][i][j] = A[0][i][W-j-1];
    for(int i=0;i<W;i++) for(int j=0;j<H;j++) A[3][i][j] = A[1][i][H-j-1];

    for(int t=0;t<4;t++) for(int i=0;i<=max(H,W);i++){
        exist[t][i] = -1;
        for(int j=0;j<=max(H,W);j++){
            ma[t][i][j] = 0;
            mi[t][i][j] = inf;
        }
    }

    auto calc = [&](int H,int W,int t){
        for(int i=0;i<H;i++) for(int j=W-1;j>=0;j--){
            ma[t][i][j] = max(ma[t][i][j+1],A[t][i][j]);
            mi[t][i][j] = min(mi[t][i][j+1],A[t][i][j]);
            if(A[t][i][j]==M) exist[t][i] = max(exist[t][i],j);
        }
    };

    calc(H,W,0);
    calc(W,H,1);
    calc(H,W,2);
    calc(W,H,3);
    
    auto check = [&](int H,int W,int d,int t){
        bool res = false;
        int ma2 = 0,mi2 = inf,pl = W-1;
        bool judge = true;
        for(int i=0;i<H;i++){
            int l = -1;
            for(int j=0;j<=pl;j++){
                if(A[t][i][j]<M-d) break;
                l = j;
            }
            if(l<exist[t][i]){
                judge = false;
                break;
            }
            mi2 = min(mi2,mi[t][i][l+1]);
            ma2 = max(ma2,ma[t][i][l+1]);
            pl = l;
        }
        res |= judge && ma2-mi2<=d;
        ma2 = 0,mi2 = inf,pl = W-1,judge = true;
        for(int i=H-1;i>=0;i--){
            int l = -1;
            for(int j=0;j<=pl;j++){
                if(A[t][i][j]<M-d) break;
                l = j;
            }
            if(l<exist[t][i]){
                judge = false;
                break;
            }
            mi2 = min(mi2,mi[t][i][l+1]);
            ma2 = max(ma2,ma[t][i][l+1]);
            pl = l;
        }
        res |= judge && ma2-mi2<=d;
        return res;
    };

    auto ok = [&](int d){
        bool res = false;
        res |= check(H,W,d,0);
        res |= check(W,H,d,1);
        res |= check(H,W,d,2);
        res |= check(W,H,d,3);
        return res;
    };

    int l = -1,r = M;
    while(l+1<r){
        int m = (l+r)>>1;
        (ok(m)? r:l) = m;
    }
    cout << r << endl;
}
accuracy: 1
time_ms: 440
memory_kb: 191716
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <array>
#include <list>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <tuple>
#include <bitset>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>
#include <cassert>
#include <random>
using vvi = std::vector<std::vector<int>>;
int shrink_to_right(const int left_max_value, const std::vector<std::vector<int>>& left_max, const std::vector<std::vector<int>>& right_min) {
	int min = INT_MAX;
	std::vector<int> right_pos(left_max.size());
	for (auto i = 0; i < left_max.size(); ++i) {
		right_pos[i] = std::distance(left_max[i].begin(), std::upper_bound(left_max[i].begin(), left_max[i].end(), left_max_value));
	}
	int min_pos = right_min.front().size();
	for (auto i = 0; i < right_min.size(); ++i) {
		min_pos = std::min(min_pos, right_pos[i]);
		if (min_pos < right_min[i].size())
			min = std::min(min, right_min[i][min_pos]);
	}
	int result = min;
	min = INT_MAX;
	min_pos = right_min.front().size();
	for (auto i = 1; i <= right_min.size(); ++i) {
		min_pos = std::min(min_pos, right_pos[right_pos.size() - i]);
		if (min_pos < right_min[right_min.size() - i].size())
			min = std::min(min, right_min[right_min.size() - i][min_pos]);
	}
	return std::max(result, min);
}
int first_less_or_equals(const std::vector<int>& array, const int value) {
	int left = 0;
	int right = array.size();
	while (left < right) {
		auto mid = (left + right) / 2;
		if (array[mid] <= value) right = mid;
		else left = mid + 1;
	}
	return right;
}
int shrink_to_left(const int right_max_value, const std::vector<std::vector<int>>& right_max, const std::vector<std::vector<int>>& left_min) {
	int min = INT_MAX;
	std::vector<int> right_pos(right_max.size());
	for (auto i = 0; i < right_max.size(); ++i) {
		right_pos[i] = first_less_or_equals(right_max[i], right_max_value) - 1;
	}
	int max_pos = -1;
	for (auto i = 0; i < left_min.size(); ++i) {
		max_pos = std::max(max_pos, right_pos[i]);
		if (max_pos >= 0)
			min = std::min(min, left_min[i][max_pos]);
	}
	int result = min;
	min = INT_MAX;
	max_pos = -1;
	for (int i = left_min.size() - 1; i >= 0; --i) {
		max_pos = std::max(max_pos, right_pos[i]);
		if (max_pos >= 0)
			min = std::min(min, left_min[i][max_pos]);
	}
	return std::max(result, min);
}
int shrink_to_bottom(const int top_max_value, const std::vector<std::vector<int>>& top_max, const std::vector<std::vector<int>>& bottom_min) {
	int min = INT_MAX;
	std::vector<int> bottom_pos(top_max.size());
	for (auto i = 0; i < top_max.size(); ++i) {
		bottom_pos[i] = std::distance(top_max[i].begin(), std::upper_bound(top_max[i].begin(), top_max[i].end(), top_max_value));
	}
	int min_pos = bottom_min.front().size();
	for (auto i = 0; i < bottom_min.size(); ++i) {
		min_pos = std::min(min_pos, bottom_pos[i]);
		if (min_pos < bottom_min[i].size())
			min = std::min(min, bottom_min[i][min_pos]);
	}
	int result = min;
	min = INT_MAX;
	min_pos = bottom_min.front().size();
	for (auto i = 1; i <= bottom_min.size(); ++i) {
		min_pos = std::min(min_pos, bottom_pos[bottom_pos.size() - i]);
		if (min_pos < bottom_min[bottom_min.size() - i].size())
			min = std::min(min, bottom_min[bottom_min.size() - i][min_pos]);
	}
	return std::max(result, min);
}
int shrink_to_top(const int bottom_max_value, const std::vector<std::vector<int>>& bottom_max, const std::vector<std::vector<int>>& top_min) {
	int min = INT_MAX;
	std::vector<int> bottom_pos(bottom_max.size());
	for (auto i = 0; i < bottom_max.size(); ++i) {
		bottom_pos[i] = first_less_or_equals(bottom_max[i], bottom_max_value) - 1;
	}
	int max_pos = -1;
	for (auto i = 0; i < top_min.size(); ++i) {
		max_pos = std::max(max_pos, bottom_pos[i]);
		if (max_pos >= 0)
			min = std::min(min, top_min[i][max_pos]);
	}
	int result = min;
	min = INT_MAX;
	max_pos = -1;
	for (int i = top_min.size() - 1; i >= 0; --i) {
		max_pos = std::max(max_pos, bottom_pos[i]);
		if (max_pos >= 0)
			min = std::min(min, top_min[i][max_pos]);
	}
	return std::max(result, min);
}
int cal_max_min(const int max_max_value, const vvi& top_max, const vvi& top_min, const vvi& left_max, const vvi& left_min, const vvi& bottom_max, const vvi& bottom_min, const vvi& right_max, const vvi& right_min) {
	return std::max({
		shrink_to_right(max_max_value, left_max, right_min),
		shrink_to_left(max_max_value, right_max, left_min),
		shrink_to_bottom(max_max_value, top_max, bottom_min),
		shrink_to_top(max_max_value, bottom_max, top_min)
		});
}
int main() {
	int h, w; std::cin >> h >> w;
	std::vector<std::vector<int>> state(h, std::vector<int>(w)); for (auto& line : state) for (auto& area : line) std::cin >> area;
	std::vector<std::vector<int>> flipped(w, std::vector<int>(h));
	for (auto i = 0; i < h; ++i) for (auto j = 0; j < w; ++j) flipped[j][i] = state[i][j];
	auto top_max = flipped;
	auto top_min = flipped;
	auto left_max = state;
	auto left_min = state;
	auto bottom_max = flipped;
	auto bottom_min = flipped;
	auto right_max = state;
	auto right_min = state;
	for (auto i = 0; i < h; ++i) for (auto j = 1; j < w; ++j) {
		left_max[i][j] = std::max(left_max[i][j], left_max[i][j - 1]);
		left_min[i][j] = std::min(left_min[i][j], left_min[i][j - 1]);
		right_max[i][w - j - 1] = std::max(right_max[i][w - j - 1], right_max[i][w - j]);
		right_min[i][w - j - 1] = std::min(right_min[i][w - j - 1], right_min[i][w - j]);
	}
	for (auto i = 1; i < h; ++i) for (auto j = 0; j < w; ++j) {
		top_max[j][i] = std::max(top_max[j][i], top_max[j][i - 1]);
		top_min[j][i] = std::min(top_min[j][i], top_min[j][i - 1]);
		bottom_max[j][h - i - 1] = std::max(bottom_max[j][h - i - 1], bottom_max[j][h - i]);
		bottom_min[j][h - i - 1] = std::min(bottom_min[j][h - i - 1], bottom_min[j][h - i]);
	}
	std::vector<std::pair<int, int>> coordinates; coordinates.reserve(h * w);
	for (auto i = 0; i < h; ++i) for (auto j = 0; j < w; ++j) coordinates.emplace_back(i, j);
	std::sort(coordinates.begin(), coordinates.end(), [&state](const std::pair<int, int>& a, const std::pair<int, int>& b) {return state[a.first][a.second] < state[b.first][b.second]; });
	const int max_value = state[coordinates.back().first][coordinates.back().second];
	const int min_value = state[coordinates.front().first][coordinates.front().second];
	auto min = 0;
	auto max = coordinates.size();
	while (min < max) {
		auto mid = (min + max) / 2;
		auto min_max = state[coordinates[mid].first][coordinates[mid].second];
		auto max_min = cal_max_min(min_max, top_max, top_min, left_max, left_min, bottom_max, bottom_min, right_max, right_min);
		auto min_diff = min_max - min_value;
		auto max_diff = max_value - max_min;
		if (min_diff < max_diff) {
			min = mid + 1;
		}
		else {
			max = mid;
		}
	}
	int result = INT_MAX;
	if (min > 0) {
		int min_max = state[coordinates[min - 1].first][coordinates[min - 1].second];
		result = max_value - cal_max_min(min_max, top_max, top_min, left_max, left_min, bottom_max, bottom_min, right_max, right_min);
	}
	if (min < coordinates.size()) {
		int min_max = state[coordinates[min].first][coordinates[min].second];
		result = std::min(result, min_max - min_value);
	}
	std::cout << result << '\n';
}
accuracy: 1
time_ms: 2010
memory_kb: 191048
final_rank: 20