//2017-11-3
//miaomiao
//
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

#define pb push_back
#define For(i, a, b) for(int i = (a); i <= (int)(b); ++i)

#define N (40000+5)

struct node{
	int id, v;
	bool operator <(const node &rhs)const{return v < rhs.v;}
}num[N];

int n, nn, hn, an, ql, qr;
vector<int> G[N<<2], g[N<<2], dif[N<<2];

inline void Add(int u, int v){
//	printf("%d -> %d\n", u, v);
	G[u].pb(v);
}

#define lc (o<<1)
#define rc (o<<1|1)
#define mid ((L+R)>>1)

namespace Seg_tree{
	int h[N<<2];
	
	void Build(int o, int L, int R){
		if(L == R){
			hn = max(hn, o); Add(nn+o, num[L].id^1);
			return;
		}

		Add(o+nn, lc+nn); Add(o+nn, rc+nn);
		Build(lc, L, mid); Build(rc, mid+1, R);
	}

	void Modify(int o, int L, int R, int me){
		if(ql <= L && qr >= R){
			Add(me, o+nn); return;
		}

		if(ql <= mid) Modify(lc, L, mid, me);
		if(qr > mid) Modify(rc, mid+1, R, me);
	}
};

#undef lc
#undef rc
#undef mid

using namespace Seg_tree;

int clk, sn, tp, low[N<<2], dfn[N<<2], sid[N<<2], st[N<<2];
int dig[N<<2], val[N<<2];

void AddEdges(int mxd){
	int l = 2, r = 0;

	//For(i, 2, nn) printf("%d ", num[i].v); puts("");
	For(i, 2, nn){
		while(num[i].v-num[l].v >= mxd) ++l;
		while(r < nn && num[r+1].v-num[i].v < mxd) ++r;
	
	//	printf("num[%d].id = %d\n", i, num[i].id);
	//	printf("i = %d l = %d r = %d\n", i, l, r);
		if(l < i) ql = l, qr = i-1, Modify(1, 1, nn, num[i].id);
		if(r > i) ql = i+1, qr = r, Modify(1, 1, nn, num[i].id);
	}
}

#define v G[now][i]

void Targan(int now){
	low[now] = dfn[now] = ++clk;
	st[++tp] = now;

	For(i, 0, G[now].size()-1)
		if(!dfn[v]){
			Targan(v); low[now] = min(low[now], low[v]);
		}else if(!sid[v]) low[now] = min(low[now], dfn[v]);
	
	if(low[now] == dfn[now]){
		sid[now] = ++sn;
		while(st[tp] ^ now) sid[st[tp--]] = sn;
		--tp;
	}
}

#undef v

bool Topsort(){
	queue<int> q;
	For(i, 1, sn) if(!dig[i]) q.push(i);
	
	int now, v;

	while(!q.empty()){
		now = q.front(); q.pop();
		
		if(val[now] == -1) val[now] = 1;

		if(val[now] == 1)
			For(i, 0, dif[now].size()-1) if(val[dif[now][i]] == 1){
				val[now] = 0; break;
			}

		if(!val[now]) For(i, 0, dif[now].size()-1)
				if(val[dif[now][i]] == 0) return false;
		
		For(i, 0, g[now].size()-1){
			--dig[v = g[now][i]];
			
			if(!val[now] && val[v] == 1) return false;
			if(!val[now]) val[v] = 0;
			
			if(!dig[v]) q.push(v);
		}
	}

	return true;
}

bool Check(int mxd){
	For(i, 0, nn+hn) G[i].clear();
	hn = 0; Build(1, 1, nn);
	
	AddEdges(mxd); an = nn + hn;
	
	sn = clk = tp = 0;
	For(i, 0, an) dfn[i] = low[i] = st[i] = sid[i] = 0;
	For(i, 2, an) if(!dfn[i]) Targan(i);
	
	int u, v;

	For(i, 1, sn) g[i].clear(), dif[i].clear(), dig[i] = 0, val[i] = -1;
	for(int i = 2; i <= nn; i += 2){
		u = sid[i], v = sid[i^1]; 
		if(u == v) return false;
		dif[u].pb(v); dif[v].pb(u);
	}

	For(i, 2, an) For(j, 0, G[i].size()-1)
		if(sid[i]^sid[G[i][j]]) g[sid[G[i][j]]].pb(sid[i]), ++dig[sid[i]];
	
//	printf("mxd = %d Here = true\n", mxd);
	return Topsort();
}

int main(){
	int x, y, L = 0, R = 0, mid;

	scanf("%d", &n);

	nn = 1;
	For(i, 1, n){
		scanf("%d%d", &x, &y);
		++nn; num[nn] = (node){nn, x};
		++nn; num[nn] = (node){nn, y};
		R = max(R, max(x, y));
	}
	
	sort(num+1, num+nn+1);

	while(L < R){
		mid = (L+R+1) >> 1;
		
	//	printf("L = %d R = %d mid = %d\n", L, R, mid);
		if(Check(mid)) L = mid;
		else R = mid - 1;
	//	puts("=============================");
	}

	//printf("Check(%d) = %d\n", L, Check(L));
	printf("%d\n", L);

	return 0;
}

Measured memory_bytes: 30804