#include <bits/stdc++.h>
using namespace std;
struct edge {
  int from, to, cost;
};
bool comp(edge e1, edge e2) { return e1.cost < e2.cost; }
int p[100001];
int r[100001];
void init(int n) {
  for (int i = 0; i < n; i++) {
    p[i] = i;
    r[i] = 0;
  }
}
int find(int n) {
  if (p[n] == n) return n;
  p[n] = find(p[n]);
  return p[n];
}
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y) return;
  if (r[x] < r[y])
    p[x] = y;
  else {
    p[y] = x;
    if (r[x] == r[y]) r[x]++;
  }
}
bool same(int x, int y) { return (find(x) == find(y)); }
int main() {
  int n;
  cin >> n;
  map<int, vector<int>> mx, my;
  vector<int> xs, ys;
  int xt[n], yt[n];
  for (int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    xt[i] = x;
    yt[i] = y;
    mx[x].push_back(i);
    my[y].push_back(i);
  }
  for (auto it = mx.begin(); it != mx.end(); ++it) {
    xs.push_back(it->first);
  }
  for (auto it = my.begin(); it != my.end(); ++it) {
    ys.push_back(it->first);
  }
  vector<edge> G;
  for (int i = 0; i < xs.size() - 1; i++) {
    for (int xc : mx[xs[i]]) {
      for (int xd : mx[xs[i + 1]]) {
        G.push_back({xc, xd, xs[i + 1] - xs[i]});
        G.push_back({xd, xc, xs[i + 1] - xs[i]});
      }
    }
  }
  for (int i = 0; i < ys.size() - 1; i++) {
    for (int xc : my[ys[i]]) {
      for (int xd : my[ys[i + 1]]) {
        G.push_back({xc, xd, ys[i + 1] - ys[i]});
        G.push_back({xd, xc, ys[i + 1] - ys[i]});
      }
    }
  }
  sort(G.begin(), G.end(), comp);
  init(n);
  long long int res = 0;
  for (int i = 0; i < xs.size(); i++) {
    for (int xc : mx[xs[i]]) {
      unite(xc, mx[xs[i]][0]);
    }
  }
  for (int i = 0; i < ys.size(); i++) {
    for (int xc : mx[ys[i]]) {
      unite(xc, mx[ys[i]][0]);
    }
  }
  for (int i = 0; i < G.size(); i++) {
    edge e = G[i];
    if (!same(e.from, e.to)) {
      res += e.cost;
      unite(e.from, e.to);
    }
  }
  cout << res << endl;
  return 0;
}
