#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define Size(x) ((int)((x).size()))
#define rep(i, l, r) for(int (i) = (l); (i) <= (r); ++(i))
#define per(i, r, l) for(int (i) = (r); (i) >= (l); --(i))
#define chkmax(x, y) (x) = max((x), (y))
#define chkmin(x, y) (x) = min((x), (y))
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> VI;
inline char gc() {
	static char now[1 << 16], *S, *T;
	if (S == T) {T = (S = now) + fread(now, 1, 1 << 16, stdin); if (S == T) return EOF;}
	return *S ++;
}
inline int read() {
	int x = 0, f = 1; char c = gc();
	while (c < '0' || c > '9') {(c == '-') ? (f = 0) : 0; c = gc();}
	while (c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = gc();}
	return f ? x : ((~ x) + 1);
}
const int N = 20010;
const int inf = 1000000000;
struct edge {
	int to, nxt;
} e[10000010], e2[10000010];
int hd[N * 33], cnt, hd2[N * 33], cnt2;
inline void addedge(int x, int y) {
	e[++ cnt] = (edge) {y, hd[x]};
	hd[x] = cnt;
}
inline void addedge2(int x, int y) {
	e2[++ cnt2] = (edge) {y, hd2[x]};
	hd2[x] = cnt2;
}
int n, X[N << 1];
int mn[N << 3], mx[N << 3], len = 0, id[N << 1];
void build(int p, int l, int r) {
	chkmax(len, p);
	if (l == r) {
		mn[p] = mx[p] = X[l];
		addedge(p + (n << 1 | 1), id[l + 1] ^ 1);
		return ;
	}
	int mid = (l + r) >> 1;
	build(p << 1, l, mid); build(p << 1 | 1, mid + 1, r);
	addedge(p + (n << 1 | 1), (p << 1) + (n << 1 | 1));
	addedge(p + (n << 1 | 1), (p << 1 | 1) + (n << 1 | 1));
	mn[p] = min(mn[p << 1], mn[p << 1 | 1]);
	mx[p] = max(mx[p << 1], mx[p << 1 | 1]);
}
void query(int fr, int p, int l, int r, int ql, int qr) {
	ql = max(ql, l); qr = min(qr, r);
	if (ql > qr) return ;
	if (ql <= l && r <= qr) {
		addedge2(fr, p + (n << 1 | 1));
		return ;
	}
	int mid = (l + r) >> 1;
	if (ql <= mid) query(fr, p << 1, l, mid, ql, qr);
	if (mid < qr) query(fr, p << 1 | 1, mid + 1, r, ql, qr);
}

int dfn[N * 33], low[N * 33], instk[N * 33], stk[N * 33], top, tim, scc, bel[N * 33];
void tarjan(int x) {
	dfn[x] = low[x] = ++ tim; stk[++ top] = x; instk[x] = 1;
	for (int i = hd[x]; i; i = e[i].nxt) {
		int y = e[i].to;
		if (!dfn[y]) {
			tarjan(y);
			low[x] = min(low[x], low[y]);
		} else if (instk[y]) low[x] = min(low[x], dfn[y]);
	}
	for (int i = hd2[x]; i; i = e2[i].nxt) {
		int y = e2[i].to;
		if (!dfn[y]) {
			tarjan(y);
			low[x] = min(low[x], low[y]);
		} else if (instk[y]) low[x] = min(low[x], dfn[y]);
	}
	if (dfn[x] == low[x]) {
		++ scc; int y;
		do {
			y = stk[top --];
			instk[y] = 0;
			bel[y] = scc;
		} while (y ^ x);
	}
}
int rnk[N << 1], b[N << 1 | 1];
inline bool cmp(int x, int y) {
	return X[x] < X[y];
}
inline int getupp(int val) {
	return upper_bound(b + 1, b + 2 * n + 1, val) - b;
}
inline int getlow(int val) {
	return lower_bound(b + 1, b + 2 * n + 1, val) - b - 1;
}
inline bool check(int mid) {
	cnt2 = 0;
	for (int i = 2; i <= (n << 1 | 1); ++ i) hd2[i] = 0;
	for (int i = 2; i <= (n << 1 | 1); ++ i) {
		query(i, 1, 1, n * 2, getupp(X[i] - mid), rnk[i] - 1);
		query(i, 1, 1, n * 2, rnk[i] + 1, getlow(X[i] + mid));
	}
	for (int i = 2; i <= (n << 1 | 1) + len; ++ i) dfn[i] = low[i] = instk[i] = bel[i] = 0; tim = top = scc = 0;
	for (int i = 2; i <= (n << 1 | 1) + len; ++ i) if (!dfn[i]) tarjan(i);
	for (int i = 1; i <= n; ++ i) if (bel[i << 1] == bel[i << 1 | 1]) return 0;
	return 1;
}

int main() {
	n = read();
	rep(i, 1, n) X[i << 1] = read(), X[i << 1 | 1] = read(), b[i * 2 - 1] = X[i << 1], b[i * 2] = X[i << 1 | 1], id[i << 1] = i << 1, id[i << 1 | 1] = i << 1 | 1;
	sort(id + 2, id + (n << 1 | 1) + 1, cmp);
	rep(i, 2, n << 1 | 1) {
		rnk[id[i]] = i - 1;
	}
	sort(b + 1, b + n * 2 + 1);
	build(1, 1, n << 1);
	int l = 1, r = inf, mid, ans;
	while (l <= r) {
		mid = (l + r) >> 1;
		if (check(mid)) l = mid + 1, ans = mid;
		else r = mid - 1;
	}
	printf("%d\n", ans);
	return 0;
}

Measured memory_bytes: 31488