#include <bits/stdc++.h>
using namespace std;
using VI = vector<int>;
using VVI = vector<VI>;
using VB = vector<bool>;
using VVB = vector<VB>;
using VD = vector<double>;
using VVD = vector<VD>;
using VS = vector<string>;
using PII = pair<int, int>;
using VPII = vector<PII>;
using VL = vector<long long>;
using VVL = vector<VL>;
struct DisjointSet {
  VI parent, rank;
  DisjointSet(int n) : parent(n), rank(n, 1) {
    for (int i = 0; i < n; ++i) parent[i] = i;
  }
  int find(int u) {
    if (parent[u] == u) return u;
    return parent[u] = find(parent[u]);
  }
  void merge(int u, int v) {
    u = find(u), v = find(v);
    if (u == v) return;
    if (rank[u] > rank[v]) swap(u, v);
    parent[u] = v;
    if (rank[v] == rank[u]) ++rank[v];
  }
};
int n;
VPII X, Y;
long long kruskal(vector<pair<long long, PII>>& edges) {
  long long ret = 0;
  sort(edges.begin(), edges.end());
  VB used(n, false);
  DisjointSet ds(n);
  for (int i = 0; i < (int)edges.size(); ++i) {
    long long cost = edges[i].first;
    int u = edges[i].second.first, v = edges[i].second.second;
    if (ds.find(u) == ds.find(v)) continue;
    if (used[u] == true && used[v] == true) continue;
    ds.merge(u, v);
    used[u] = used[v] = true;
    ret += cost;
  }
  return ret;
}
long long minCost() {
  sort(X.begin(), X.end());
  sort(Y.begin(), Y.end());
  vector<pair<long long, PII>> edges;
  for (int i = 1; i < n; ++i) {
    long long cost = abs(X[i - 1].first - X[i].first);
    int u = X[i - 1].second, v = X[i].second;
    edges.emplace_back(pair<long long, PII>(cost, PII(u, v)));
    cost = abs(Y[i - 1].first - Y[i].first);
    u = Y[i - 1].second, v = Y[i].second;
    edges.emplace_back(pair<long long, PII>(cost, PII(u, v)));
  }
  return kruskal(edges);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  X = Y = VPII(n);
  for (int i = 0; i < n; ++i) {
    X[i].second = Y[i].second = i;
    cin >> X[i].first >> Y[i].first;
  }
  cout << minCost() << endl;
  return 0;
}
