#include <map>
#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

void Get_Val(int &Ret)
{
	Ret = 0;
	char ch;
	while (ch = getchar(), ch > '9' || ch < '0')
		;
	do
	{
		(Ret *= 10) += ch - '0';
	}
	while (ch = getchar(), ch >= '0' && ch <= '9');
}

namespace G
{
	const int Max_V(10050 * 30);
	const int Max_E(10050 * 300);
	int V, Head[Max_V], Total, To[Max_E], Next[Max_E];
	inline void Add_Edge(const int &s, const int &t)
	{
		++Total, To[Total] = t, Next[Total] = Head[s], Head[s] = Total;
	}
	inline int rev(const int &x)
	{
		return (x <= V) ? (x + V) : (x - V);
	}
	inline void Link(const int &a, const int &b)
	{
		Add_Edge(rev(a), b), Add_Edge(rev(b), a);
	}
	int dfsclock, Pre[Max_V], Lowlink[Max_V], scctot, sccno[Max_V];
	stack<int> S;
	void clear()
	{
		for (int i = 1;i <= (V << 1);++i)
			Head[i] = Pre[i] = Lowlink[i] = sccno[i] = 0;
		for (int i = 1;i <= Total;++i)
			To[i] = Next[i] = 0;
		Total = dfsclock = scctot = 0;
	}
	void Tarjan(const int &u)
	{
		int v;
		Pre[u] = Lowlink[u] = ++dfsclock, S.push(u);
		for (int i = Head[u];i;i = Next[i])
			if (!Pre[v = To[i]])
				Tarjan(v), Lowlink[u] = min(Lowlink[u], Lowlink[v]);
			else
				if (!sccno[v])
					Lowlink[u] = min(Lowlink[u], Pre[v]);
		if (Pre[u] == Lowlink[u])
		{
			++scctot;
			while (true)
			{
				v = S.top(), S.pop();
				sccno[v] = scctot;
				if (u == v)
					break;
			}
		}
	}
	bool check()
	{
		for (int i = 1;i <= (V << 1);++i)
			if (!Pre[i])
				Tarjan(i);
		for (int i = 1;i <= V;++i)
			if (sccno[i] == sccno[i + V])
				return false;
		return true;
	}
}

const int Max_N(10050);
const int Max_M(20050);

int N, M, X[Max_N], Y[Max_N], P[Max_M << 1];
vector<int> V[Max_M], Pre[Max_M], Suf[Max_M];
map<int, int> S;

void init()
{
	Get_Val(N);
	for (int i = 1;i <= N;++i)
		Get_Val(X[i]), Get_Val(Y[i]), S[X[i]], S[Y[i]];
	for (map<int, int>::iterator it = S.begin();it != S.end();++it)
		P[it -> second = ++M] = it -> first;
	for (int i = 1;i <= N;++i)
		X[i] = S[X[i]], Y[i] = S[Y[i]];
}

#define LCH (segt[cur].lch)
#define RCH (segt[cur].rch)

struct node
{
	int lch, rch;
};
int tot, root, Pos[Max_M];
node segt[Max_M << 1];

void build_tree(int &cur, const int &LEFT, const int &RIGHT)
{
	if (!cur)
		segt[++tot] = segt[cur], cur = tot;
	if (LEFT == RIGHT)
	{
		Pos[LEFT] = cur;
		return;
	}
	int MID = LEFT + ((RIGHT - LEFT) >> 1);
	build_tree(LCH, LEFT, MID), build_tree(RCH, MID + 1, RIGHT);
}

void dfs(const int &cur, const int &LEFT, const int &RIGHT)
{
	if (LEFT == RIGHT)
		return;
	int MID = LEFT + ((RIGHT - LEFT) >> 1);
	G::Link(G::rev(N + LCH), N + cur), G::Link(G::rev(N + RCH), N + cur);
	dfs(LCH, LEFT, MID), dfs(RCH, MID + 1, RIGHT);
}

void Link(const int &cur, const int &LEFT, const int &RIGHT, const int &l, const int &r, const int &p)
{
	if (LEFT == l && RIGHT == r)
	{
		G::Link(G::rev(N + cur), G::rev(p));
		return;
	}
	int MID = LEFT + ((RIGHT - LEFT) >> 1);
	if (r <= MID)
		Link(LCH, LEFT, MID, l, r, p);
	else
		if (l > MID)
			Link(RCH, MID + 1, RIGHT, l, r, p);
		else
			Link(LCH, LEFT, MID, l, MID, p), Link(RCH, MID + 1, RIGHT, MID + 1, r, p);
}

bool check(const int &D)
{
	if (D == 0)
		return true;
	G::clear();
	dfs(root, 1, M);
	for (int p = 1, l, r, mid;p <= M;++p)
	{
		for (int j = 0;j != V[p].size();++j)
			G::Link(G::rev(V[p][j]), N + Pos[p]);
		for (int j = 0;j != V[p].size();++j)
		{
			G::Link(G::rev(V[p][j]), Suf[p][j]);
			G::Link(G::rev(V[p][j]), Pre[p][j]);
			if (j - 1 >= 0)
			{
				G::Link(G::rev(V[p][j]), G::rev(Pre[p][j - 1]));
				G::Link(G::rev(Pre[p][j - 1]), Pre[p][j]);
			}	
			if (j + 1 < V[p].size())
			{
				G::Link(G::rev(V[p][j]), G::rev(Suf[p][j + 1]));
				G::Link(G::rev(Suf[p][j + 1]), Suf[p][j]);
			}
		}
		l = 1, r = p + 1;
		while (l < r)
		{
			mid = l + ((r - l) >> 1);
			if (P[p] - P[mid] < D)
				r = mid;
			else
				l = mid + 1;
		}
		if (l <= p - 1)
			Link(root, 1, M, l, p - 1, N + Pos[p]);
		l = p, r = M + 1;
		while (l < r)
		{
			mid = l + ((r - l) >> 1);
			if (P[mid] - P[p] < D)
				l = mid + 1;
			else
				r = mid;
		}
		if (p + 1 <= (--l))
			Link(root, 1, M, p + 1, l, N + Pos[p]);
	}
	return G::check();
}

void work()
{
	build_tree(root, 1, M);
	G::V = N + tot;
	for (int i = 1;i <= N;++i)
		V[X[i]].push_back(i), V[Y[i]].push_back(-i);
	for (int p = 1;p <= M;++p)
	{
		for (int j = 0;j != V[p].size();++j)
			Pre[p].push_back(++G::V);
		for (int j = 0;j != V[p].size();++j)
			Suf[p].push_back(++G::V);
	}
	for (int p = 1;p <= M;++p)
		for (int j = 0;j != V[p].size();++j)
			if (V[p][j] > 0)
				V[p][j] = V[p][j];
			else
				V[p][j] = G::rev(-V[p][j]);
	int l(0), r(1000000000), mid;
	while (l < r)
	{
		mid = l + ((r - l) >> 1);
		if (check(mid))
			l = mid + 1;
		else
			r = mid;
	}
	printf("%d", l - 1);
}

int main()
{
	init();
	work();
	return 0;
}

Measured memory_bytes: 24272