#include<bits/stdc++.h>
using namespace std;
const int N=100005,M=10000005;
int id1[N],id2[N],ne[M],fi[N],zz[M],low[N],dfn[N],l,from[N],tot,flag[N],Stack[N],x[N],y[N],f1[N],f2[N],n,cnt,num;
void jb(int x,int y){
	ne[++tot]=fi[x];
	fi[x]=tot;
	zz[tot]=y;
}
void Tarjan(int x){
	low[x]=dfn[x]=++l;
	Stack[++tot]=x;
	flag[x]=1;
	for (int i=fi[x];i;i=ne[i]){
		if (!dfn[zz[i]])Tarjan(zz[i]),low[x]=min(low[x],low[zz[i]]);
		else if (flag[zz[i]])low[x]=min(low[x],dfn[zz[i]]);
	}
	if (low[x]==dfn[x]){
		num++;
		while (Stack[tot]!=x){
			from[Stack[tot]]=num;
			flag[Stack[tot]]=0;
			tot--;
		}
		from[Stack[tot]]=num;
		flag[Stack[tot]]=0;
		tot--;
	}
}
struct TTree{
	int Flag;
	struct Tree{
		int l,r,id;
	}T[N];
	void build(int x,int l,int r){
		T[x].l=l;T[x].r=r;
		if (l==r){
			if (Flag)T[x].id=f1[l]+n;
			else T[x].id=f2[l];
			return;
		}
		T[x].id=++cnt;
		int mid=(l+r)/2;
		build(x*2,l,mid);
		build(x*2+1,mid+1,r);
	}
	void solve(int x){
		if (T[x].l==T[x].r)return;
		jb(T[x].id,T[x*2].id);jb(T[x].id,T[x*2+1].id);
		solve(x*2);solve(x*2+1);
	}
	void insert(int x,int l,int r,int z){
		if (T[x].l>r||l>T[x].r)return;
		if (T[x].l>=l&&T[x].r<=r){
			jb(z,T[x].id);
			return;
		}
		insert(x*2,l,r,z);
		insert(x*2+1,l,r,z);
	}
}T[2];
int cmp1(int a,int b){
	return x[a]<x[b];
}
int cmp2(int a,int b){
	return y[a]<y[b];
}
int check(int dis){
	memset(fi,0,sizeof fi);
	memset(dfn,0,sizeof dfn);
	tot=0;
	T[0].solve(1);T[1].solve(1);
	for (int i=2;i<=n;i++){
		int l=1,r=i;
		while (l<r){
			int mid=(l+r)/2;
			if (x[f1[mid]]<=x[f1[i]]-dis)l=mid+1;
			else r=mid;
		}
		T[0].insert(1,l,i-1,f1[i]);
	}
	for (int i=1;i<n;i++){
		int l=i,r=n;
		while (l<r){
			int mid=(l+r+1)/2;
			if (x[f1[mid]]>=x[f1[i]]+dis)r=mid-1;
			else l=mid;
		}
		T[0].insert(1,i+1,l,f1[i]);
	}
	for (int i=2;i<=n;i++){
		int l=1,r=i;
		while (l<r){
			int mid=(l+r)/2;
			if (y[f2[mid]]<=y[f2[i]]-dis)l=mid+1;
			else r=mid;
		}
		T[1].insert(1,l,i-1,f2[i]+n);
	}
	for (int i=1;i<n;i++){
		int l=i,r=n;
		while (l<r){
			int mid=(l+r+1)/2;
			if (y[f2[mid]]>=y[f2[i]]+dis)r=mid-1;
			else l=mid;
		}
		T[1].insert(1,i+1,l,f2[i]+n);
	}
	for (int i=1;i<=n;i++){
		int l1=1,r1=n;
		if (y[f2[n]]<=x[f1[i]]-dis)l1=n+1;
		while (l1<r1){
			int mid=(l1+r1)/2;
			if (y[f2[mid]]>x[f1[i]]-dis)r1=mid;
			else l1=mid+1;
		}
		int l2=1,r2=n;
		if (y[f2[1]]>=x[f1[i]]+dis)l2=r2=0;
		while (l2<r2){
			int mid=(l2+r2+1)/2;
			if (y[f2[mid]]<x[f1[i]]+dis)l2=mid;
			else r2=mid-1;
		}
		if (l1>l2)continue;
		if (id2[f1[i]]>=l1&&id2[f1[i]]<=l2){
			T[1].insert(1,l1,id2[f1[i]]-1,f1[i]);
			T[1].insert(1,id2[f1[i]]+1,l2,f1[i]);
		}
		else T[1].insert(1,l1,l2,f1[i]);
	}
	for (int i=1;i<=n;i++){
		int l1=1,r1=n;
		if (x[f1[n]]<=y[f2[i]]-dis)r1=l1=n+1;
		while (l1<r1){
			int mid=(l1+r1)/2;
			if (x[f1[mid]]>y[f2[i]]-dis)r1=mid;
			else l1=mid+1;
		}
		int l2=1,r2=n;
		if (x[f1[1]]>=y[f2[i]]+dis)l2=r2=0;
		while (l2<r2){
			int mid=(l2+r2+1)/2;
			if (x[f1[mid]]<y[f2[i]]+dis)l2=mid;
			else r2=mid-1;
		}
		if (l1>l2)continue;
		if (id1[f2[i]]>=l1&&id1[f2[i]]<=l2){
			T[0].insert(1,l1,id1[f2[i]]-1,f2[i]+n);
			T[0].insert(1,id1[f2[i]]+1,l2,f2[i]+n);
		}
		else T[0].insert(1,l1,l2,f2[i]+n);
	}
	tot=l=num=0;
	for (int i=1;i<=cnt;i++)
		if (!dfn[i])Tarjan(i);
	for (int i=1;i<=n;i++)
		if (from[i]==from[n+i])return 0;
	return 1;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);
	for (int i=1;i<=n;i++)f1[i]=i,f2[i]=i;
	sort(f1+1,f1+n+1,cmp1);
	sort(f2+1,f2+n+1,cmp2);
	for (int i=1;i<=n;i++)id1[f1[i]]=i,id2[f2[i]]=i;
	cnt=2*n;
	T[0].Flag=1;
	T[0].build(1,1,n);
	T[1].build(1,1,n);
	int l=0,r=1e9;
	while (l<r){
		int mid=(l+r+1)/2;
		if (check(mid))l=mid;
		else r=mid-1;
	}
	printf("%d\n",l);
	return 0;
}



Measured memory_bytes: 18688