#include <stdio.h>
#include <algorithm>

using namespace std;

const int maxn = 32000;
struct node {
	int v;
	node *next;
} pooln[maxn*30*2] , *g[maxn*20];
struct tree {
	int l , r , i;
	tree *ll , *rr;
} poolt[maxn*20] , *t;
int topn , topt;
int n;
int x[maxn] , y[maxn];
int mix[maxn*2] , pos[maxn*2] , getx[maxn] , gety[maxn];
int dfn[maxn*20] , low[maxn*20];
int stack[maxn*20] , ins[maxn*20] , tops;
int col[maxn*20] , color;
int index;
bool cmp ( int x1 , int x2 ) {
	int y1 , y2;
	if ( x1 < 0 ) y1 = y[-x1];
	else y1 = x[x1];
	if ( x2 < 0 ) y2 = y[-x2];
	else y2 = x[x2];
	return y1 < y2;
}
void clear () {
	int i;
	for ( i = 1 ; i <= topn ; i++ ) {
		pooln[i].v = 0;
		pooln[i].next = NULL;
	}
	for ( i = 1 ; i <= 2 * n + topt ; i++ ) {
		g[i] = NULL;
		dfn[i] = low[i] = 0;
		col[i] = 0;
		ins[i] = 0;
	}
	for ( i = 1 ; i <= topt ; i++ ) {
		poolt[i].l = poolt[i].r = poolt[i].i = 0;
		poolt[i].ll = poolt[i].rr = NULL;
	}
	tops = 0;
	color = index = 0;
	topt = 0; topn = 0;
	t = NULL;
}
void add ( int u , int v ) {
	node *tmp = &pooln[++topn];
	tmp -> v = v; tmp -> next = g[u]; g[u] = tmp;
	//printf ( "%d  %d\n" , u , v );
}
void buildtree ( tree *id , int l , int r ) {
	id -> l = l; id -> r = r;
	if ( l == r ) {
		if ( mix[l] > 0 ) add ( 2 * n + id -> i , mix[l] * 2 );
		else add ( 2 * n + id -> i , (-mix[l]) * 2 - 1 );
		return ;
	}
	int mid = (l+r)/2;
	id -> ll = &poolt[++topt]; id -> ll -> i = topt;
	id -> rr = &poolt[++topt]; id -> rr -> i = topt;
	buildtree ( id -> ll , l , mid );
	buildtree ( id -> rr , mid + 1 , r );
	add ( 2 * n + id -> i , 2 * n + id -> ll -> i );
	add ( 2 * n + id -> i , 2 * n + id -> rr -> i );
}
void change ( tree *id , int l , int r , int from ) {
	if ( id -> l == l && id -> r == r ) {
		add ( from , 2 * n + id -> i );
		return ;
	}
	int mid = (id->l+id->r)/2;
	if ( r <= mid ) change ( id -> ll , l , r , from );
	else {
		if ( l > mid ) change ( id -> rr , l , r , from );
		else {
			change ( id -> ll , l , mid , from );
			change ( id -> rr , mid + 1 , r , from );
		}
	}
}
void tarjan ( int i ) {
	dfn[i] = low[i] = ++index;
	stack[++tops] = i;
	ins[i] = 1;
	for ( node *j = g[i] ; j ; j = j -> next ) {
		if ( dfn[j->v] ) {
			if ( ins[j->v] )low[i] = min ( low[i] , dfn[j->v] );
		}
		else {
			tarjan ( j -> v );
			low[i] = min ( low[i] , low[j->v] );
		}
	}
	if ( low[i] == dfn[i] ) {
		color++;
		while ( stack[tops] != i ) {
			col[stack[tops]] = color;
			ins[stack[tops]] = 0;
			tops--;
		}
		col[i] = color;
		ins[i] = 0;
		tops--;
	}
}
int check ( int ans ) {
	int i , l , r;
	clear ();
	t = &poolt[++topt];
	t -> i = 1;
	buildtree ( t , 1 , n * 2 );
	//printf ( "\n" );
	for ( i = 1 ; i <= n ; i++ ) {
		l = lower_bound ( pos + 1 , pos + 2 * n + 1 , x[i] - ans + 1 ) - pos;
		if ( x[i] + ans - 1 >= pos[2*n] ) r = 2 * n;
		else r = upper_bound ( pos + 1 , pos + 2 * n + 1 , x[i] + ans - 1 ) - pos - 1;
		if ( l <= getx[i] - 1 ) change ( t , l , getx[i] - 1 , i * 2 - 1 );
		if ( getx[i] + 1 <= r ) change ( t , getx[i] + 1 , r , i * 2 - 1 );
		//printf ( "%d %d %d %d\n" , i , l , r , getx[i] );
		
		l = lower_bound ( pos + 1 , pos + 2 * n + 1 , y[i] - ans + 1 ) - pos;
		if ( y[i] + ans - 1 >= pos[2*n] ) r = 2 * n;
		else r = upper_bound ( pos + 1 , pos + 2 * n + 1 , y[i] + ans - 1 ) - pos - 1;
		if ( l <= gety[i] - 1 ) change ( t , l , gety[i] - 1 , i * 2 );
		if ( gety[i] + 1 <= r ) change ( t , gety[i] + 1 , r , i * 2 );
		//printf ( "%d %d %d %d\n" , i , l , r , gety[i] );
	}
	for ( i = 1 ; i <= n * 2 + topt ; i++ ) if ( !dfn[i] ) tarjan ( i );
	//for ( i = 1 ; i <= n * 2 + topt ; i++ ) printf ( "%d  %d %d\n" , dfn[i] , low[i] , col[i] );
	for ( i = 1 ; i <= n ; i++ ) {
		if ( col[i*2] == col[i*2-1] ) return 0;
	}
	return 1;
}
void work () {
	int i , l , r , mid;
	scanf ( "%d" , &n );
	for ( i = 1 ; i <= n ; i++ ) {
		scanf ( "%d%d" , &x[i] , &y[i] );
		mix[i*2-1] = i; mix[i*2] = -i;
		pos[i*2-1] = x[i]; pos[i*2] = y[i];
	}
	sort ( mix + 1 , mix + n * 2 + 1 , cmp );
	sort ( pos + 1 , pos + n * 2 + 1 );
	for ( i = 1 ; i <= n * 2 ; i++ ) {
		//printf ( "%d %d\n" , mix[i] , pos[i] );
		if ( mix[i] < 0 ) gety[-mix[i]] = i;
		else getx[mix[i]] = i;
	}
	l = 0; r = 1000000000;
	while ( l < r - 1 ) {
		mid = (l+r)/2;
		if ( check ( mid ) == 1 ) l = mid;
		else r = mid;
		//printf ( "%d %d\n" , l , r );
	}
	if ( check ( r ) == 1 ) printf ( "%d\n" , r );
	else printf ( "%d\n" , l );
}
int main () {
	work ();
	return 0;
}


Measured memory_bytes: 32512