// Slower C++ solution:
// AT2336 Flags

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#define RI register int

using namespace std;

const int N = 4e4 + 5;

pair <int, int> e[N<<1];

int tot, scc_cnt, node_cnt, a[2][N], n, tp, sta[N<<1], low[N<<2], dfn[N<<2], scc[N<<2];

int cnt, head[N<<2], to[N<<5], nxt[N<<5];

template <class T> T Max(T a, T b) { return a > b ? a : b; }

template <class T> T Min(T a, T b) { return a < b ? a : b; }

inline int read() {

    int x = 0, f = 1; char ch;

    while(! isdigit(ch = getchar())) (ch == '-') && (f = -f);

    for(x = ch^48; isdigit(ch = getchar()); x = (x<<3) + (x<<1) + (ch^48));

    return x * f;

}

inline void add(int u, int v) {

    to[++ cnt] = v; nxt[cnt] = head[u]; head[u] = cnt;

}

struct Segment_Tree {

    struct node {

        int l, r, val;

        node *ch[2];

        node(int l, int r) : l(l), r(r) {

            val = 0;

            ch[0] = ch[1] = NULL;

        }

        inline int mid() { return (l + r) >> 1; }

    } *root;

    void build(node *&o, int l, int r) {

        o = new node(l, r);

        if(l == r) {

            o->val = e[l].second;

            return;

        }

        o->val = ++ node_cnt;

        build(o->ch[0], l, o->mid());

        build(o->ch[1], o->mid() + 1, r);

        add(o->val, o->ch[0]->val);

        add(o->val, o->ch[1]->val);

    }

    void link(node *o, int l, int r, int u) {

        if(r < l) return;

        if(l <= o->l && o->r <= r) {

            add(u, o->val);

            return;

        }

        if(l <= o->mid()) link(o->ch[0], l, r, u);

        if(r > o->mid()) link(o->ch[1], l, r, u);

    }

} tr;

inline void Tarjan(int x) {

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

    sta[++ tp] = x;

    for(RI i = head[x]; i; i = nxt[i]) {

        if(! dfn[to[i]]) {

            Tarjan(to[i]);

            low[x] = Min(low[x], low[to[i]]);

        }

        else if(scc[to[i]] == 0) {

        	low[x] = Min(low[x], dfn[to[i]]);

        }

    }

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

    	int t; scc_cnt ++;

    	do {

    		t = sta[tp --];

    		scc[t] = scc_cnt;

    	} while(t != x);

    }

}

inline bool check(int x) {

    cnt = tot = scc_cnt = tp = 0; node_cnt = 2 * n;

    memset(head, 0, sizeof(head));

    tr.build(tr.root, 1, 2 * n);

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

        for(RI k = 0; k <= 1; ++ k) {

            int l = lower_bound(e + 1, e + 2*n + 1,make_pair(a[k][i]-x+1, 0)) - e;

            int r = upper_bound(e + 1, e + 2*n + 1,make_pair(a[k][i]+x-1, 2*n+1)) - e - 1;

            int m = lower_bound(e + 1, e + 2*n + 1,make_pair(a[k][i], (k^1)*n+i)) - e;

            tr.link(tr.root, l, m - 1, k * n + i);

            tr.link(tr.root, m + 1, r, k * n + i);

        }

    }

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

    	dfn[i] = low[i] = scc[i] = 0;

    }

    for(RI i=1;i<=node_cnt;i++) {

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

    }

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

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

    }

    return 1;

}

int main() {

    cin >> n;

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

        cin >> a[0][i] >> a[1][i];

    }

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

        e[2*i - 1].first = a[0][i];

        e[2*i - 1].second = i + n;

        e[2*i].first = a[1][i];

        e[2*i].second = i;

    }

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

    int l = 0, r = 1e9;

    while(l < r) {

        int mid = (l + r + 1) >> 1;

        if(check(mid)) l = mid;

        else r = mid - 1;

    }

    cout << l << endl;

    return 0;

}

/*

3

1 3

2 5

1 9



*/

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

#define pii pair<int,int> 

#define mp make_pair

using namespace std;

const int mxn=2e4+4;

int A[mxn],B[mxn],X[mxn],n,cnt;

int ord[mxn],scc[mxn],mid;

set<pii>s;

bool used[mxn];

inline void dfs(int a,int x){

	int tx,po;

	if(a<=n)tx=X[a+n],po=a+n;

	else tx=X[a-n],po=a-n;

	used[a]=1;

	s.erase(mp(tx,po));

	for(;s.size();){

		set<pii>::iterator it=s.lower_bound(mp(x-mid+1,-1));

		if(it==s.end() or it->first>x+mid-1)break;

		int y=it->second;

		if(y==a){

			it++;

			if(it==s.end() or it->first>x+mid-1)break;

			y=it->second;

		}

		if(y>n)dfs(y-n,X[y-n]);

		else dfs(y+n,X[y+n]);

	}

	ord[++cnt]=a;

}

inline void dfs2(int a,int x){

	scc[a]=cnt;

	s.erase(mp(x,a));

	int tx;

	if(a<=n)tx=X[a+n];

	else tx=X[a-n];

	for(;s.size();){

		set<pii>::iterator it2=s.lower_bound(mp(tx-mid+1,-1));

		if(it2==s.end() or it2->first>tx+mid-1)break;

		int y=it2->second;

		if(y==a-n or y==a+n){

			it2++;

			if(it2==s.end() or it2->first>tx+mid-1)break;

			y=it2->second;

		}

		dfs2(y,X[y]);

	}

}

inline bool check(int md){

	mid=md,s.clear();

	memset(used,0,sizeof(used));

	memset(scc,0,sizeof(scc));

	for(int i=1;i<=n*2;++i)s.insert(mp(X[i],i));

	cnt=0;

	for(int i=1;i<=n*2;++i)if(!used[i])dfs(i,X[i]);

	cnt=0;

	for(int i=1;i<=n*2;++i)s.insert(mp(X[i],i));

	for(int i=n*2;i;--i){

		if(!scc[ord[i]]){

			++cnt;

			dfs2(ord[i],X[ord[i]]);

		}

	}

	for(int i=1;i<=n;++i)if(scc[i]==scc[i+n])return 0;

	return 1;

}

int main(){

	ios_base::sync_with_stdio(false);

	cin.tie(0),cout.tie(0);

	cin>>n;

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

		cin>>A[i]>>B[i];

		X[i]=A[i],X[i+n]=B[i];

	}

	int lo=0,hi=1000000009,md;

	for(;lo<hi-1;){

		int md=lo+hi>>1;

		if(check(md))lo=md;

		else hi=md; 

	}

	cout<<lo<<endl;

	return 0;

}