// Slower C++ solution:
#include <stdio.h>

#include <iostream>

#include <vector>

#include <assert.h>

#include <set>

#include <map>

#include <cmath>

#include <queue>

#include <stack>

#include <string>

#include <sstream>

#include <memory.h>

#include <time.h>

#include <string.h>

#include <stdlib.h>

#include <algorithm>

using namespace std;

typedef long long ll;

const int N = 80000;

int nodeID[N];

vector<vector<int> > g;

vector<pair<int,int> > val;

int n, L;

int Not(int u) {

	if (u < L)

		return u + L;

	return u - L;

}

void addEdge(int u, int v) {

	g[Not(u)].push_back(v);

	g[Not(v)].push_back(u);

}

vector<int> S;

int comp[N], low[N], idx[N], dfs, cmp;

bool vis[N];

void DFS(int u) {

	idx[u] = low[u] = ++dfs;

	vis[u] = true;

	S.push_back(u);

	for (int i = 0; i < g[u].size(); ++i) {

		int v = g[u][i];

		if (!low[v])

			DFS(v);

		if (vis[v])

			low[u] = min(low[u], low[v]);

	}

	if (low[u] == idx[u]) {

		while (true) {

			int v = S.back();

			S.pop_back();

			vis[v] = false;

			comp[v] = cmp;

			if (u == v)

				break;

		}

		++cmp;

	}

}

int id;

void setID(int n, int s, int e) {

	if (s == e)

		return;

	nodeID[n] = id++;

	setID(n * 2, s, (s + e) / 2);

	setID(n * 2 + 1, (s + e) / 2 + 1, e);

}

void initEdges(int n, int s, int e) {

	if (s == e) {

		nodeID[n] = val[s].second;

		return;

	}

	initEdges(n * 2, s, (s + e) / 2);

	initEdges(n * 2 + 1, (s + e) / 2 + 1, e);

	g[Not(nodeID[n])].push_back(Not(nodeID[n * 2]));

	g[Not(nodeID[n])].push_back(Not(nodeID[n * 2 + 1]));

}

int ql, qr;

void addEdges(int n, int s, int e, int u) {

	if (qr<s || ql>e)

		return;

	if (s >= ql && e <= qr) {

		g[u].push_back(Not(nodeID[n]));

		return;

	}

	addEdges(n * 2, s, (s + e) / 2, u);

	addEdges(n * 2 + 1, (s + e) / 2 + 1, e, u);

}

vector<int> sz;

bool check(int d) {

	for (int i = 0; i < g.size(); ++i)

		g[i].resize(sz[i]);

	for (int i = 1; i < val.size(); ++i) {

		ql = lower_bound(val.begin() + 1, val.end(), make_pair(val[i].first - d + 1, -1)) - val.begin();

		if (ql < i) {

			qr = i - 1;

			addEdges(1, 1, n * 2, val[i].second);

		}

		ql = i + 1;

		qr = lower_bound(val.begin() + 1, val.end(), make_pair(val[i].first + d, -1)) - val.begin();

		--qr;

		if (ql <= qr)

			addEdges(1, 1, n * 2, val[i].second);

	}

	memset(low, 0, sizeof(low));

	dfs = cmp = 0;

	for (int i = 0; i < g.size(); ++i)

		if (!low[i])

			DFS(i);

	for (int i = 0; i < L; ++i)

		if (comp[i] == comp[Not(i)])

			return false;

	return true;

}

int main()

{

	scanf("%d", &n);

	id = n;

	setID(1, 1, n * 2);

	L = id;

	val.resize(n * 2 + 1);

	for (int i = 1; i <= n; ++i) {

		scanf("%d", &val[i].first);

		val[i].second = i - 1;

		scanf("%d", &val[i + n].first);

		val[i + n].second = Not(i - 1);

	}

	sort(val.begin() + 1, val.end());

	g.resize(L << 1);

	initEdges(1, 1, n * 2);

	for (int i = 0; i < g.size(); ++i)

		sz.push_back(g[i].size());

	int l = 0, r = 1e9, m, res = 0;

	while (l <= r) {

		m = (l + r) / 2;

		if (check(m)) {

			res = m;

			l = m + 1;

		}else

			r = m - 1;

	}

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

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1449567239843874x):
#include <stdio.h>

#include <iostream>

#include <vector>

#include <assert.h>

#include <set>

#include <map>

#include <cmath>

#include <queue>

#include <stack>

#include <string>

#include <sstream>

#include <memory.h>

#include <time.h>

#include <string.h>

#include <stdlib.h>

#include <algorithm>

using namespace std;

typedef long long ll;

const int N = 60000;

int nodeID[80000];

vector<vector<int> > g;

vector<pair<int,int> > val;

int n, L;

int Not(int u) {

	if (u < L)

		return u + L;

	return u - L;

}

void addEdge(int u, int v) {

	g[Not(u)].push_back(v);

	g[Not(v)].push_back(u);

}

vector<int> S;

int comp[N], low[N], idx[N], dfs, cmp;

bool vis[N];

void DFS(int u) {

	idx[u] = low[u] = ++dfs;

	vis[u] = true;

	S.push_back(u);

	for (int i = 0; i < g[u].size(); ++i) {

		int v = g[u][i];

		if (!low[v])

			DFS(v);

		if (vis[v])

			low[u] = min(low[u], low[v]);

	}

	if (low[u] == idx[u]) {

		while (true) {

			int v = S.back();

			S.pop_back();

			vis[v] = false;

			comp[v] = cmp;

			if (u == v)

				break;

		}

		++cmp;

	}

}

int id;

void setID(int n, int s, int e) {

	if (s == e)

		return;

	nodeID[n] = id++;

	setID(n * 2, s, (s + e) / 2);

	setID(n * 2 + 1, (s + e) / 2 + 1, e);

}

void initEdges(int n, int s, int e) {

	if (s == e) {

		nodeID[n] = val[s].second;

		return;

	}

	initEdges(n * 2, s, (s + e) / 2);

	initEdges(n * 2 + 1, (s + e) / 2 + 1, e);

	g[Not(nodeID[n])].push_back(Not(nodeID[n * 2]));

	g[Not(nodeID[n])].push_back(Not(nodeID[n * 2 + 1]));

}

int ql, qr;

void addEdges(int n, int s, int e, int u) {

	if (qr<s || ql>e)

		return;

	if (s >= ql && e <= qr) {

		g[u].push_back(Not(nodeID[n]));

		return;

	}

	addEdges(n * 2, s, (s + e) / 2, u);

	addEdges(n * 2 + 1, (s + e) / 2 + 1, e, u);

}

vector<int> sz;

bool check(int d) {

	for (int i = 0; i < g.size(); ++i)

		g[i].resize(sz[i]);

	for (int i = 1; i < val.size(); ++i) {

		ql = lower_bound(val.begin() + 1, val.end(), make_pair(val[i].first - d + 1, -1)) - val.begin();

		if (ql < i) {

			qr = i - 1;

			addEdges(1, 1, n * 2, val[i].second);

		}

		ql = i + 1;

		qr = lower_bound(val.begin() + 1, val.end(), make_pair(val[i].first + d, -1)) - val.begin();

		--qr;

		if (ql <= qr)

			addEdges(1, 1, n * 2, val[i].second);

	}

	memset(low, 0, sizeof(low));

	dfs = cmp = 0;

	for (int i = 0; i < g.size(); ++i)

		if (!low[i])

			DFS(i);

	for (int i = 0; i < L; ++i)

		if (comp[i] == comp[Not(i)])

			return false;

	return true;

}

int main()

{

	scanf("%d", &n);

	id = n;

	setID(1, 1, n * 2);

	L = id;

	val.resize(n * 2 + 1);

	for (int i = 1; i <= n; ++i) {

		scanf("%d", &val[i].first);

		val[i].second = i - 1;

		scanf("%d", &val[i + n].first);

		val[i + n].second = Not(i - 1);

	}

	sort(val.begin() + 1, val.end());

	g.resize(L << 1);

	initEdges(1, 1, n * 2);

	for (int i = 0; i < g.size(); ++i)

		sz.push_back(g[i].size());

	int l = 0, r = 1e9, m, res = 0;

	while (l <= r) {

		m = (l + r) / 2;

		if (check(m)) {

			res = m;

			l = m + 1;

		}else

			r = m - 1;

	}

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

	return 0;

}