#include <bits/stdc++.h>
long long mod = 1e9 + 7;
int spf[100001];
using namespace std;
void primeFactors(long long n, vector<long long> &vec) {
  while (n % 2 == 0) {
    vec.push_back(2);
    n = n / 2;
  }
  for (long long i = 3; i <= sqrt(n); i = i + 2) {
    while (n % i == 0) {
      vec.push_back(i);
      n = n / i;
    }
  }
  if (n > 2) {
    vec.push_back(n);
  }
}
long long gcd(long long a, long long b) {
  if (b == 0) {
    return a;
  } else {
    return gcd(b, a % b);
  }
}
long long Lcm(long long a, long long b) { return ((a * b) / gcd(a, b)); }
tuple<long long, long long, long long> getL(complex<long double> p1,
                                            complex<long double> p2) {
  long long a, b, c;
  a = p2.imag() - p1.imag();
  b = p1.real() - p2.real();
  c = -a * p1.real() - b * p1.imag();
  long long gcdres = abs(gcd(a, gcd(b, c)));
  if (a < 0 || a == 0 && b < 0) {
    gcdres *= -1;
  }
  a /= gcdres;
  b /= gcdres;
  c /= gcdres;
  return tuple<long long, long long, long long>(a, b, c);
}
long long fastpow(long long base, long long pow) {
  if (!base) return 0;
  if (!pow) return 1;
  if (pow == 1) return base;
  long long x = fastpow(base, pow / 2) % mod;
  x *= x;
  x %= mod;
  if (pow % 2) x *= base;
  return x % mod;
}
long long inverse(long long x) { return fastpow(x, mod - 2) % mod; }
long double disty(pair<double, double> a, pair<double, double> b) {
  return sqrt(pow(b.second - a.second, 2.0) + pow(b.first - a.first, 2.0));
}
void factorize(long long x, set<long long> &ss) {
  while (x % 2 == 0) ss.insert(2), x /= 2;
  for (int i = 3; i <= sqrt(x); i += 2)
    while (x % i == 0) ss.insert(i), x /= i;
  if (x > 2) ss.insert(x);
}
void SieveOfEratosthenes(long long n, bool prime[]) {
  for (int p = 2; p * p <= n; p++) {
    if (prime[p] == true) {
      for (int i = p * p; i <= n; i += p) prime[i] = false;
    }
  }
}
void divisors(long long n, vector<long long> &vec) {
  for (long long i = 2; i <= sqrt(n); ++i) {
    if (n % i == 0 && i != sqrt(n)) {
      vec.push_back(i);
      vec.push_back(n / i);
    } else if (n % i == 0) {
      vec.push_back(i);
    }
  }
}
bool isprime(long long n) {
  if (n == 1) {
    return false;
  }
  for (int i = 2; i <= sqrt(n); ++i) {
    if (n % i == 0) {
      return false;
    }
  }
  return true;
}
complex<long double> rot(complex<long double> p, long double angle) {
  return (p * polar((long double)1.0, angle));
}
complex<long double> rotA(complex<long double> p, complex<long double> A,
                          long double angle) {
  return (((p - A) * polar((long double)1, angle)) + A);
}
long double distance(complex<long double> a, complex<long double> b) {
  long double x1 = a.real(), y1 = a.imag(), x2 = b.real(), y2 = b.imag();
  return pow(y2 - y1, 2) + pow(x2 - x1, 2);
}
int distSq(pair<long long, long long> p, pair<long long, long long> q) {
  return (p.first - q.first) * (p.first - q.first) +
         (p.second - q.second) * (p.second - q.second);
}
bool isSquare(pair<long long, long long> p1, pair<long long, long long> p2,
              pair<long long, long long> p3, pair<long long, long long> p4) {
  long long d2 = distSq(p1, p2);
  long long d3 = distSq(p1, p3);
  long long d4 = distSq(p1, p4);
  if (d2 == d3 && 2 * d2 == d4 && 2 * d2 == distSq(p2, p3)) {
    int d = distSq(p2, p4);
    return (d == distSq(p3, p4) && d == d2);
  }
  if (d3 == d4 && 2 * d3 == d2 && 2 * d3 == distSq(p3, p4)) {
    int d = distSq(p2, p3);
    return (d == distSq(p2, p4) && d == d3);
  }
  if (d2 == d4 && 2 * d2 == d3 && 2 * d2 == distSq(p2, p4)) {
    int d = distSq(p2, p3);
    return (d == distSq(p3, p4) && d == d2);
  }
  return false;
}
long long FP(long long base, long long power, long long m) {
  if (power == 0) {
    return 1;
  } else if (power % 2 == 0) {
    long long res = FP(base, power / 2, m);
    return (res % m * res % m) % m;
  } else {
    long long res = FP(base, power / 2, m);
    return ((((base % m * (res % m)) % m) * (res % m) % m) % m);
  }
}
long long EGCD(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 0;
    y = 1;
    return a;
  } else {
    long long ans = EGCD(b, a % b, x, y);
    long long tmp = x;
    x = y - (a / b) * x;
    y = tmp;
    return ans;
  }
}
void sieve() {
  spf[1] = 1;
  for (int i = 2; i < 100001; i++) spf[i] = i;
  for (int i = 4; i < 100001; i += 2) spf[i] = 2;
  for (int i = 3; i * i < 100001; i++) {
    if (spf[i] == i) {
      for (int j = i * i; j < 100001; j += i)
        if (spf[j] == j) spf[j] = i;
    }
  }
}
set<int> getFactorization(int x) {
  set<int> ret;
  while (x != 1) {
    ret.insert(spf[x]);
    x = x / spf[x];
  }
  return ret;
}
void helper(int *a, int s, int e) {
  int mid = (s + e) / 2;
  int i = s;
  int j = mid + 1;
  int k = s;
  int temp[10];
  while (i <= mid && j <= e) {
    if (a[i] < a[j]) {
      temp[k++] = a[i++];
    } else {
      temp[k++] = a[j++];
    }
  }
  while (i <= mid) {
    temp[k++] = a[i++];
  }
  while (j <= e) {
    temp[k++] = a[j++];
  }
  for (int h = s; h <= e; ++h) {
    a[h] = temp[h];
  }
}
void mergesort(int *arr, int s, int e) {
  if (s >= e) {
    return;
  }
  int mid = (s + e) / 2;
  mergesort(arr, s, mid);
  mergesort(arr, mid + 1, e);
  helper(arr, s, e);
}
long long newfastpow(long long base, long long pow) {
  if (pow == 0) {
    return 1;
  } else if (pow % 2 == 0) {
    long long x = newfastpow(base, pow / 2);
    return x * x;
  } else {
    long long x = newfastpow(base, pow / 2);
    return x * x * base;
  }
}
long long fact(long long n) {
  if (n == 0) {
    return 1;
  } else {
    return n * fact(n - 1);
  }
}
int pivot(int start, int ending, int arr[], int N) {
  int mid;
  double before, after;
  while (start <= ending) {
    mid = (start + ending) / 2;
    if (mid == 0) {
      before = arr[N - 1];
    } else {
      before = arr[mid - 1];
    }
    if (mid == N - 1) {
      after = arr[0];
    } else {
      after = arr[mid + 1];
    }
    if (arr[mid] > after && arr[mid] > before) {
      break;
    } else if (after > before) {
      return pivot(mid + 1, ending, arr, N);
    } else {
      return pivot(start, mid - 1, arr, N);
    }
  }
  return arr[mid];
}
int fib(int n, int arr[]) {
  if (n <= 1) {
    return arr[n] = 1;
  }
  if (arr[n - 1] == -1) {
    arr[n - 1] = fib(n - 1, arr);
  }
  if (arr[n - 2] == -1) {
    arr[n - 2] = fib(n - 2, arr);
  }
  return arr[n - 1] + arr[n - 2];
}
long long calcdec(string s) {
  long long power = s.size() - 1;
  long long num = 0;
  for (int i = 0; i < s.size(); ++i) {
    long long val = s[i] - '0';
    if (val == 1) {
      num += (newfastpow(2, power) * val);
    }
    power--;
  }
  return num;
}
string toString(long long num) {
  string s = "";
  if (num == 0) {
    return "0";
  }
  while (num > 0) {
    char x = (num % 10) + '0';
    s = x + s;
    num /= 10;
  }
  return s;
}
long long nc;
long long rep[100000];
long long sz[100000];
long long maxx = 1;
void StartDSU(long long n) {
  for (int i = 0; i <= n; ++i) {
    rep[i] = i;
    sz[i] = 1;
  }
  nc = n;
}
long long findu(long long u) {
  if (rep[u] == u) {
    return u;
  } else {
    return rep[u] = findu(rep[u]);
  }
}
void Join(long long a, long long b) {
  a = findu(rep[a]);
  b = findu(rep[b]);
  if (a == b) {
    return;
  }
  if (sz[a] < sz[b]) {
    swap(a, b);
  }
  rep[b] = a;
  sz[a] += sz[b];
  nc -= 1;
  maxx = max(maxx, sz[a]);
}
vector<pair<long long, pair<long long, long long> > > edges;
long long kruskal(long long n) {
  long long cost = 0;
  StartDSU(n);
  for (int i = 0; i < edges.size(); ++i) {
    long long from = edges[i].second.first;
    long long to = edges[i].second.second;
    long long w = edges[i].first;
    if (findu(from) == findu(to)) {
      continue;
    } else {
      Join(from, to);
      cost += w;
    }
  }
  return cost;
}
struct wasla {
  long long fromx, fromy, tox, toy;
};
int main() {
  long long n;
  cin >> n;
  long long num = 0;
  vector<pair<long long, long long> > xx, yy;
  map<pair<long long, long long>, long long> id;
  for (int i = 0; i < n; ++i) {
    long long a, b;
    cin >> a >> b;
    pair<long long, long long> p(a, b), pp(b, a);
    xx.push_back(p);
    yy.push_back(pp);
    id[{a, b}] = num;
    num++;
  }
  sort(xx.begin(), xx.end());
  sort(yy.begin(), yy.end());
  map<long long, vector<wasla> > mp;
  map<long long, vector<wasla> >::iterator it;
  for (int i = 0; i < xx.size() - 1; ++i) {
    long long val1 = abs(xx[i].first - xx[i + 1].first);
    long long val2 = abs(yy[i].first - yy[i + 1].first);
    wasla w1, w2;
    w1.fromx = xx[i].first;
    w1.fromy = xx[i].second;
    w1.tox = xx[i + 1].first;
    w1.toy = xx[i + 1].second;
    w2.fromx = yy[i].second;
    w2.fromy = yy[i].first;
    w2.tox = yy[i + 1].second;
    w2.toy = yy[i + 1].first;
    mp[val1].push_back(w1);
    mp[val2].push_back(w2);
  }
  StartDSU(n);
  long long finalcost = 0;
  for (it = mp.begin(); it != mp.end(); ++it) {
    long long pay = it->first;
    for (int i = 0; i < mp[pay].size(); ++i) {
      pair<long long, long long> from(mp[pay][i].fromx, mp[pay][i].fromy),
          to(mp[pay][i].tox, mp[pay][i].toy);
      if (findu(id[from]) == findu(id[to])) {
        continue;
      } else {
        Join(id[from], id[to]);
        finalcost += pay;
      }
    }
  }
  cout << finalcost << "\n";
  return 0;
}
