#include <bits/stdc++.h>
using namespace std;
static const int MAX_N = 100000;
static const long long int INF = 1LL << 60;
struct edge {
  int to;
  long long int cost;
};
int N;
int x[MAX_N], y[MAX_N];
pair<int, int> s1[MAX_N], s2[MAX_N];
vector<edge> G[MAX_N];
long long int mincost[MAX_N];
bool used[MAX_N];
long long int prim() {
  fill(mincost, mincost + N, INF);
  fill(used, used + N, false);
  mincost[0] = 0;
  long long int res = 0;
  for (;;) {
    int v = -1;
    for (int u = 0; u < N; u++) {
      if (!used[u] && (v == -1 || mincost[u] < mincost[v])) v = u;
    }
    if (v == -1) break;
    used[v] = true;
    res += mincost[v];
    for (int i = 0; i < G[v].size(); i++) {
      mincost[G[v][i].to] = min(mincost[G[v][i].to], G[v][i].cost);
    }
  }
  return res;
}
int main() {
  cin >> N;
  for (int i = 0; i < N; i++) {
    cin >> x[i] >> y[i];
  }
  for (int i = 0; i < N; i++) {
    s1[i].first = x[i];
    s1[i].second = i;
    s2[i].first = y[i];
    s2[i].second = i;
  }
  sort(s1, s1 + N);
  sort(s2, s2 + N);
  for (int i = 0; i < N - 1; i++) {
    G[s1[i].second].push_back(
        (edge){s1[i + 1].second, abs(s1[i].first - s1[i + 1].first)});
    G[s1[i + 1].second].push_back(
        (edge){s1[i].second, abs(s1[i].first - s1[i + 1].first)});
    G[s2[i].second].push_back(
        (edge){s2[i + 1].second, abs(s2[i].first - s2[i + 1].first)});
    G[s2[i + 1].second].push_back(
        (edge){s2[i].second, abs(s2[i].first - s2[i + 1].first)});
  }
  cout << prim() << endl;
  return 0;
}
