//satyaki3794
#include <bits/stdc++.h>
#include <sys/resource.h>
#define ff first
#define ss second
#define pb push_back
#define MOD (1000000007LL)
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<ll, ll> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod = MOD){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}



const int N = 10002;
int n, cc, choices[N][3], seg_idx[N][3], totnodes;
int disc[16*N], low[16*N], scc_idx[16*N], sccnum, ticks;
bool instack[16*N];
stack<int> st;
iii arr[2*N];
vector<int> adj[16*N];
map<int, int> opposite;


void build(int node, int s, int e){
	if(s > e)	return;
	totnodes = max(totnodes, node);
	if(s == e){
		seg_idx[arr[s].ss.ff][arr[s].ss.ss] = node;
		return;
	}
	int mid = (s+e)/2;
	build(LEFT(node), s, mid);
	build(RIGHT(node), mid+1, e);
}

int get_opposite(int n){
	return opposite[n];
}


void add_edge(int node, int s, int e, int lo, int hi, int idx){
	if(s > e || lo > e || s > hi)	return;
	if(s >= lo && e <= hi){
// cout<<"found incompatibility between nodes "<<node<<" "<<idx<<endl;
// cout<<"so added edges "<<node<<" to "<<get_opposite(idx)<<" and "<<idx<<" to "<<get_opposite(node)<<endl;
		adj[node].pb(get_opposite(idx));
		adj[idx].pb(get_opposite(node));
		return;
	}
	int mid = (s+e)/2;
	add_edge(LEFT(node), s, mid, lo, hi, idx);
	add_edge(RIGHT(node), mid+1, e, lo, hi, idx);
}


void tarjan(int v){

	disc[v] = low[v] = ++ticks;
	instack[v] = true;
	st.push(v);

	for(auto vv : adj[v])
		if(disc[vv] == -1){
			tarjan(vv);
			low[v] = min(low[v], low[vv]);
		}
		else if(instack[vv]){
			low[v] = min(low[v], disc[vv]);
		}


	if(low[v] == disc[v]){
		++sccnum;
		while(!st.empty() && st.top() != v){
			instack[st.top()] = false;
			scc_idx[st.top()] = sccnum;
			st.pop();
		}
		instack[st.top()] = false;
		scc_idx[st.top()] = sccnum;
		st.pop();
	}
}



bool possible(int mid){

	sccnum = ticks = 0;
	for(int i=1;i<=2*totnodes;i++){
		adj[i].clear();
		disc[i] = low[i] = scc_idx[i] = -1;
		instack[i] = false;
	}
	while(!st.empty())
		st.pop();

	int lptr = 1, rptr = 1;
	for(int i=1;i<=2*n;i++){

		while(lptr < i && arr[lptr].ff <= arr[i].ff-mid)
			lptr++;
		while(rptr+1 <= 2*n && arr[rptr+1].ff < arr[i].ff+mid)
			rptr++;

// cout<<"at i = "<<i<<": "<<lptr<<" "<<rptr<<endl;

		if(lptr <= i-1)
			add_edge(1, 1, 2*n, lptr, i-1, seg_idx[arr[i].ss.ff][arr[i].ss.ss]);
		if(rptr >= i+1)
			add_edge(1, 1, 2*n, i+1, rptr, seg_idx[arr[i].ss.ff][arr[i].ss.ss]);
	}

	for(int i=1;i<=2*n;i++){
		int node = seg_idx[arr[i].ss.ff][arr[i].ss.ss], temp = node;
		node /= 2;
		while(node >= 1){
			adj[temp].pb(node);
// cout<<"yolo added edges "<<node<<" to "<<temp<<" and "<<temp<<" to "<<node<<endl;
			node /= 2;
		}
	}


// cout<<"extra edges"<<endl;
// 	for(int i=1;i<=n;i++){

// cout<<"found incompatibilty between nodes "<<seg_idx[i][1]<<" "<<seg_idx[i][2]<<endl;
		
// 		// adj[seg_idx[i][1]].pb(totnodes + seg_idx[i][2]);
// 		// adj[seg_idx[i][2]].pb(totnodes + seg_idx[i][1]);

// 		// adj[totnodes + seg_idx[i][1]].pb(seg_idx[i][2]);
// 		// adj[totnodes + seg_idx[i][2]].pb(seg_idx[i][1]);
// 	}

// cout<<16*N<<" "<<totnodes<<" "<<2*totnodes<<endl;

	ticks = 0;
	for(int i=1;i<=2*totnodes;i++)
		if(disc[i] == -1)
			tarjan(i);

// cout<<ticks<<" "<<totnodes<<endl;;
// for(int i=1;i<=ticks;i++)	cout<<scc_idx[i]<<" ";cout<<endl;

	for(int i=1;i<=2*n;i++){
		int node = seg_idx[arr[i].ss.ff][arr[i].ss.ss];
		if(scc_idx[node] == scc_idx[get_opposite(node)]){
// cout<<"shit occurred at "<<node<<endl;
			return false;
		}
	}

	return true;
}



int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

    struct rlimit rl;
    int result = getrlimit(RLIMIT_STACK, &rl);
    rl.rlim_cur = 32 * 1024 * 1024;
    result = setrlimit(RLIMIT_STACK, &rl);

    //http://codeforces.com/blog/entry/50500?#comment-344091
    //if nodes A and B are under NAND, add edges a->!b and b->!a
    //for each leaf of segment tree l and any of its ancestors a, add edge l->a
    //edge a->b says that if a is true, so is b

    scanf("%d", &n);
    for(int i=1;i<=n;i++){
    	scanf("%d%d", &choices[i][1], &choices[i][2]);
    	arr[2*i-1] = {choices[i][1], {i, 1}};
    	arr[2*i] = {choices[i][2], {i, 2}};
    }
    sort(arr+1, arr+2*n+1);
    build(1, 1, 2*n);

    for(int i=1;i<=totnodes;i++){
    	opposite[i] = totnodes+i;
    	opposite[totnodes+i] = i;
    }

    for(int i=1;i<=n;i++){
    	opposite[seg_idx[i][1]] = seg_idx[i][2];
    	opposite[seg_idx[i][2]] = seg_idx[i][1];
    }

// cout<<totnodes<<" "<<8*N<<endl;
// cout<<"opposite:\n";
// for(int i=1;i<=totnodes;i++)	cout<<opposite[i]<<":"<<opposite[opposite[i]]<<" ";cout<<endl;


// cout<<"seg_idx: ";for(int i=1;i<=n;i++)	cout<<seg_idx[i][1]<<":"<<seg_idx[i][2]<<" ";cout<<endl;
// cout<<"arr: ";for(int i=1;i<=2*n;i++)	cout<<arr[i].ff<<":"<<arr[i].ss.ff<<":"<<arr[i].ss.ss<<" ";cout<<endl;
// cout<<totnodes<<endl;


// cout<<possible(1e9)<<endl;;

    int ans = 0, lo = 1, hi = (int)1e9;
    while(lo <= hi){
    	int mid = (lo + hi)/2;
    	if(possible(mid)){
    		ans = max(ans, mid);
    		lo = mid+1;
    	}
    	else{
    		hi = mid-1;
    	}
    }

    printf("%d\n", ans);
    return 0;
}







Measured memory_bytes: 27456