#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const long long INFL = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-9;
const int DX[] = {1, 0, -1, 0}, DY[] = {0, -1, 0, 1};
vector<pair<long long, int>> x_and_idx, y_and_idx;
struct UnionFind {
  vector<long long> data;
  UnionFind(long long size) : data(size, -1) {}
  bool unionSet(long long x, long long y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(long long x, long long y) { return root(x) == root(y); }
  long long root(long long x) {
    return data[x] < 0 ? x : data[x] = root(data[x]);
  }
  long long size(long long x) { return -data[root(x)]; }
};
void solve(long long N, std::vector<long long> x, std::vector<long long> y) {
  for (int i = 0; i < (N); i++) {
    x_and_idx.push_back(make_pair(x[i], i));
    y_and_idx.push_back(make_pair(y[i], i));
  }
  UnionFind uf(N);
  sort((x_and_idx).begin(), (x_and_idx).end());
  sort((y_and_idx).begin(), (y_and_idx).end());
  vector<pair<long long, pair<int, int>>> memo;
  for (int i = 0; i < (N); i++) {
    long long now = x_and_idx[i].first;
    for (int cnt = 1; cnt < (20); cnt++) {
      if (N <= cnt + i || now == x_and_idx[i + cnt].first) break;
      memo.push_back(
          make_pair(abs(x[x_and_idx[i].second] - x[x_and_idx[i + cnt].second]),
                    make_pair(x_and_idx[i].second, x_and_idx[i + cnt].second)));
    }
    if (i + 1 != N && x_and_idx[i].first == x_and_idx[i + 1].first) {
      uf.unionSet(x_and_idx[i].second, x_and_idx[i + 1].second);
    }
    for (int i = 0; i < (N); i++) {
      long long now = y_and_idx[i].first;
      for (int cnt = 1; cnt < (20); cnt++) {
        if (N <= cnt + i || now == y_and_idx[i + cnt].first) break;
        memo.push_back(make_pair(
            abs(y[y_and_idx[i].second] - y[y_and_idx[i + cnt].second]),
            make_pair(y_and_idx[i].second, y_and_idx[i + cnt].second)));
      }
    }
    if (i + 1 != N && y_and_idx[i].first == y_and_idx[i + 1].first) {
      uf.unionSet(y_and_idx[i].second, y_and_idx[i + 1].second);
    }
  }
  sort((memo).begin(), (memo).end());
  long long ans = 0;
  for (int i = 0; i < (memo.size()); i++) {
    if (uf.size(0) == N) break;
    pair<long long, pair<int, int>> now = memo[i];
    if (uf.findSet(now.second.first, now.second.second)) continue;
    ans += now.first;
    uf.unionSet(now.second.first, now.second.second);
  }
  cout << ans << endl;
}
int main() {
  long long N;
  scanf("%lld", &N);
  std::vector<long long> x(N);
  std::vector<long long> y(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &x[i]);
    scanf("%lld", &y[i]);
  }
  solve(N, std::move(x), std::move(y));
  return 0;
}
