#include <algorithm>  
#include <iostream>  
#include <sstream>  
#include <string>  
#include <cstring>
#include <vector>  
#include <queue>  
#include <set>  
#include <map>  
#include <cstdio>  
#include <cstdlib>  
#include <cctype>  
#include <cmath>  
#include <list>  
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;  

#define PB push_back  
#define MP make_pair  
#define SZ(v) ((int)(v).size())  
#define FOR(i,a,b) for(int i=(a);i<(b);++i)  
#define REP(i,n) FOR(i,0,n)  
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)  
#define REPE(i,n) FORE(i,0,n)  
#define FORSZ(i,a,v) FOR(i,a,SZ(v))  
#define REPSZ(i,v) REP(i,SZ(v))  
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN=10000;
typedef struct R { int x,idx; } R;
bool operator<(const R &a,const R &b) { if(a.x!=b.x) return a.x<b.x; return a.idx<b.idx; }

int n;
int a[MAXN],b[MAXN];
R aa[MAXN],bb[MAXN];
int pos[2*MAXN];
int ala[MAXN],aha[MAXN];
int alb[MAXN],ahb[MAXN];
int bla[MAXN],bha[MAXN];
int blb[MAXN],bhb[MAXN];

int key[2*MAXN],minkey[2*MAXN],nkey;
int comp[2*MAXN],ncomp;
int stck[2*MAXN],nstck;
set<int> lft;
int sval[4*MAXN];
void sinit() { FOR(i,1,4*n) sval[i]=INT_MAX; }
void sset(int idx,int val) { /*printf("[setting %d to %d]\n",idx,val);*/ idx+=2*n; sval[idx]=val; for(idx>>=1;idx>0;idx>>=1) sval[idx]=min(sval[2*idx],sval[2*idx+1]); }
int sget(int lidx,int ridx) { int ret=INT_MAX; for(lidx+=2*n,ridx+=2*n;lidx<ridx;lidx>>=1,ridx>>=1) { if(lidx&1) ret=min(ret,sval[lidx++]); if(ridx&1) ret=min(ret,sval[--ridx]); } return ret; }

int other(int id) { return id==-1?-1:id<n?id+n:id-n; }
int getedge(int l,int h) {
	set<int>::iterator it=lft.lower_bound(l);
	return it==lft.end()||*it>h?-1:*it;
}
int getedge(int l,int m,int h) {
	if(m<l||m>h) return getedge(l,h);
	int ret=-1;
	if(ret==-1) ret=getedge(l,m-1);
	if(ret==-1) ret=getedge(m+1,h);
	return ret;
}
int getedge(int at) {
	int ret=-1;
	if(at<n) {
		if(ret==-1) ret=getedge(ala[at],pos[at],aha[at]);
		if(ret==-1) ret=getedge(alb[at],pos[at+n],ahb[at]);
	} else {
		if(ret==-1) ret=getedge(bla[at-n],pos[at-n],bha[at-n]);
		if(ret==-1) ret=getedge(blb[at-n],pos[at],bhb[at-n]);
	}
	if(ret==-1) return ret;
	ret=ret<n?aa[ret].idx:bb[ret-n].idx+n;
	return other(ret);
}
void update(int &ret,int l,int h) {
	if(l<=h) {
		int cur=sget(l,h+1);
		//printf("[updating %d..%d -> %d]\n",l,h,cur);
		ret=min(ret,cur);
	}
}
void update(int &ret,int l,int m,int h) {
	if(l<=m&&m<=h) update(ret,l,m-1),update(ret,m+1,h); else update(ret,l,h);
}
void update(int &ret,int at) {
	if(at<n) {
		update(ret,ala[at],pos[at],aha[at]);
		update(ret,alb[at],pos[at+n],ahb[at]);
	} else {
		update(ret,bla[at-n],pos[at-n],bha[at-n]);
		update(ret,blb[at-n],pos[at],bhb[at-n]);
	}
}
//int tmp=0;
void tarjan(int at,int dp=0) {
	key[at]=minkey[at]=nkey++; stck[nstck++]=at; sset(pos[other(at)],key[at]); lft.erase(pos[other(at)]);
	//REP(i,dp) printf("  "); printf("%d%c=%d (%d,%d)\n",at%n+1,at<n?'A':'B',key[at],pos[at],pos[other(at)]); if(++tmp>100) exit(0);
	while(true) {
		int to=getedge(at);
		if(to==-1) break;
		tarjan(to,dp+1);
		if(minkey[to]<minkey[at]) minkey[at]=minkey[to];
	}
	update(minkey[at],at);
	//REP(i,dp) printf("  "); printf("%d%c->%d\n",at%n+1,at<n?'A':'B',minkey[at]);
	if(minkey[at]==key[at]) {
		while(comp[at]==-1) { int to=stck[--nstck]; sset(pos[other(to)],INT_MAX); comp[to]=ncomp; } ++ncomp;
	}
}

bool ok(int D) {
	REP(i,n) { int l=-1,h=n; while(l+1<h) { int m=l+(h-l)/2; if(aa[m].x>a[i]-D) h=m; else l=m; } ala[i]=h;   } // aa[?].x>a[i]-D
	REP(i,n) { int l=-1,h=n; while(l+1<h) { int m=l+(h-l)/2; if(bb[m].x>a[i]-D) h=m; else l=m; } alb[i]=h+n; } // bb[?].x>a[i]-D
	REP(i,n) { int l=-1,h=n; while(l+1<h) { int m=l+(h-l)/2; if(aa[m].x>b[i]-D) h=m; else l=m; } bla[i]=h;   } // aa[?].x>b[i]-D
	REP(i,n) { int l=-1,h=n; while(l+1<h) { int m=l+(h-l)/2; if(bb[m].x>b[i]-D) h=m; else l=m; } blb[i]=h+n; } // bb[?].x>b[i]-D
	REP(i,n) { int l=-1,h=n; while(l+1<h) { int m=l+(h-l)/2; if(aa[m].x<a[i]+D) l=m; else h=m; } aha[i]=l;   } // aa[?].x<a[i]+D
	REP(i,n) { int l=-1,h=n; while(l+1<h) { int m=l+(h-l)/2; if(bb[m].x<a[i]+D) l=m; else h=m; } ahb[i]=l+n; } // bb[?].x<a[i]+D
	REP(i,n) { int l=-1,h=n; while(l+1<h) { int m=l+(h-l)/2; if(aa[m].x<b[i]+D) l=m; else h=m; } bha[i]=l;   } // aa[?].x<b[i]+D
	REP(i,n) { int l=-1,h=n; while(l+1<h) { int m=l+(h-l)/2; if(bb[m].x<b[i]+D) l=m; else h=m; } bhb[i]=l+n; } // bb[?].x<b[i]+D
	REP(i,n) pos[aa[i].idx]=i; REP(i,n) pos[bb[i].idx+n]=i+n;
	//printf("aa:"); REP(i,n) printf(" %d",aa[i].x); puts("");
	//printf("bb:"); REP(i,n) printf(" %d",bb[i].x); puts("");
	//REP(i,n) printf("%d %d: (%d..%d) (%d..%d) | (%d..%d) (%d..%d)\n",a[i],b[i],ala[i],aha[i],alb[i]-n,ahb[i]-n,bla[i],bha[i],blb[i]-n,bhb[i]-n);

	sinit();
	lft.clear(); REP(i,2*n) lft.insert(i);
	REP(i,2*n) key[i]=comp[i]=-1; nkey=ncomp=nstck=0;
	REP(i,2*n) if(key[i]==-1) tarjan(i);
	REP(i,n) if(comp[i]==comp[i+n]) return false;
	return true;
}

int solve() {
	REP(i,n) aa[i].x=a[i],aa[i].idx=i; sort(aa,aa+n);
	REP(i,n) bb[i].x=b[i],bb[i].idx=i; sort(bb,bb+n);

	//int tst=4; printf("ok(%d)=%d\n",tst,ok(tst)?1:0); exit(0);

	int l=0,h=1000000001;
	while(l+1<h) {
		int m=l+(h-l)/2;
		//printf("%d -> %d\n",m,ok(m)?1:0);
		if(ok(m)) l=m; else h=m;
	}
	return l;
}


void run() {
	scanf("%d",&n); REP(i,n) scanf("%d%d",&a[i],&b[i]);
	printf("%d\n",solve());
}

int myrand() { return (rand()%10000)*10000+rand()%10000; }
void test() {
	n=MAXN; REP(i,n) a[i]=myrand(),b[i]=myrand();
	printf("%d\n",solve());
}

int main() {
	run();
	//test();
	return 0;
}


Measured memory_bytes: 3200