#include <bits/stdc++.h>
using namespace std;

struct Segtree {
    int n, V;

    Segtree(int n_input, vector<int> edges[]){
        n = 1;
        while(n < n_input) n <<= 1;
        V = 2*n-1;
        for(int k=0; k<n-1; k++){
            edges[k+V].push_back(2*k+1+V);
            edges[k+V].push_back(2*k+2+V);
        }
    }

    void between(int a, int b, int s, vector<int> edges[]){
        return query(a, b+1, 0, 0, n, s, edges);
    }

    void query(int a, int b, int k, int l, int r, int s, vector<int> edges[]){
        if(r<=a || b<=l) return;
        if(a<=l && r<=b){
            edges[s+n-1].push_back(k+V);
            return;
        }
        query(a, b, 2*k+1, l, (l+r)/2, s, edges);
        query(a, b, 2*k+2, (l+r)/2, r, s, edges);
    }
};

struct SCC{
    int N;
    vector<bool> used;
    vector<int> vs;
    vector<int> cmp;

    void dfs(int v, const vector<int> G[]){
        used[v] = true;
        for(auto u : G[v]){
            if(!used[u]) dfs(u, G);
        }
        vs.push_back(v);
    }

    void rdfs(int v, int k, const vector<vector<int>>& rG){
        used[v] = true;
        cmp[v] = k;
        for(auto u : rG[v]){
            if(!used[u]) rdfs(u, k, rG);
        }
    }

    void calculate(int Nin, const vector<int> G[]){
        N = Nin;
        vector<vector<int>> rG(N);
        for(int i=0; i<N; i++) for(int j : G[i]) rG[j].push_back(i);
        used.resize(N);
        fill(used.begin(), used.end(), false);
        for(int v=0; v<N; v++){
            if(!used[v]) dfs(v, G);
        }

        fill(used.begin(), used.end(), false);
        cmp.resize(N);
        int k = 0;
        for(int i = vs.size()-1; i>=0; i--){
            if(!used[vs[i]]) rdfs(vs[i], k++, rG);
        }
    }

    int dump_graph(const vector<int> G[], vector<int> edges2[]){
        for(int i=0; i<N; i++){
            for(auto j : G[i]){
                if(cmp[i] != cmp[j]){
                    edges2[cmp[i]].push_back(cmp[j]);
                }
            }
        }
        return *max_element(cmp.begin(), cmp.end()) + 1;
    }
};

int N;
vector<pair<int, int>> A;
vector<int> Z;
vector<vector<int>> P;

bool check(int X){
    vector<int> edges[140000];
    Segtree st(2*N, edges);
    int offset = st.n-1, V = st.V;
    for(int i=0; i<N; i++){
        int a = offset + P[i][0], b = offset + P[i][1];
        edges[a+V].push_back(b);
        edges[b+V].push_back(a);
    }
    for(int i=0; i<2*N; i++){
        int l = lower_bound(Z.begin(), Z.end(), Z[i]-X+1) - Z.begin();
        int r = lower_bound(Z.begin(), Z.end(), Z[i]+X) - Z.begin() - 1;
        st.between(l, i-1, i, edges);
        st.between(i+1, r, i, edges);
    }
    SCC scc;
    scc.calculate(2*V, edges);
    for(int i=0; i<V; i++) if(scc.cmp[i] == scc.cmp[i+V]) return false;
    return true;
}

int main(){
    cin >> N;
    for(int i=0; i<N; i++){
        int x, y;
        cin >> x >> y;
        A.emplace_back(x, i);
        A.emplace_back(y, i);
    }
    sort(A.begin(), A.end());
    P.resize(N);
    for(int i=0; i<2*N; i++){
        Z.push_back(A[i].first);
        P[A[i].second].push_back(i);
    }

    int ok = 0, ng = 1e9+1;
    while(ng-ok>1){
        int mid = (ok+ng)/2;
        (check(mid) ? ok : ng) = mid;
    }
    cout << ok << endl;
    return 0;
}


Measured memory_bytes: 21776