// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
#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 P { int x,idx; } R;

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



int n;

int a[MAXN],b[MAXN];

P p[2*MAXN];

int pos[2*MAXN];

int lb[2*MAXN],ub[2*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) { 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+1;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 r) {

	set<int>::iterator it=lft.lower_bound(l);

	return it==lft.end()||*it>r?-1:*it;

}

int getedge(int at) {

	int l=lb[pos[at]],r=ub[pos[at]],a=pos[at],b=pos[other(at)]; if(a>b) swap(a,b);

	int ret=-1;

	if(ret==-1&&l<=a&&a<=r) ret=getedge(l,a-1);

	if(ret==-1&&l<=a&&b<=r) ret=getedge(a+1,b-1);

	if(ret==-1&&l<=b&&b<=r) ret=getedge(b+1,r);

	if(ret==-1&&a<l&&l<=b&&b<=r) ret=getedge(l,b-1);

	if(ret==-1&&b>r&&l<=a&&a<=r) ret=getedge(a+1,r);

	if(ret==-1&&(a<l||a>r)&&(b<l||b>r)) ret=getedge(l,r);

	return ret==-1?-1:other(p[ret].idx);

}

void update(int &ret,int l,int r) {

	if(l<=r) ret=min(ret,sget(l,r));

}

void update(int &ret,int at) {

	int l=lb[pos[at]],r=ub[pos[at]],a=pos[at],b=pos[other(at)]; if(a>b) swap(a,b);

	if(l<=a&&a<=r) update(ret,l,a-1);

	if(l<=a&&b<=r) update(ret,a+1,b-1);

	if(l<=b&&b<=r) update(ret,b+1,r);

	if(a<l&&l<=b&&b<=r) update(ret,l,b-1);

	if(b>r&&l<=a&&a<=r) update(ret,a+1,r);

	if((a<l||a>r)&&(b<l||b>r)) update(ret,l,r);

}



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

	key[at]=minkey[at]=nkey++; stck[nstck++]=at; sset(pos[other(at)],key[at]); lft.erase(pos[other(at)]);

	//REP(i,dep) printf(" "); printf("tarjan(%d%c)\n",at%n+1,at<n?'A':'B');

	while(true) {

		int to=getedge(at);

		if(to==-1) break;

		tarjan(to,dep+1);

		if(minkey[to]<minkey[at]) minkey[at]=minkey[to];

	}

	update(minkey[at],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,2*n) { int l=-1,h=2*n; while(l+1<h) { int m=l+(h-l)/2; if(p[m].x>p[i].x-D) h=m; else l=m; } lb[i]=h; } //p[?].x>p[i].x-D

	REP(i,2*n) { int l=-1,h=2*n; while(l+1<h) { int m=l+(h-l)/2; if(p[m].x<p[i].x+D) l=m; else h=m; } ub[i]=l; } //p[?].x<p[i].x+D

	//REP(i,2*n) printf("%d=%d: %d..%d\n",i,p[i].x,lb[i],ub[i]);



	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) p[i].x=a[i],p[i].idx=i,p[i+n].x=b[i],p[i+n].idx=i+n; sort(p,p+2*n);

	REP(i,2*n) pos[p[i].idx]=i;



	//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;

		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 main() {

	run();

	return 0;

}


// Fastest known solution for this problem: