#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <unordered_map>
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
int n0, n;
int indx[10001], indy[10001];
vector<int> g[163841], gr[163841];
void add_edge(int i, int j){
  g[i].push_back(j);
  gr[j].push_back(i);
}
void init(){
  for(int i=0; i<10*n0; i++){
    g[i].clear();
    gr[i].clear();
  }
  for(int i=0; i<n0-1; i++){
    add_edge(i+2*n0, 2*i+1+2*n0);
    add_edge(i+2*n0, 2*i+2+2*n0);
    add_edge(i+4*n0, 2*i+1+4*n0);
    add_edge(i+4*n0, 2*i+2+4*n0);
    add_edge(2*i+1+6*n0, i+6*n0);
    add_edge(2*i+2+6*n0, i+6*n0);
    add_edge(2*i+1+8*n0, i+8*n0);
    add_edge(2*i+2+8*n0, i+8*n0);
  }
  for(int i=0; i<n; i++){
    add_edge(i+2*n0+n0-1, indy[i]);
    add_edge(i+4*n0+n0-1, indx[i]+n0);
    add_edge(indx[i], i+6*n0+n0-1);
    add_edge(indy[i]+n0, i+8*n0+n0-1);
  }
}
void segtree(int s, int t, int i, int a, int b, int k, int l, int r){
  if(a>=b) return;
  if(b<=l || r<=a) return;
  if(a<=l && r<=b){
    add_edge(i+n0*s, k+2*n0*t);
    return;
  }
  segtree(s, t, i, a, b, 2*k+1, l, (l+r)/2);
  segtree(s, t, i, a, b, 2*k+2, (l+r)/2, r);
}
void segtree2(int s, int t, int i, int a, int b, int k, int l, int r){
  if(a>=b) return;
  if(b<=l || r<=a) return;
  if(a<=l && r<=b){
    add_edge(k+2*n0*s, i+n0*t);
    return;
  }
  segtree2(s, t, i, a, b, 2*k+1, l, (l+r)/2);
  segtree2(s, t, i, a, b, 2*k+2, (l+r)/2, r);
}
bool used[163841];
int cmp[163841];
vector<int> vs;
 
void dfs(int x){
	used[x]=1;
	for(auto y:g[x]){
		if(!used[y]) dfs(y);
	}
	vs.push_back(x);
}
 
void rdfs(int v, int k){
	used[v]=1;
	cmp[v]=k;
	for(auto y:gr[v]){
		if(!used[y]) rdfs(y, k);
	}
}
 
int scc(){
	fill(used, used+10*n0, 0);
	vs.clear();
	for(int i=0; i<10*n0; i++){
		if(!used[i]) dfs(i);
	}
	fill(used, used+10*n0, 0);
	int k=0;
	for(int i=vs.size()-1; i>=0; i--){
		if(!used[vs[i]]) rdfs(vs[i], k++);
	}
	return k;
}

int main()
{
	cin>>n;
  n0=1;
  while(n0<n) n0*=2;
  int x[10000], y[10000];
  P px[10000], py[10000];
  for(int i=0; i<n; i++){
    cin>>x[i]>>y[i];
    px[i]=P(x[i], i);
    py[i]=P(y[i], i);
  }
  sort(px, px+n);
  sort(py, py+n);
  for(int i=0; i<n; i++) indx[i]=px[i].second, indy[i]=py[i].second;
  int d1=0, d2=1e9;
  while(d1!=d2){
    int d=(d1+d2+1)/2;
    init();
    for(int i=0; i<n; i++){
      int i1=upper_bound(px, px+n, P(px[i].first-d, 1e5))-px;
      segtree(0, 2, indx[i], i1, i, 0, 0, n0);
      int i2=lower_bound(px, px+n, P(px[i].first+d, -1))-px;
      segtree(0, 2, indx[i], i+1, i2, 0, 0, n0);
      int i3=upper_bound(py, py+n, P(px[i].first-d, 1e5))-py;
      int i4=lower_bound(py, py+n, P(px[i].first+d, -1))-py;
      segtree2(4, 1, indx[i], i3, i4, 0, 0, n0);
    }
    for(int i=0; i<n; i++){
      int i1=upper_bound(py, py+n, P(py[i].first-d, 1e5))-py;
      segtree(1, 1, indy[i], i1, i, 0, 0, n0);
      int i2=lower_bound(py, py+n, P(py[i].first+d, -1))-py;
      segtree(1, 1, indy[i], i+1, i2, 0, 0, n0);
      int i3=upper_bound(px, px+n, P(py[i].first-d, 1e5))-px;
      int i4=lower_bound(px, px+n, P(py[i].first+d, -1))-px;
      segtree2(3, 0, indy[i], i3, i4, 0, 0, n0);
    }
    scc();
    bool nuee=0;
    for(int i=0; i<n; i++){
      if(cmp[i]==cmp[i+n0]){
        nuee=1;
        break;
      }
    }
    if(nuee) d2=d-1;
    else d1=d;
  }
  cout<<d1<<endl;
	return 0;
}

Measured memory_bytes: 36212