// Slower C++ solution:
#include <algorithm>

#include <cstdio>

#include <cstring>

#include <vector>



using namespace std;



const int N = 1e4 + 5;



struct flag {

    int pos, idx;

    inline bool operator < (const flag& a) const { return pos < a.pos; }

    inline flag(int p = 0, int id = 0) : pos(p), idx(id) { }

} f[N << 1];

int n;



const int V = N << 3;

int vc, refer[V];

vector<int> G[V];

int dfn[V], low[V], timer;

int stk[V], top; bool inS[V];

int cmp[V], scc;



inline void addEdge(int fr, int to) {

    G[fr].push_back(to);

}



#define mid ((l + r) >> 1)

#define op(x) ((x) <= n ? (x) + n : (x) - n)

void build(int l, int r, int x) {

    refer[x] = ++vc;

    if (l == r)

        return addEdge(refer[x], op(f[l].idx));

    build(l, mid, x << 1);

    addEdge(refer[x], refer[x << 1]);

    build(mid + 1, r, x << 1 | 1);

    addEdge(refer[x], refer[x << 1 | 1]);

}

#undef op



void link(int l, int r, int x, int ql, int qr, int p) {

    if (ql <= l && r <= qr) return addEdge(p, refer[x]);

    if (ql <= mid) link(l, mid, x << 1, ql, qr, p);

    if (qr > mid) link(mid + 1, r, x << 1 | 1, ql, qr, p);

}

#undef mid



void tarjan(int x) {

    dfn[x] = low[x] = ++timer;

    inS[stk[++top] = x] = 1;

    for (auto y : G[x]) {

        if (!dfn[y]) tarjan(y), low[x] = min(low[x], low[y]);

        else if (inS[y]) low[x] = min(low[x], dfn[y]);

    }

    if (low[x] == dfn[x]) {

        ++scc;

        for (; ; ) {

            int k = stk[top--];

            cmp[k] = scc, inS[k] = 0;

            if (k == x) break;

        }

    }

}



#define CLR(x, v) memset(x, v, sizeof(x))

bool judge(int d) {

    for (int i = 1; i < n * 7; i++) G[i].clear();

    CLR(dfn, 0), CLR(low, 0), CLR(cmp, 0);

    CLR(stk, 0), CLR(inS, 0);

    timer = top = scc = 0, CLR(refer, 0);



    vc = n * 2, build(1, n * 2, 1);

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

        int l = upper_bound(f + 1, f + 1 + n * 2, flag(f[i].pos - d)) - f;

        int r = upper_bound(f + 1, f + 1 + n * 2, flag(f[i].pos + d - 1)) - f - 1;

        if (l < i) link(1, n * 2, 1, l, i - 1, f[i].idx);

        if (i < r) link(1, n * 2, 1, i + 1, r, f[i].idx);

    }



    for (int i = 1; i <= n * 2; i++)

        if (!dfn[i]) tarjan(i);

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

        if (cmp[i] == cmp[i + n]) return 0;

    return 1;

}

#undef CLR



signed main() {

    scanf("%d", &n);

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

        scanf("%d%d", &f[i].pos, &f[i + n].pos);

        f[i].idx = i, f[i + n].idx = i + n;

    }

    sort(f + 1, f + 1 + n * 2);



    int lb = 0, ub = f[n * 2].pos - f[1].pos + 1, ans = 0;

    while (lb <= ub) {

        int mid = (lb + ub) >> 1;

        if (judge(mid)) ans = mid, lb = mid + 1;

        else ub = mid - 1;

    }



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

    return 0;

}

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

using namespace std;



typedef long long ll;

typedef pair<int, int> pii;

typedef pair<int, pii> pipii;

typedef pair<pii, int> piipi;

typedef pair<pii, pii> piipii;



#define mp make_pair

#define fi first

#define se second

#define all(a) (a).begin(), (a).end()

#define sz(a) (int)(a).size()

#define eb emplace_back



int x[10005], y[10005];

pii a[20005];



struct twosat{

    int n;

    vector<vector<int> > adj, radj, scc;

    vector<int> sid, vis;

    stack<int> st;

    int cnt;



    void init(int m){

        n = m;

        adj.clear();

        radj.clear();

        sid.clear();

        vis.clear();

        scc.clear();



        adj.resize(m);

        radj.resize(m);

        sid.resize(m);

        vis.resize(m);

    }



    void impl(int x, int y){

        adj[x].push_back(y);

        radj[y].push_back(x);

    }

    void vee(int x, int y){

        impl(x^1, y);

        impl(y^1, x);

    }

    void nand(int x, int y){

        vee(x^1, y^1);

    }

    void xoro(int x, int y){

        vee(x, y);

        vee(x^1, y^1);

    }



    void dfs1(int x){

        if(vis[x]++) return;

        for(int i=0;i<adj[x].size();i++) dfs1(adj[x][i]);

        st.push(x);

    }

    void dfs2(int x){

        if(!vis[x]) return;

        vis[x] = 0;

        sid[x] = cnt;

        scc.back().push_back(x);

        for(int i=0;i<radj[x].size();i++) dfs2(radj[x][i]);

    }

    bool two_sat(){

        cnt = 0;

        for(int i=0;i<n;i++) dfs1(i);

        while(!st.empty()){

            int v = st.top();

            st.pop();

            if(vis[v]){

                scc.push_back(vector<int>());

                dfs2(v);

                cnt++;

            }

        }

        for(int i=0;i<n;i+=2){

            if(sid[i] == sid[i+1]) return false;

        }

        return true;

    }

};



twosat sat;



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

    if(s == e) return;

    else{

        int mid = (s+e)/2;

        build(n+n, s, mid);

        build(n+n+1, mid+1, e);



        sat.impl((n+n)*2, n*2);

        sat.impl((n+n+1)*2, n*2);

    }

}

void query(int n, int s, int e, int l, int r, vector<int> &Q){

    if(s > r || l > e) return;

    if(l <= s && e <= r){

        Q.eb(n);

        return;

    }

    int mid = (s+e)/2;

    query(n+n, s, mid, l, r, Q);

    query(n+n+1, mid+1, e, l, r, Q);

}

int idx[10005][2];

int main(){

    int n;

    scanf("%d", &n);

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

        scanf("%d%d", &x[i], &y[i]);

        a[i] = mp(x[i], i);

        a[i+n] = mp(y[i], i);

    }

    sort(a+1, a+2*n+1);

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

        if(idx[a[i].se][0] == 0) idx[a[i].se][0] = i;

        else idx[a[i].se][1] = i;

    }



    int lo = 1, hi = 1e9, ans = 0;

    while(lo <= hi){

        int mid = (lo+hi)/2;



        sat.init(16*n+2);

        build(1, 1, 2*n);



        int l = 1, r = 1;

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

            l = min(l, i);

            r = max(r, i);

            while(a[i].fi-a[l].fi >= mid) l++;

            while(r+1 <= 2*n && a[r+1].fi-a[i].fi < mid) r++;

            vector<int> Q1, Q2, Q3;



            query(1, 1, 2*n, i, i, Q1);

            if(i != l) query(1, 1, 2*n, l, i-1, Q2);

            if(i != r) query(1, 1, 2*n, i+1, r, Q3);



            for(int i=0;i<sz(Q2);i++){

                int x = Q2[i]*2, y = Q1[0]*2;

                sat.nand(x, y);

            }

            for(int i=0;i<sz(Q3);i++){

                int x = Q3[i]*2, y = Q1[0]*2;

                sat.nand(x, y);

            }

        }

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

            int x = idx[i][0], y = idx[i][1];

            vector<int> Q1, Q2;

            query(1, 1, 2*n, x, x, Q1);

            query(1, 1, 2*n, y, y, Q2);

            sat.xoro(Q1[0]*2, Q2[0]*2);

        }

        int ok = sat.two_sat();

        if(ok == 1) ans = mid, lo = mid+1;

        else hi = mid-1;

    }

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

}