#include<stdio.h>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
#define SIZE 200000
class twosat
{
public:
	int num;//変数の個数
	vector<int>pat[SIZE * 2];
	vector<int>rpat[SIZE * 2];
	bool flag[SIZE * 2];
	int bun[SIZE * 2];
	vector<int>topo;
	void init(int n)
	{
		num = n;
		for (int i = 0; i < SIZE * 2; i++)
		{
			pat[i].clear();
			rpat[i].clear();
		}
	}
	void adde(int ax, bool ay, int bx, bool by)//ay ax or by bx を追加
	{
		int t = ax * 2, s = bx * 2;
		if ((ay) && (by))
		{
			pat[t + 1].push_back(s);
			pat[s + 1].push_back(t);
			rpat[t].push_back(s + 1);
			rpat[s].push_back(t + 1);
		}
		if ((!ay) && (by))
		{
			pat[t].push_back(s);
			pat[s + 1].push_back(t + 1);
			rpat[t + 1].push_back(s + 1);
			rpat[s].push_back(t);
		}
		if ((ay) && (!by))
		{
			pat[t + 1].push_back(s + 1);
			pat[s].push_back(t);
			rpat[t].push_back(s);
			rpat[s + 1].push_back(t + 1);
		}
		if ((!ay) && (!by))
		{
			pat[t].push_back(s + 1);
			pat[s].push_back(t + 1);
			rpat[t + 1].push_back(s);
			rpat[s + 1].push_back(t);
		}
	}
	void dfs(int node)
	{
		if (flag[node])return;
		flag[node] = true;
		for (int i = 0; i < pat[node].size(); i++)dfs(pat[node][i]);
		topo.push_back(node);
	}
	void rdfs(int node, int b)
	{
		if (flag[node])return;
		flag[node] = true;
		bun[node] = b;
		for (int i = 0; i < rpat[node].size(); i++)rdfs(rpat[node][i], b);
	}
	void scc()
	{
		fill(flag, flag + SIZE * 2, false);
		topo.clear();
		for (int i = 0; i < num * 2; i++)if (!flag[i])dfs(i);
		fill(flag, flag + SIZE * 2, false);
		int pt = 0;
		for (int i = num * 2 - 1; i >= 0; i--)if (!flag[topo[i]])rdfs(topo[i], pt++);
	}
	bool issatisfiable()
	{
		for (int i = 0; i < num; i++)
		{
			if (bun[i * 2] == bun[i * 2 + 1])return false;
		}
		return true;
	}
	vector<bool>getval()
	{
		vector<bool>ret;
		for (int i = 0; i < num; i++)
		{
			if (bun[i * 2] < bun[i * 2 + 1])ret.push_back(false);
			else ret.push_back(true);
		}
		return ret;
	}
};
twosat sat;
typedef pair<int, int>pii;
void add(int beg, int end, int node, int lb, int ub, int pl)
{
	if (end < lb || ub < beg)return;
	if (beg <= lb&&ub <= end)
	{
		sat.adde(pl, false, node, false);
		return;
	}
	add(beg, end, node * 2, lb, (lb + ub) / 2, pl);
	add(beg, end, node * 2 + 1, (lb + ub) / 2 + 1, ub, pl);
}
bool isok(vector<pii>v, vector<pii>zat, int med)
{
	sat.init(80000);
	for (int i = 1; i < (1 << 15); i++)sat.adde(i * 2, false, i, true), sat.adde(i * 2 + 1, false, i, true);
	int lb = 0, ub = 0;
	for (int i = 0; i < zat.size(); i++)
	{
		for (;;)
		{
			if (zat[lb].first <= zat[i].first - med)lb++;
			else break;
		}
		for (;;)
		{
			if (ub == zat.size())break;
			if (zat[ub].first >= zat[i].first + med)break;
			else ub++;
		}
		add(lb, i - 1, 1, 0, (1 << 15) - 1, (1 << 15) + i);
		add(i + 1, ub - 1, 1, 0, (1 << 15) - 1, (1 << 15) + i);
	}
	for (int i = 0; i < v.size(); i++)
	{
		int l1 = lower_bound(zat.begin(), zat.end(), make_pair(v[i].first, i + 1)) - zat.begin();
		int l2 = lower_bound(zat.begin(), zat.end(), make_pair(v[i].second, -i - 1)) - zat.begin();
		sat.adde((1 << 15) + l1, true, (1 << 15) + l2, true);
	}
	sat.scc();
	return sat.issatisfiable();
}
int main()
{
	int num;
	scanf("%d", &num);
	vector<pii>v;
	vector<pii>zat;
	for (int i = 0; i < num; i++)
	{
		int za, zb;
		scanf("%d%d", &za, &zb);
		v.push_back(make_pair(za, zb));
		zat.push_back(make_pair(za, i + 1)), zat.push_back(make_pair(zb, -i - 1));
	}
	sort(zat.begin(), zat.end());
	int beg = 0, end = 1000000000;
	for (;;)
	{
		if (beg == end)break;
		int med = (beg + end + 1) / 2;
		if (isok(v, zat, med))beg = med;
		else end = med - 1;
	}
	printf("%d\n", beg);
}

Measured memory_bytes: 52180