#include <bits/stdc++.h>

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()
#define pb push_back

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef double ld;

const ll inf = 1e10;

vector<vector<int> > g;
vector<vector<int> > gr;
vector<int> order;
vector<char> used;

void dfs1(int v)
{
	used[v] = true;
	for (int to : g[v]) {
		if (!used[to]) {
			dfs1(to);
		}
	}
	order.pb(v);
}

vector<int> compId;

void dfs2(int v, int cc)
{
	compId[v] = cc;
	for (int to : gr[v]) {
		if (compId[to] == -1) {
			dfs2(to, cc);
		}
	}
}

struct data
{
	ll x, y;
	int id;
};

bool comp1(const data& a, const data& b)
{
	if (a.x != b.x) {
		return a.x < b.x;
	}
	return a.id < b.id;
}

bool comp2(const data& a, const data& b)
{
	if (a.y != b.y) {
		return a.y < b.y;
	}
	return a.id < b.id;
}

int n;

void buildST(int v, int tl, int tr, vector<int>& vertex)
{
	int tm = (tl + tr) >> 1;
	int LF = v * 2;
	if (v >= 4 * n) {
		LF = (v - 4 * n + 1) * 2 + 4 * n - 1;
	}
	int RG = v * 2 + 1;
	if (v >= 4 * n) {
		RG = (v - 4 * n + 1) * 2 + 4 * n;
	}
	g[v].pb(LF);
	gr[LF].pb(v);
	if (tl == tm) {
		vertex[tl] = LF;
	} else {
		buildST(LF, tl, tm, vertex);
	}
	g[v].pb(RG);
	gr[RG].pb(v);
	if (tm + 1 == tr) {
		vertex[tr] = RG;
	} else {
		buildST(RG, tm + 1, tr, vertex);
	}
}

void getX(vector<data>& v, ll a, ll b, int& l, int& r)
{
	if (a > b) {
		l = -1, r = -1;
		return;
	}
	if (v.back().x < a) {
		l = r = -1;
		return;
	}
	if (v[0].x > b) {
		l = r = -1;
		return;
	}
	int lf = -1, rg = n - 1;
	while (rg - lf > 1) {
		int md = (lf + rg) >> 1;
		if (v[md].x >= a) {
			rg = md;
		} else {
			lf = md;
		}
	}
	l = rg;
	lf = 0, rg = n;
	while (rg - lf > 1) {
		int md = (lf + rg) >> 1;
		if (v[md].x <= b) {
			lf = md;
		} else {
			rg = md;
		}
	}
	r = lf;
}

void getY(vector<data>& v, ll a, ll b, int& l, int& r)
{
	if (a > b) {
		l = r = -1;
		return;
	}
	if (v.back().y < a) {
		l = r = -1;
		return;
	}
	if (v[0].y > b) {
		l = r = -1;
		return;
	}
	int lf = -1, rg = n - 1;
	while (rg - lf > 1) {
		int md = (lf + rg) >> 1;
		if (v[md].y >= a) {
			rg = md;
		} else {
			lf = md;
		}
	}
	l = rg;
	lf = 0, rg = n;
	while (rg - lf > 1) {
		int md = (lf + rg) >> 1;
		if (v[md].y <= b) {
			lf = md;
		} else {
			rg = md;
		}
	}
	r = lf;
}

void makeEdges(int u, int v, int tl, int tr, int l, int r)
{
	if (tl == l && tr == r) {
		g[u].pb(v);
		gr[v].pb(u);
		return;
	}
	int LF = v * 2;
	if (v >= 4 * n) {
		LF = (v - 4 * n + 1) * 2 + 4 * n - 1;
	}
	int RG = v * 2 + 1;
	if (v >= 4 * n) {
		RG = (v - 4 * n + 1) * 2 + 4 * n;
	}
	int tm = (tl + tr) >> 1;
	if (l <= tm) {
		makeEdges(u, LF, tl, tm, l, min(r, tm));
	}
	if (r > tm) {
		makeEdges(u, RG, tm + 1, tr, max(l, tm + 1), r);
	}
}

int main()
{

	//ifstream cin("input.txt");
	//freopen("output.txt", "w", stdout);

	//ios_base::sync_with_stdio(false);
	//cin.tie(0);

	cin >> n;
	vector<data> v(n);

	for (int i = 0; i < n; ++i) {
		cin >> v[i].x >> v[i].y;
		v[i].id = i;
	}

	vector<int> x_id(n), y_id(n);
	vector<data> vx = v;
	sort(all(vx), comp1);
	for (int i = 0; i < n; ++i) {
		x_id[vx[i].id] = i;
	}
	vector<data> vy = v;
	sort(all(vy), comp2);
	for (int i = 0; i < n; ++i) {
		y_id[vy[i].id] = i;
	}

	ll lf = 0, rg = inf;
	//ll lf = 7, rg = 9;
	while (rg - lf > 1) {
		ll d = (lf + rg) >> 1;
		//ll d = 5;
		g = vector<vector<int> >(8 * n, vector<int>());
		gr = vector<vector<int> >(8 * n, vector<int>());
		order.clear();
		used.assign(8 * n, false);
		compId.assign(8 * n, -1);
		vector<int> vertex_x(n), vertex_y(n);
		buildST(1, 0, n - 1, vertex_x);
		buildST(4 * n, 0, n - 1, vertex_y);
		for (int i = 0; i < n; ++i) {
			ll x = v[i].x;
			ll y = v[i].y;
			int l, r;

			getY(vy, x - d + 1, x + d - 1, l, r);
			if (l != -1) {
				makeEdges(vertex_y[y_id[i]], 4 * n, 0, n - 1, l, r);
			}

			getX(vx, x - d + 1, x + d - 1, l, r);
			if (l != -1) {
				if (l <= x_id[i] && x_id[i] <= r) {
					if (l < x_id[i]) {
						makeEdges(vertex_y[y_id[i]], 1, 0, n - 1, l, x_id[i] - 1);
					}
					if (x_id[i] < r) {
						makeEdges(vertex_y[y_id[i]], 1, 0, n - 1, x_id[i] + 1, r);
					}
				} else {
					makeEdges(vertex_y[y_id[i]], 1, 0, n - 1, l, r);
				}
			}

			getX(vx, y - d + 1, y + d - 1, l, r);
			if (l != -1) {
				makeEdges(vertex_x[x_id[i]], 1, 0, n - 1, l, r);
			}

			getY(vy, y - d + 1, y + d - 1, l, r);
			if (l != -1) {
				if (l <= y_id[i] && y_id[i] <= r) {
					if (l < y_id[i]) {
						makeEdges(vertex_x[x_id[i]], 4 * n, 0, n - 1, l, y_id[i] - 1);
					}
					if (y_id[i] < r) {
						makeEdges(vertex_x[x_id[i]], 4 * n, 0, n - 1, y_id[i] + 1, r);
					}
				} else {
					makeEdges(vertex_x[x_id[i]], 4 * n, 0, n - 1, l, r);
				}
			}
		}
		/*for (int i = 0; i < sz(g); ++i) {
			for (int to : g[i]) {
				cout << i << " " << to << '\n';
			}
		}*/
		for (int i = 0; i < sz(g); ++i) {
			if (!used[i]) {
				dfs1(i);
			}
		}
		reverse(all(order));
		int cc = 0;
		for (int v : order) {
			if (compId[v] == -1) {
				dfs2(v, cc);
				++cc;
			}
		}
		bool ok = true;
		for (int i = 0; i < n; ++i) {
			if (compId[vertex_x[x_id[i]]] == compId[vertex_y[y_id[i]]]) {
				ok = false;
				break;
			}
		}
		if (ok) {
			lf = d;
		} else {
			rg = d;
		}
	}

	cout << lf << "\n";

}


Measured memory_bytes: 24996