#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
const long long INF = 1e+14;
const long double eps = 1e-8;
const long double pi = acos(-1.0);
void Yes() {
  cout << "Yes" << endl;
  exit(0);
}
void No() {
  cout << "No" << endl;
  exit(0);
}
struct edge {
  int to;
  long long cost;
};
int N;
long long x[100100], y[100100];
pair<long long, long long> xy[100100], yx[100100];
long long mincost[100100];
bool used[100100];
vector<edge> G[100100];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> N;
  map<pair<long long, long long>, int> mpx, mpy;
  for (int i = 0; i < N; i++) {
    cin >> x[i] >> y[i];
    xy[i] = make_pair(x[i], y[i]);
    yx[i] = make_pair(y[i], x[i]);
    mpx[xy[i]] = i;
    mpy[yx[i]] = i;
  }
  sort(xy, xy + N);
  sort(yx, yx + N);
  for (int i = 0; i < N - 1; i++) {
    G[mpx[xy[i]]].push_back(
        edge{mpx[xy[i + 1]], abs(xy[i].first - xy[i + 1].first)});
    G[mpx[xy[i + 1]]].push_back(
        edge{mpx[xy[i]], abs(xy[i].first - xy[i + 1].first)});
    G[mpy[yx[i]]].push_back(
        edge{mpy[yx[i + 1]], abs(yx[i].first - yx[i + 1].first)});
    G[mpy[yx[i + 1]]].push_back(
        edge{mpy[yx[i]], abs(yx[i].first - yx[i + 1].first)});
  }
  priority_queue<pair<long long, long long>, vector<pair<long long, long long>>,
                 greater<pair<long long, long long>>>
      pque;
  fill(mincost, mincost + N, INF);
  fill(used, used + N, false);
  mincost[0] = 0;
  pque.push(pair<long long, long long>(0, 0));
  long long ans = 0;
  while (pque.size()) {
    pair<long long, long long> p = pque.top();
    pque.pop();
    int v = p.second;
    if (used[v] == true) continue;
    used[v] = true;
    ans += p.first;
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (mincost[e.to] > e.cost) {
        mincost[e.to] = e.cost;
        pque.push(pair<long long, long long>(mincost[e.to], e.to));
      }
    }
  }
  cout << ans << endl;
  return 0;
}
