#include<bits/stdc++.h>
using namespace std;
const bool DBG = 1;

#define TRACE(x)    x
#define WATCH(x)    TRACE(cout << #x" = " << x << endl)
#define WATCHR(a,b) TRACE(for(auto it=a; it!=b;) cout<<*(it++)<<" ";cout<<endl)
#define WATCHC(V)   TRACE({cout << #V" = "; WATCHR(V.begin(), V.end());})
#define all(x) (x).begin(), (x).end()

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define lb lower_bound
#define ub upper_bound
#define f first
#define s second
#define resz resize

#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i, a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define sort_by(x, y) sort(all(x), [&](const auto& a, const auto& b) { return y; })

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<double, double>;

using vpii = vector<pii>;
using vvpii = vector<vpii>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;
using vpdd = vector<pdd>;
using vvpdd = vector<vpdd>;

template<typename T> void ckmin(T& a, const T& b) { a = min(a, b); }
template<typename T> void ckmax(T& a, const T& b) { a = max(a, b); }


// Labels strongly connected components in reverse topological order.
// That means for any edge u-->v comp[u] >= comp[v].
pair<int, vi> strongly_connected_components(const vvi& graph) {
    const int N = graph.size();
    int C = 0, V = 0, top = 0;
    vi comp(N, -1), inx(N, -1), stack(N + 1, -1);
	
    auto tarjan = [&](auto&& self, int loc) -> int {
		//cout << "Enter: " << loc << endl;
        stack[top++] = loc;
        int low = inx[loc] = V++;
		//cout << "PreFor: " << loc << endl;
        for (int nbr : graph[loc]) {
			//cout << "Nbr: " << nbr << endl;
            if (inx[nbr] == -1) low = min(low, self(self, nbr));
            else if (comp[nbr] == -1) low = min(low, inx[nbr]);
        }
		//cout << "PostFor: " << loc << endl;
        if (low == inx[loc]) {
            while (stack[top] != loc)
                comp[stack[--top]] = C;
            C++;
        }
		//cout << "Exit: " << loc << endl;
        return low;
    };
	
    for (int i = 0; i < N; i++) {
		/*if(i % 100 == 0) {
			cout << "tarjan " << i << " / " << N << endl;
		}*/
        if (inx[i] == -1)
            tarjan(tarjan, i);
    }
    return { C, comp };
}

struct two_sat {
    vvi graph;
    two_sat() {}

    inline int neg(int a) { return a^1; }
	
    void implies(int a, int b) {
        if (a < 0 || b < 0) return;
        graph[a].pb(b);
        graph[neg(b)].pb(neg(a));
    }
	
    void assign(int a, int v) {
        if (v) implies(neg(a), a);
        else implies(a, neg(a));
    }
    void equal(int a, int b) {
        implies(a, b);
        implies(neg(a), neg(b));
    }
    void not_equal(int a, int b) {
        implies(a, neg(b));
        implies(neg(a), b);
    }
    void at_most_one(int a, int b) {
        implies(a, neg(b)); // contrapositive is automatic
    }
    void at_least_one(int a, int b) {
        implies(neg(a), b); // contrapositive is automatic
    }
	
    int new_var() {
        graph.pb({});
        graph.pb({});
        return sz(graph) - 1;
    }
	
    int make_or(int a, int b) {
        if (a < 0) return b;
        if (b < 0) return a;
        int v = new_var();
        implies(a, v);
        implies(b, v);
        return v;
    }
	
    int make_and(int a, int b) {
        if (a < 0) return b;
        if (b < 0) return a;
        int v = new_var();
        implies(v, a);
        implies(v, b);
        return v;
    }
	
    vb solve() {
        //int C; vi comp; tie(C, comp) = strongly_connected_components(graph);
		//cout << "pre-scc" << endl;
		auto p = strongly_connected_components(graph);
		//cout << "post-scc" << endl;
		int C = p.f; vi comp = p.s;
        vb res(sz(graph));
        for (int v = 0; v < sz(res); v++) {
            if (comp[v] == comp[neg(v)]) return {};
            res[v] = comp[v] < comp[neg(v)];
        }
        return res;
    }
};

template<typename T, typename F> struct segment_tree {
    int SZ;
    T id; F tt;
    vector<T> table;
	
    segment_tree() {}
    segment_tree(int _SZ, T _id, F _tt) : SZ(_SZ), id(_id), tt(_tt) {
        table.resize(2 * SZ, id);
    }
    template<typename L> void set_leaves(L create) {
        for (int i = 0; i < SZ; i++) table[SZ + i] = create(i);
        for (int i = SZ - 1; i; i--) table[i] = tt(table[2 * i], table[2 * i + 1]);
    }
	
    // Replaces the element at index i with v
    void replace(int i, T v) {
        table[i += SZ] = v;
        for (i /= 2; i > 0; i /= 2) {
            table[i] = tt(table[2 * i], table[2 * i + 1]);
        }
    }
	
    // Accumulates the elements at indices in [i, j)
    T operator()(int i, int j) const {
        T left = id, right = id;
        for (i += SZ, j += SZ; i < j; i /= 2, j /= 2) {
            if (i&1) left = tt(left, table[i++]);
            if (j&1) right = tt(table[--j], right);
        }
        return tt(left, right);
    }
    const T& operator[](int i) const { return table[SZ + i]; }
};

//two_sat g;
//map<pair<int,int>,int> memo;
int combine(two_sat &g, int n1, int n2) {
	//if(memo.find({n1, n2}) != memo.end()) return memo[{n1, n2}];
	//two_sat g = *gp;
	//cout << "[size=" << sz(g.graph) << "] Combining: " << n1 << " + " << n2 << " => ";
	int nc = g.new_var();
	//cout << nc << " | [size=" << sz(g.graph) << "]" << endl;
	g.implies(n1, nc);
	g.implies(n2, nc);
	return nc;//memo[{n1, n2}] = nc;
}

bool test(vpii srt, int d) {
	//memo.clear();
	int nn = srt.size();
	two_sat g;
	int eid = g.new_var();
	//vi els(nn);
	//auto f = [&g](int n1, int n2) -> int {return combine(g, n1, n2);};
	auto f = [&g](int n1, int n2){return combine(g, n1, n2);};
	segment_tree<int, decltype(f)> st(nn, eid, f);
	st.set_leaves([&g](int i){return g.new_var();});
	//cout << "SIZE: " << sz(g.graph);// << endl;
	vi other(nn, -1);
	FOR(i,0,nn) {
		int j = abs(srt[i].s) - 1;
		if(other[j] == -1) {
			other[j] = i;
		} else {
			//cout << "x != y: " << st[i] << " " << st[other[abs(srt[i].s)-1]] << endl;
			g.not_equal(st[i], st[other[j]]);
			//cout << st[i] << " => !" << st[other[j]] << endl;
			//cout << st[other[j]] << " => !" << st[i] << endl;
		}
	}
	//cout << " " << sz(g.graph);
	int pl=0, ph=0;
	FOR(i,0,nn) {
		while(pl<nn && srt[i].f - srt[pl].f >= d) pl++;
		if(pl < i) {
			int z = st(pl, i);
			//cout << i << ": x != radius(x,d=" << d << ")[" << pl << "," << i-1 << "]: " << st[i] << " " << z << endl;
			g.implies(z, g.neg(st[i]));
			//cout << z << " => " << g.neg(st[i]) << endl;
		}
		while(ph<nn && srt[ph].f - srt[i].f <  d) ph++;
		if(ph > i+1) {
			int z = st(i+1, ph);
			//cout << i << ": x != radius(x,d=" << d << ")[" << i+1 << "," << ph-1 << "]: " << st[i] << " " << z << endl;
			g.implies(z, g.neg(st[i]));
			//cout << z << " => " << g.neg(st[i]) << endl;
		}
	}
	//cout << " " << sz(g.graph) << endl;
	auto r = g.solve();
	/*FOR(i,0,sz(r)) {
		cout << r[i] << " ";
	}	cout << endl;*/
	return sz(r);
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cout << fixed << setprecision(15);

	int n; cin >> n;
	vpii pts(n), srt(2*n);
	FOR(i,0,n) {
		cin >> pts[i].f >> pts[i].s;
		srt[2*i+0] = {pts[i].f, +i+1};
		srt[2*i+1] = {pts[i].s, -i-1};
	}
	sort(srt.begin(), srt.end());

	int dl = 0, dm, dh = 1;
	while(test(srt, dh)) dh *= 2;
	while(dh - dl > 1) {
		int dm = dl + (dh - dl) / 2;
		if(test(srt, dm)) dl = dm;
		else dh = dm;
	}
	while(!test(srt, dh)) dh--;
	cout << dh << endl;
	return 0;
}


Measured memory_bytes: 60124