// Original C++ solution (slower):
#include <cstdio>

#include <algorithm>

#include <vector>

#include <cstring>

#include <cstdlib>

#include <cassert>

using namespace std;

typedef vector<int> vec;

typedef vector<vec> mat;



int N,M;

const int MAX_N = 20010;

const int MAX_M = 160010;



struct pt{

	int x,id;

	pt(){}

	pt(int x_,int id_):x(x_),id(id_){}

	bool operator<(const pt& r)const{

		return x<r.x;

	}

}a[MAX_N];



int pos[MAX_N];

int sz;



mat path,rpath;



bool vsi[MAX_M];

int ID[MAX_M];

vec st;



void add_edge(int x,int y){

	if(x<=0||x==M||x>=M*2){

		puts("-1");

		exit(0);

	}

	if(y<=0||y==M||y>=M*2){

		puts("-1");

		exit(0);

	}

	path[x].push_back(y);

	rpath[y].push_back(x);

}



void update(int x){

	x+=sz;

	while(x>1){

		add_edge(x/2,x);

		add_edge(x/2+M,x+M);

		x>>=1;

	}

}



void update(int x,int L,int R){

	x+=sz,L+=sz,R+=sz;

	while(L<R){

		if(L%2==1)add_edge(x,(L++)+M);

		if(R%2==0)add_edge(x,(R--)+M);

		L>>=1,R>>=1;

	}

	if(L==R)add_edge(x,L+M);

}



void init(int len){

	st.clear();

	memset(vsi,0,sizeof(vsi));

	memset(ID,-1,sizeof(ID));

	path.assign(M*2,vec());

	rpath.assign(M*2,vec());



	for(int i=0;i<N;i+=2){

		add_edge(pos[i],pos[i+1]+M);

		add_edge(pos[i]+M,pos[i+1]);

		add_edge(pos[i+1],pos[i]+M);

		add_edge(pos[i+1]+M,pos[i]);

	}

	for(int i=0;i<N;i++){

		update(i);

	}



	int L=0,R=0;

	for(int i=0;i<N;i++){

		while(L<i&&a[i].x-a[L].x>=len)L++;

		while(R<N&&a[R].x-a[i].x<len)R++;

		update(i,L,i-1);

		update(i,i+1,R-1);

	}

}



void dfs(int v){

	vsi[v]=1;

	for(auto& u:path[v]){

		if(vsi[u])continue;

		dfs(u);

	}

	st.push_back(v);

}



void rdfs(int v,int c){

	ID[v]=c;

	for(auto& u:rpath[v]){

		if(ID[u]>=0)continue;

		rdfs(u,c);

	}

}



bool chk(int len){

	init(len);

	vsi[0]=vsi[M]=1;

	for(int i=0;i<M*2;i++){

		if(vsi[i])continue;

		dfs(i);

	}

	int v,c=0;

	while(!st.empty()){

		v=st.back();st.pop_back();

		if(ID[v]>=0)continue;

		rdfs(v,c++);

	}

	for(int i=sz;i<N+sz;i++){

		if(ID[i]==ID[i+M])return 0;

	}

	return 1;

}



int main(){



	scanf("%d",&N);

	N<<=1;

	for(sz=1;sz<N;sz<<=1);

	M=N+sz;



	for(int i=0,x;i<N;i++){

		scanf("%d",&x);

		a[i]=pt(x,i);

	}



	sort(a,a+N);

	for(int i=0;i<N;i++){

		pos[a[i].id]=i+sz;

	}



	int lo=0,hi=1e9,mid;

	while(lo+1<hi){

		mid=(lo+hi)/2;

		if(chk(mid))lo=mid;

		else hi=mid;

	}

	printf("%d\n",lo);



	return 0;

}


// Optimized solution to the same problem (faster):
#include <cstdio>

#include <algorithm>

#include <vector>

#include <cstring>

#include <cstdlib>

#include <cassert>

using namespace std;

typedef vector<int> vec;

typedef vector<vec> mat;



int N,M;

const int MAX_N = 20010;

const int MAX_M = 110000;



struct pt{

	int x,id;

	pt(){}

	pt(int x_,int id_):x(x_),id(id_){}

	bool operator<(const pt& r)const{

		return x<r.x;

	}

}a[MAX_N];



int pos[MAX_N];

int sz;



mat path,rpath;



bool vsi[MAX_M];

int ID[MAX_M];

vec st;



void add_edge(int x,int y){

	path[x].push_back(y);

	rpath[y].push_back(x);

}



void update(int x){

	x+=sz;

	while(x>1){

		add_edge(x/2,x);

		add_edge(x/2+M,x+M);

		x>>=1;

	}

}



void update(int x,int L,int R){

	x+=sz,L+=sz,R+=sz;

	while(L<R){

		if(L%2==1)add_edge(x,(L++)+M);

		if(R%2==0)add_edge(x,(R--)+M);

		L>>=1,R>>=1;

	}

	if(L==R)add_edge(x,L+M);

}



void init(int len){

	st.clear();

	memset(vsi,0,sizeof(vsi));

	memset(ID,-1,sizeof(ID));

	path.assign(M*2,vec());

	rpath.assign(M*2,vec());



	for(int i=0;i<N;i+=2){

		add_edge(pos[i],pos[i+1]+M);

		add_edge(pos[i]+M,pos[i+1]);

		add_edge(pos[i+1],pos[i]+M);

		add_edge(pos[i+1]+M,pos[i]);

	}

	for(int i=0;i<N;i++){

		update(i);

	}



	int L=0,R=0;

	for(int i=0;i<N;i++){

		while(L<i&&a[i].x-a[L].x>=len)L++;

		while(R<N&&a[R].x-a[i].x<len)R++;

		update(i,L,i-1);

		update(i,i+1,R-1);

	}

}



void dfs(int v){

	vsi[v]=1;

	for(auto& u:path[v]){

		if(vsi[u])continue;

		dfs(u);

	}

	st.push_back(v);

}



void rdfs(int v,int c){

	ID[v]=c;

	for(auto& u:rpath[v]){

		if(ID[u]>=0)continue;

		rdfs(u,c);

	}

}



bool chk(int len){

	init(len);

	vsi[0]=vsi[M]=1;

	for(int i=0;i<M*2;i++){

		if(vsi[i])continue;

		dfs(i);

	}

	int v,c=0;

	while(!st.empty()){

		v=st.back();st.pop_back();

		if(ID[v]>=0)continue;

		rdfs(v,c++);

	}

	for(int i=sz;i<N+sz;i++){

		if(ID[i]==ID[i+M])return 0;

	}

	return 1;

}



int main(){



	scanf("%d",&N);

	N<<=1;

	for(sz=1;sz<N;sz<<=1);

	M=N+sz;



	for(int i=0,x;i<N;i++){

		scanf("%d",&x);

		a[i]=pt(x,i);

	}



	sort(a,a+N);

	for(int i=0;i<N;i++){

		pos[a[i].id]=i+sz;

	}



	int lo=0,hi=1e9,mid;

	while(lo+1<hi){

		mid=(lo+hi)/2;

		if(chk(mid))lo=mid;

		else hi=mid;

	}

	printf("%d\n",lo);



	return 0;

}


// Fastest known solution for this problem: