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

class SAT2{
public:
	vector<vector<int> > v;
	vector<vector<int> > rev;
	int SIZE;
	void resize(int n){
		SIZE = n+2;
		v.assign(SIZE*2, vector<int>());
		rev = v;
	}
	int get_id(int id, bool xor_id){
		return id + (SIZE)*(int)(xor_id);
	}
	void add_edge(int a, bool xor_a,int b,bool xor_b){  //  a -->> b
		v[get_id(a,xor_a)].push_back(get_id(b,xor_b));
		rev[get_id(b, xor_b)].push_back(get_id(a, xor_a));
	}
	vector<bool> used;
	vector<pair<int, int> > vis;
	inline void dfs(int b,int &ord){
		used[b] = true;
		for (int i = 0; i < v[b].size(); i++){
			if (used[v[b][i]] == false){
				dfs(v[b][i], ord);
			}
		}
		vis.push_back(make_pair(ord,b));
		ord++;
	}
	vector<int> belong;
	inline void rdfs(int b,int &ord){
		used[b] = false;
		belong[b] = ord;
		for (int i = 0; i < rev[b].size(); i++){
			if (used[rev[b][i]] ){
				rdfs(rev[b][i],ord);
			}
		}
	}
	bool can(){
		int n = v.size();
		int ord = 0;
		used.assign(n, false);
		vis.clear();
		for (int i = 0; i < n; i++){
			if (used[i] == false){
				dfs(i,ord);
			}
		}
		sort(vis.begin(), vis.end(),greater<pair<int,int> > ());
		belong.resize(vis.size());
		for (int i = 0; i < n; i++){
			if (used[vis[i].second]){
				ord++;
				rdfs(vis[i].second, ord);
			}
		}
		for (int i = 0; i < SIZE; i++){
			if (belong[i] == belong[i + SIZE]){
				return false;
			}
		}
		return true;
	}
};

#define MAX 20002

int n;

vector<pair<int, int> > v;

vector<pair<long long int,int> > val;


int seg[MAX * 4];

int SZ;

int ids[MAX];

vector < pair<int, int> > ed;

inline void init(int b, int l, int r){
	if (l + 1 == r){
		ids[l] = b;
		SZ = max(SZ, b);
		return;
	}
	init(b * 2 + 1, l, (l + r) >> 1);
	init(b * 2 + 2, (l + r) >> 1, r);
	ed.push_back(make_pair(b, b * 2 + 1));
	ed.push_back(make_pair(b, b * 2 + 2));
}

inline void query(int b, int l, int r, int ll, int rr, int x,SAT2 &sat){
	if (rr <= l || r <= ll){
		return;
	}
	if (ll <= l&&r <= rr){
		sat.add_edge(x, true, b, false);
		sat.add_edge(b, true, x, false);
		return;
	}
	query(b * 2 + 1, l, (l + r) >> 1, ll, rr, x, sat);
	query(b * 2 + 2, (l + r) >> 1, r, ll, rr, x, sat);
}

int add[MAX * 2];


bool ok(long long int d){
	if (d == 0){
		return true;
	}
	SAT2 sat;
	sat.resize(SZ);
	int sz = ed.size();
	for (int i = 0; i < sz; i++){
		sat.add_edge(ed[i].first, 0, ed[i].second, 0);
		sat.add_edge(ed[i].second, 1, ed[i].first, 1);
	}
	for (int i = 0; i < n; i++){
		sat.add_edge(add[i],0, add[i + n],1);
		sat.add_edge(add[i], 1, add[i+n], 0);
		sat.add_edge(add[i + n], 1, add[i], 0);
		sat.add_edge(add[i + n], 0, add[i], 1);
	}
	for (int i = 0; i < val.size(); i++){
		int lef = i + 1;
		int rig = lower_bound(val.begin(), val.end(), make_pair(val[i].first + d,-1) )-val.begin();
		if (lef < rig){
			query(0, 0, n*2, lef, rig, ids[i], sat);
		}
		rig = i;
		lef = upper_bound(val.begin(), val.end(), make_pair(val[i].first - d,INT_MAX)) - val.begin();
		if (lef < rig){
			query(0, 0, n*2, lef, rig, ids[i], sat);
		}
	}
	if (sat.can()){
		return true;
	}
	return false;
}
int main(){
	cin >> n;
	init(0, 0, n * 2);
	for (int i = 0; i < n; i++){
		int x, y;
		scanf("%d%d", &x, &y);
		v.push_back(make_pair(x, y));
		val.push_back(make_pair(x,i) );
		val.push_back(make_pair(y,i+n) );
	}
	sort(val.begin(), val.end());
	for (int i = 0; i < val.size(); i++){
		add[val[i].second] = ids[i];
	}
	long long int mint = 0;
	long long int maxt = 1000000000;
	while (mint + 1LL < maxt){
		long long int mid = (mint + maxt) >> 1LL;
		if (ok(mid)){
			mint = mid;
		}
		else{
			maxt = mid - 1;
		}
	}
	if (mint != maxt){
		if (ok(maxt)){
			mint = maxt;
		}
		else{
			maxt = mint;
		}
	}
	printf("%lld\n", maxt);
	return 0;
}

Measured memory_bytes: 33944