#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <sstream>
#include <functional>
#include <map>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <list>
#include <numeric>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> P;
const double PI = 3.14159265358979323846;
const double EPS = 1e-12;
const ll INF = 1LL<<29;
const ll mod = 1e9+7;
#define rep(i,n) for(int (i)=0;(i)<(ll)(n);++(i))
#define repd(i,n,d) for(ll (i)=0;(i)<(ll)(n);(i)+=(d))
#define all(v) (v).begin(), (v).end()
#define pb(x) push_back(x)
#define mp(x,y) make_pair((x),(y))
#define mset(m,v) memset((m),(v),sizeof(m))
#define chmin(x,y) (x=min(x,y))
#define chmax(x,y) (x=max(x,y))
#define fst first
#define snd second
#define UNIQUE(x) (x).erase(unique(all(x)),(x).end())
template<class T> ostream &operator<<(ostream &os, const vector<T> &v){int n=v.size();rep(i,n)os<<v[i]<<(i==n-1?"":" ");return os;}

#define VAR(x) ((x)<<1)
#define NOT(x) ((x)^1)

#define N 10010
int x[N], y[N];
vector<P> v;
int n, n2;
bool used[16*N];

void visit(int v, vector<vector<int>> &g, vector<int> &ord, vector<int> &num, int k){
	if(num[v]>=0) return;
	num[v] = k;
	rep(i, g[v].size()){
		visit(g[v][i], g, ord, num, k);
	}
	ord.pb(v);
}

bool twoSAT(int m, vector<P> &cs){
	int n = m*2;
	vector<vector<int>> g(n), h(n);
	rep(i, cs.size()){
		int u = cs[i].fst, v = cs[i].snd;
		g[NOT(u)].pb(v);
		g[NOT(v)].pb(u);
		h[v].pb(NOT(u));
		h[u].pb(NOT(v));
	}
	vector<int> num(n, -1), ord, dro;
	rep(i, n) visit(i, g, ord, num, i);
	reverse(all(ord));
	fill(all(num), -1);
	rep(i, n) visit(ord[i], h, dro, num, i);
	rep(i, n) if(num[i]==num[NOT(i)]) return false;
	return true;
}

int vark(int k){
	return k>=n2-1?v[k-n2+1].snd:VAR(k);
}

void query2(int k, vector<P> &cs){
	if(k>=n2-1||used[k]) return;
	used[k] = true;
	query2(k*2+1, cs);
	query2(k*2+2, cs);
	cs.pb(P(NOT(vark(k*2+1)), vark(k)));
	cs.pb(P(NOT(vark(k*2+2)), vark(k)));
	cs.pb(P(NOT(vark(k*2+1)), NOT(vark(k*2+2))));
}

vector<int> query(int a, int b, int k, int l, int r, vector<P> &cs){
	if(r<=a||b<=l) return vector<int>();
	if(a<=l&&r<=b){
		query2(k, cs);
		return vector<int>(1, vark(k));
	}
	vector<int> res, res2;
	res = query(a, b, k*2+1, l, (l+r)/2, cs);
	res2 = query(a, b, k*2+2, (l+r)/2, r, cs);
	if(res.size()<res2.size()) res.swap(res2);
	res.insert(res.end(), all(res2));
	return res;
}

bool solve(int d){
	int l = 0, r = 0;
	mset(used, 0);
	vector<P> cs;
	//cerr<<"start "<<d<<endl;
	while(r<2*n){
		while(r<2*n && v[r].fst-v[l].fst<d) r++;
		//cerr<<l<<" "<<r<<endl;
		auto s = query(l, r, 0, 0, n2, cs);
		rep(i, s.size()) rep(j, i) cs.pb(P(NOT(s[i]), NOT(s[j])));
		while(r<2*n && v[r].fst-v[l].fst>=d) l++;
	}
	sort(all(cs)); UNIQUE(cs);
	//cerr<<"d = "<<d<<endl;
	//cerr<<cs.size()<<endl;
	/*rep(i, cs.size()){
		int a = cs[i].fst, b = cs[i].snd;
		int sa = a&1, sb = b&1;
		a>>=1; b>>=1;
		if(sa)a*=-1; if(sb)b*=-1;
		cout<<a<<" "<<b<<endl;
	}*/
	//vector<P> cs2(cs.begin(), cs.end());
	return twoSAT(2*n2-1, cs);
}

int main(){
	cin>>n;
	n2 = 1;
	while(n2<n*2) n2<<=1;
	rep(i, n){
		cin>>x[i]>>y[i];
		int var = VAR(i+n2-1);
		v.pb(P(x[i], var));
		v.pb(P(y[i], NOT(var)));
	}
	sort(all(v));
	int lb = 0, ub = 1e9+10;
	while(ub-lb>1){
		int md = (lb+ub)/2;
		(solve(md)?lb:ub) = md;
	}
	cout<<lb<<endl;
	return 0;
}


Measured memory_bytes: 35108