// Original C++ solution (slower):
//#define _GLIBCXX_DEBUG



#include<bits/stdc++.h>

using namespace std;



#define endl '\n'

#define lfs cout<<fixed<<setprecision(10)

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

#define ALLR(a)  (a).rbegin(),(a).rend()

#define spa << " " <<

#define fi first

#define se second

#define MP make_pair

#define MT make_tuple

#define PB push_back

#define EB emplace_back

#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)

#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)

using ll = long long;

using ld = long double;

const ll MOD1 = 1e9+7;

const ll MOD9 = 998244353;

const ll INF = 1e18;

using P = pair<ll, ll>;

template<typename T1, typename T2>

bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}

template<typename T1, typename T2>

bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}

ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}

void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}

void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}

void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}

template<typename T1,typename T2>

void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  

template<typename T>

void debug(vector<vector<T>>&v,ll h,ll w){for(ll i=0;i<h;i++)

{cout<<v[i][0];for(ll j=1;j<w;j++)cout spa v[i][j];cout<<endl;}};

void debug(vector<string>&v,ll h,ll w){for(ll i=0;i<h;i++)

{for(ll j=0;j<w;j++)cout<<v[i][j];cout<<endl;}};

template<typename T>

void debug(vector<T>&v,ll n){if(n!=0)cout<<v[0];

for(ll i=1;i<n;i++)cout spa v[i];cout<<endl;};

template<typename T>

vector<vector<T>>vec(ll x, ll y, T w){

  vector<vector<T>>v(x,vector<T>(y,w));return v;}

ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}

vector<ll>dx={1,-1,0,0,1,1,-1,-1};

vector<ll>dy={0,0,1,-1,1,-1,1,-1};

template<typename T>

vector<T> make_v(size_t a,T b){return vector<T>(a,b);}

template<typename... Ts>

auto make_v(size_t a,Ts... ts){

  return vector<decltype(make_v(ts...))>(a,make_v(ts...));

}

template<typename T1, typename T2>

ostream &operator<<(ostream &os, const pair<T1, T2>&p){

  return os << p.first << " " << p.second;

}

//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());

struct edge {

  ll to,cost;

  edge(ll x,ll y):to(x),cost(y){};

};

struct RangeGraph{

  vector<vector<edge>>g;

  ll n,sz;

  ll cnt;

  RangeGraph(ll n,ll m):n(n){

    sz=1;

    cnt=0;

    while(sz<n)sz <<= 1;

    g.assign(3*sz+m,vector<edge>());

    for(ll i=1;i<sz;i++){

      g[i].EB(2*i,0);

      g[i].EB(2*i+1,0);

      if(2*i<sz){

        g[2*i+2*sz].EB(i+2*sz,0);

        g[2*i+1+2*sz].EB(i+2*sz,0);

      }

      else{

        g[2*i].EB(i+2*sz,0);

        g[2*i+1].EB(i+2*sz,0);

      }

    }

  }

  void add_edge(ll l1,ll r1,ll l2,ll r2,ll w){//[l1,r1)->[l2,r2)

    if(l1>=r1||l2>=r2)return;

    auto v=range(l1,r1);

    ll via=3*sz+cnt;

    for(auto z:v){

      if(z<sz)g[z+2*sz].EB(via,w);

      else g[z].EB(via,w);

    }

    v=range(l2,r2);

    for(auto z:v)g[via].EB(z,0);

    cnt++;

  }

  vector<ll>range(ll l,ll r){

    vector<ll>ret;

    l+=sz,r+=sz;

    while(l!=r){

      if(l&1)ret.PB(l++);

      if(r&1)ret.PB(--r);

      l>>=1,r>>=1;

    }

    return ret;

  };

  ll add(){

    return sz;

  }

};



struct SCC{

  ll n;

  vector<vector<struct edge>>G,Gr;

  vector<ll>index;//各ノードが属する強連結成分の番号

  vector<ll>ret;//dfsに使う

  SCC(vector<vector<struct edge>>g):G(g),n(g.size()){

    index.assign(n,-1LL);

    build();

  }

  void build(){

    Gr.assign(n,vector<struct edge>());

    for(ll i=0;i<n;i++){

      for(ll j=0;j<G[i].size();j++){

        Gr[G[i][j].to].emplace_back(i,G[i][j].cost);

      }

    }

    for(ll i=0;i<n;i++)if(index[i]==-1)dfs1(i);

    fill(ALL(index),-1);

    ll cnt=0;

    reverse(ALL(ret));

    for(ll i=0;i<n;i++){

      if(index[ret[i]]==-1){

        dfs2(ret[i],cnt);

        cnt++;

      }

    }

  }

  void dfs1(ll k){

    index[k]=1;

    for(ll i=0;i<G[k].size();i++){

      if(index[G[k][i].to]==-1)dfs1(G[k][i].to);

    }

    ret.push_back(k);

  }

  void dfs2(ll k, ll idx){

    index[k]=idx;

    for(ll i=0;i<Gr[k].size();i++){

      if(index[Gr[k][i].to]==-1)dfs2(Gr[k][i].to,idx);

    }

  }

  vector<ll>output(){return index;};

};



int main(){

  cin.tie(nullptr);

  ios_base::sync_with_stdio(false);

  ll res=0,buf=0;

  bool judge = true;

  ll n;cin>>n;

  vector<ll>x(n),y(n);

  rep(i,0,n)cin>>x[i]>>y[i];

  vector<P>v;

  rep(i,0,n)v.EB(x[i],i),v.EB(y[i],i);

  sort(ALL(v));

  vector<vector<ll>>t(n);

  rep(i,0,2*n)t[v[i].se].PB(i);

  ll ok=0,ng=(ll)1e9;

  //debug(v,2*n);

  //debug(t,n,2);

  while(abs(ok-ng)>=2){

    ll mid=(ok+ng)/2;

    RangeGraph rg(4*n,4*n);

    rep(i,0,2*n){

      ll idx=lower_bound(ALL(v),MP(v[i].fi+mid,-1LL))-v.begin();

      rg.add_edge(i,i+1,2*n+i+1,2*n+idx,0);

      rg.add_edge(i+1,idx,i+2*n,i+1+2*n,0);

    }

    ll add=rg.add();

    rep(i,0,n){

      rg.g[t[i][1]+2*n+add].EB(t[i][0]+add,0);

      rg.g[t[i][0]+2*n+add].EB(t[i][1]+add,0);

    }

    SCC scc(rg.g);

    bool sw=true;

    rep(i,0,2*n){

      if(scc.index[i+add]==scc.index[i+2*n+add]){

        sw=false;

      }

    }

    if(sw)ok=mid;

    else ng=mid;

  }

  cout<<ok<<endl;

  return 0;

}

// Optimized solution to the same problem (faster):
//#define _GLIBCXX_DEBUG



#include<bits/stdc++.h>

using namespace std;



#define endl '\n'

#define lfs cout<<fixed<<setprecision(10)

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

#define ALLR(a)  (a).rbegin(),(a).rend()

#define spa << " " <<

#define fi first

#define se second

#define MP make_pair

#define MT make_tuple

#define PB push_back

#define EB emplace_back

#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)

#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)

using ll = int;

using ld = long double;

const ll MOD1 = 1e9+7;

const ll MOD9 = 998244353;

const ll INF = 1e9;

using P = pair<ll, ll>;

template<typename T1, typename T2>

bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}

template<typename T1, typename T2>

bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}

ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}

void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}

void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}

void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}

template<typename T1,typename T2>

void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  

template<typename T>

void debug(vector<vector<T>>&v,ll h,ll w){for(ll i=0;i<h;i++)

{cout<<v[i][0];for(ll j=1;j<w;j++)cout spa v[i][j];cout<<endl;}};

void debug(vector<string>&v,ll h,ll w){for(ll i=0;i<h;i++)

{for(ll j=0;j<w;j++)cout<<v[i][j];cout<<endl;}};

template<typename T>

void debug(vector<T>&v,ll n){if(n!=0)cout<<v[0];

for(ll i=1;i<n;i++)cout spa v[i];cout<<endl;};

template<typename T>

vector<vector<T>>vec(ll x, ll y, T w){

  vector<vector<T>>v(x,vector<T>(y,w));return v;}

ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}

vector<ll>dx={1,-1,0,0,1,1,-1,-1};

vector<ll>dy={0,0,1,-1,1,-1,1,-1};

template<typename T>

vector<T> make_v(size_t a,T b){return vector<T>(a,b);}

template<typename... Ts>

auto make_v(size_t a,Ts... ts){

  return vector<decltype(make_v(ts...))>(a,make_v(ts...));

}

template<typename T1, typename T2>

ostream &operator<<(ostream &os, const pair<T1, T2>&p){

  return os << p.first << " " << p.second;

}

//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());

struct RangeGraph{

  vector<vector<ll>>g;

  ll n,sz;

  ll cnt;

  RangeGraph(ll n,ll m):n(n){

    sz=1;

    cnt=0;

    while(sz<n)sz <<= 1;

    g.assign(3*sz+m,vector<ll>());

    for(ll i=1;i<sz;i++){

      g[i].EB(2*i);

      g[i].EB(2*i+1);

      if(2*i<sz){

        g[2*i+2*sz].EB(i+2*sz);

        g[2*i+1+2*sz].EB(i+2*sz);

      }

      else{

        g[2*i].EB(i+2*sz);

        g[2*i+1].EB(i+2*sz);

      }

    }

  }

  void add_edge(ll l1,ll r1,ll l2,ll r2){//[l1,r1)->[l2,r2)

    if(l1>=r1||l2>=r2)return;

    if(l1+1==r1&&l2+1==r2){

      g[l1+sz].EB(l2+sz);

    }

    else if(l1+1==r1){

      auto v=range(l2,r2);

      v=range(l2,r2);

      for(auto z:v)g[l1+sz].EB(z);

    }

    else if(l2+1==r2){

      auto v=range(l1,r1);

      for(auto z:v){

        if(z<sz)g[z+2*sz].EB(l2+sz);

        else g[z].EB(l2+sz);

      }

    }

    else{

      auto v=range(l1,r1);

      ll via=3*sz+cnt;

      for(auto z:v){

        if(z<sz)g[z+2*sz].EB(via);

        else g[z].EB(via);

      }

      v=range(l2,r2);

      for(auto z:v)g[via].EB(z);

      cnt++;

    }

  }

  vector<ll>range(ll l,ll r){

    vector<ll>ret;

    l+=sz,r+=sz;

    while(l!=r){

      if(l&1)ret.PB(l++);

      if(r&1)ret.PB(--r);

      l>>=1,r>>=1;

    }

    return ret;

  };

  ll add(){

    return sz;

  }

};



struct SCC{

  ll n;

  vector<vector<ll>>G,Gr;

  vector<ll>index;//各ノードが属する強連結成分の番号

  vector<ll>ret;//dfsに使う

  SCC(vector<vector<ll>>g):G(g),n(g.size()){

    index.assign(n,-1LL);

    build();

  }

  void build(){

    Gr.assign(n,vector<ll>());

    for(ll i=0;i<n;i++){

      for(ll j=0;j<G[i].size();j++){

        Gr[G[i][j]].push_back(i);

      }

    }

    for(ll i=0;i<n;i++)if(index[i]==-1)dfs1(i);

    fill(ALL(index),-1);

    ll cnt=0;

    reverse(ALL(ret));

    for(ll i=0;i<n;i++){

      if(index[ret[i]]==-1){

        dfs2(ret[i],cnt);

        cnt++;

      }

    }

  }

  void dfs1(ll k){

    index[k]=1;

    for(ll i=0;i<G[k].size();i++){

      if(index[G[k][i]]==-1)dfs1(G[k][i]);

    }

    ret.push_back(k);

  }

  void dfs2(ll k, ll idx){

    index[k]=idx;

    for(ll i=0;i<Gr[k].size();i++){

      if(index[Gr[k][i]]==-1)dfs2(Gr[k][i],idx);

    }

  }

  vector<vector<ll>>edges;

  void build_edges(){

    edges.assign(*max_element(ALL(index))+1,vector<ll>());

    for(ll i=0;i<n;i++){

      for(ll j=0;j<G[i].size();j++){

        if(index[i]!=index[G[i][j]]){

          edges[index[i]].push_back(index[G[i][j]]);

        }

      }

    }

  }

  vector<ll>output(){return index;};

};



int main(){

  cin.tie(nullptr);

  ios_base::sync_with_stdio(false);

  ll res=0,buf=0;

  bool judge = true;

  ll n;cin>>n;

  vector<ll>x(n),y(n);

  rep(i,0,n)cin>>x[i]>>y[i];

  vector<P>v;

  rep(i,0,n)v.EB(x[i],i),v.EB(y[i],i);

  sort(ALL(v));

  vector<vector<ll>>t(n);

  rep(i,0,2*n)t[v[i].se].PB(i);

  ll ok=0,ng=(ll)1e9;

  //debug(v,2*n);

  //debug(t,n,2);

  while(abs(ok-ng)>=2){

    ll mid=(ok+ng)/2;

    RangeGraph rg(4*n,0);

    rep(i,0,2*n){

      ll idx=lower_bound(ALL(v),MP(v[i].fi+mid,-1))-v.begin();

      rg.add_edge(i,i+1,2*n+i+1,2*n+idx);

      rg.add_edge(i+1,idx,i+2*n,i+1+2*n);

    }

    ll add=rg.add();

    rep(i,0,n){

      rg.g[t[i][1]+2*n+add].EB(t[i][0]+add);

      rg.g[t[i][0]+2*n+add].EB(t[i][1]+add);

    }

    SCC scc(rg.g);

    bool sw=true;

    rep(i,0,2*n){

      if(scc.index[i+add]==scc.index[i+2*n+add]){

        sw=false;

      }

    }

    if(sw)ok=mid;

    else ng=mid;

  }

  cout<<ok<<endl;

  return 0;

}


// Fastest known solution for this problem: