// Slower C++ solution:
#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;

const int MAXZ=2*MAXN+2*MAXN;

const int MAXLG2N=15;

const int MAXM=4*MAXN+8*MAXN+8*MAXN*MAXLG2N;

typedef struct P { int x,id; } P;

bool operator<(const P &a,const P &b) { if(a.x!=b.x) return a.x<b.x; return a.id<b.id; }



int n;

int a[MAXN],b[MAXN];

P p[2*MAXN]; int pos[2*MAXN];



int key[2*MAXZ],minkey[2*MAXZ],nkey;

int stck[2*MAXZ],nstck;

bool onstck[2*MAXZ];

int comp[2*MAXZ],ncomp;



int nz;

int sz[8*MAXN];

int ghead[2*MAXZ],gto[MAXM],gnxt[MAXM],m;



void tarjan(int at,int D=0) {

	key[at]=minkey[at]=nkey++; stck[nstck++]=at,onstck[at]=true;

	for(int x=ghead[at];x!=-1;x=gnxt[x]) {

		int to=gto[x];

		//REP(dd,D) printf("  "); printf("%c%d->%c%d\n",at%2==0?'a':'b',at/2,to%2==0?'a':'b',to/2);

		if(key[to]==-1) {

			tarjan(to,D+1);

			minkey[at]=min(minkey[at],minkey[to]);

		} else if(onstck[to]) {

			minkey[at]=min(minkey[at],key[to]);

		}

	}

	if(minkey[at]==key[at]) {

		while(onstck[at]) { int to=stck[--nstck]; comp[to]=ncomp; onstck[to]=false; } ++ncomp;

	}

}



void addedge(int a,int b) { gnxt[m]=ghead[a]; ghead[a]=m; gto[m]=b; ++m; }

void sinit(int x,int l,int r) {

	if(l==r) { sz[x]=l; return; }

	int m=l+(r-l)/2;

	sinit(2*x+1,l,m); sinit(2*x+2,m+1,r);

	sz[x]=nz++; //printf("x=%d %d..%d=%d\n",x,l,r,sz[x]);

	addedge(2*sz[x]+1,2*sz[2*x+1]+1); addedge(2*sz[2*x+1]+0,2*sz[x]+0);

	addedge(2*sz[x]+1,2*sz[2*x+2]+1); addedge(2*sz[2*x+2]+0,2*sz[x]+0);

}

void sappend(int x,int l,int r,int L,int R,int I) {

	if(L<=l&&r<=R) { addedge(2*I+0,2*sz[x]+1); return; }

	int m=l+(r-l)/2;

	if(L<=m) sappend(2*x+1,l,m,L,R,I);

	if(m+1<=R) sappend(2*x+2,m+1,r,L,R,I);

}





bool ok(int d) {

	m=0; nz=2*n; memset(ghead,-1,sizeof(ghead));

	REP(i,2*n) addedge(2*i+0,2*pos[p[i].id^1]+1);

	REP(i,2*n) addedge(2*i+1,2*pos[p[i].id^1]+0);

	sinit(0,0,2*n-1); //int mx=0,mm=m;

	REP(i,2*n) {

		int l; { int L=-1,R=i; while(L+1<R) { int M=L+(R-L)/2; if(p[i].x-p[M].x<d) R=M; else L=M; } l=R; }

		int r; { int L=i,R=2*n; while(L+1<R) { int M=L+(R-L)/2; if(p[M].x-p[i].x<d) L=M; else R=M; } r=L; }

		if(l<=i-1) sappend(0,0,2*n-1,l,i-1,i);

		if(i+1<=r) sappend(0,0,2*n-1,i+1,r,i);

	}

	//printf("nz=%d m=%d (%d) mx=%d\n",nz,m,mm,mx);

	//REP(i,2*nz) { printf("%c%d:",i%2==0?'T':'F',i/2); REPSZ(j,e[i]) printf(" %c%d",e[i][j]%2==0?'T':'F',e[i][j]/2); puts(""); }

	nkey=0; nstck=0; ncomp=0; REP(i,2*nz) onstck[i]=false,key[i]=comp[i]=-1;

	REP(i,2*nz) if(key[i]==-1) tarjan(i);

	REP(i,nz) if(comp[2*i+0]==comp[2*i+1]) return false;

	return true;

}







int solve() {

	REP(i,n) p[2*i+0].x=a[i],p[2*i+0].id=2*i+0,p[2*i+1].x=b[i],p[2*i+1].id=2*i+1;  sort(p,p+2*n); REP(i,2*n) pos[p[i].id]=i;

	//REP(i,2*n) printf("%c%d ",p[i].id%2==0?'a':'b',p[i].id/2); puts("");

	//REP(i,2*n) printf("%d ",pos[i]); puts("");

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

	int l=0,h=1000000000;

	while(l+1<h) {

		int m=l+(h-l)/2;

		//printf("testing %d\n",m);

		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;

}


// Faster C++ solution for the same problem (measured speedup: 1.8786187182260703x):
#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;

}