#include <bits/stdc++.h>
#define SZ(x) ((int) (x).size())
using namespace std;

typedef long long i64;

const int NMAX = 40005;

vector<int> G[NMAX], Gt[NMAX];

struct Point {
    int pos, ind, node;
    Point() = default;
    Point(int _pos, int _ind, int _node = -1):
        pos(_pos), ind(_ind), node(_node) {}
    bool operator<(const Point& o) const {
        return pos < o.pos || (pos == o.pos && ind < o.ind);
    }
};

vector<Point> A;

int n;

int non(int x) {
    return x < n ? x + n : x - n;
}

void addEdge(int from, int to) {
    G[non(from)].push_back(to);
    Gt[to].push_back(non(from));
    G[non(to)].push_back(from);
    Gt[from].push_back(non(to));
}

bool used[NMAX];
int minDist;
int order[NMAX], orderInd;

multiset<Point> var, negVar;


void dfs1(int node) {
    used[node] = true;
    for (int to: G[node]) {
        if (!used[to]) {
            dfs1(to);
        }
    }
    multiset<Point>& adj = negVar;
    if (node < n) {
        while (true) {
            auto it = adj.upper_bound(A[node]);
            if (it == adj.end() || it->pos - A[node].pos >= minDist) {
                break;
            }
            int to = it->node;
            adj.erase(it);
            if (!used[to + n]) {
                dfs1(to + n);
            }
        }
        while (true) {
            auto it = adj.lower_bound(A[node]);
            if (it == adj.begin()) {
                break;
            }
            --it;
            if (A[node].pos - it->pos >= minDist) {
                break;
            }
            int to = it->node;
            adj.erase(it);
            if (!used[to + n]) {
                dfs1(to + n);
            }
        }
    }
    order[orderInd++] = node;
}

int cc[NMAX];

void dfs2(int node, int ccc) {
    cc[node] = ccc;
    used[node] = false;
    for (int to: Gt[node]) {
        if (used[to]) {
            dfs2(to, ccc);
        }
    }
    multiset<Point>& adj = var;
    if (node >= n) {
        while (true) {
            auto it = adj.upper_bound(A[node - n]);
            if (it == adj.end() || it->pos - A[node - n].pos >= minDist) {
                break;
            }
            int to = it->node;
            adj.erase(it);
            if (used[to]) {
                dfs2(to, ccc);
            }
        }
        while (true) {
            auto it = adj.lower_bound(A[node - n]);
            if (it == adj.begin()) {
                break;
            }
            --it;
            if (A[node - n].pos - it->pos >= minDist) {
                break;
            }
            int to = it->node;
            adj.erase(it);
            if (used[to]) {
                dfs2(to, ccc);
            }
        }
    }
}

bool works(int minDist) {
    ::minDist = minDist;
    orderInd = 0;
    var = multiset<Point>(A.begin(), A.end());
    negVar = multiset<Point>(A.begin(), A.end());
    fill(used, used + 2 * n, false);
    for (int i = 0; i < 2 * n; ++i) {
        if (!used[i]) {
            dfs1(i);
        }
    }
    int ccc = 0;
    for (int i = 2 * n - 1; i >= 0; --i) {
        int node = order[i];
        if (used[node]) {
            dfs2(node, ccc++);
        }
    }
    for (int i = 0; i < n; ++i) {
        if (cc[i] == cc[i + n]) {
            return false;
        }
    }
    return true;
}

int main() {
    #ifdef LOCAL_RUN
    freopen("task.in", "r", stdin);
    freopen("task.out", "w", stdout);
    //freopen("task.err", "w", stderr);
    #endif // ONLINE_JUDGE
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n;

    vector<int> first(n, -1), second(n, -1);
    for (int i = 0; i < n; ++i) {
        int x, y;
        cin >> x >> y;
        A.push_back(Point(x, i));
        if (y != x) {
            A.push_back(Point(y, i));
        }
    }
    n = SZ(A);
    sort(A.begin(), A.end());
    for (int i = 0; i < n; ++i) {
        A[i].node = i;
        if (first[A[i].ind] == -1) {
            first[A[i].ind] = i;
        } else {
            second[A[i].ind] = i;
        }
    }
    for (int i = 0; i < SZ(first); ++i) {
        if (second[i] == -1) {
            second[i] = first[i];
        }
        addEdge(first[i], second[i]);
    }
    int ans = 0;
    for (int step = 1 << 29; step > 0; step /= 2) {
        if (works(ans + step)) {
            ans += step;
        }
    }
    cout << ans << '\n';
}


Measured memory_bytes: 11132