#include <bits/stdc++.h>
using namespace std;
using namespace std;
std::mt19937 mt((long long)time(0));
long long dx[4] = {0, 1, 0, -1};
long long dy[4] = {1, 0, -1, 0};
long long a[200001];
long long mapdata[200001];
long long ans = 0;
using Weight = long long;
using Flow = long long;
struct Edge {
  long long src, dst;
  Weight weight;
  Flow cap;
  Edge() : src(0), dst(0), weight(0) {}
  Edge(long long s, long long d, Weight w) : src(s), dst(d), weight(w) {}
};
using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;
using Array = std::vector<Weight>;
using Matrix = std::vector<Array>;
void add_edge(Graph &g, long long a, long long b, Weight w = 1) {
  g[a].emplace_back(a, b, w);
  g[b].emplace_back(b, a, w);
}
void add_arc(Graph &g, long long a, long long b, Weight w = 1) {
  g[a].emplace_back(a, b, w);
}
struct uf_tree {
  std::vector<long long> parent;
  long long __size;
  uf_tree(long long size_) : parent(size_, -1), __size(size_) {}
  void unite(long long x, long long y) {
    if ((x = find(x)) != (y = find(y))) {
      if (parent[y] < parent[x]) std::swap(x, y);
      parent[x] += parent[y];
      parent[y] = x;
      __size--;
    }
  }
  bool is_same(long long x, long long y) { return find(x) == find(y); }
  long long find(long long x) {
    return parent[x] < 0 ? x : parent[x] = find(parent[x]);
  }
  long long size(long long x) { return -parent[find(x)]; }
  long long size() { return __size; }
};
std::pair<Weight, Edges> kruskal(Graph const &g) {
  uf_tree uf(g.size());
  Edges es;
  for (auto &adj : g)
    for (auto &e : adj) es.emplace_back(e);
  std::sort(es.begin(), es.end(),
            [](const Edge &e, const Edge &f) { return e.weight < f.weight; });
  Weight total = 0;
  Edges T;
  for (auto &e : es)
    if (!uf.is_same(e.src, e.dst)) {
      T.push_back(e);
      total += e.weight;
      uf.unite(e.src, e.dst);
    }
  return std::make_pair(total, T);
}
long long xPos[100001], yPos[100001], CntToX[100001], CntToY[100001];
map<long long, long long> XtoCnt, YtoCnt, XtoY, YtoX;
vector<long long> x, y;
signed main() {
  long long N, cnt = 0;
  cin >> N;
  for (long long i = 0; i < N; i++) {
    long long inX, inY;
    cin >> inX >> inY;
    if (xPos[inX] == 0 && yPos[inY] == 0) {
      xPos[inX]++;
      yPos[inY]++;
      XtoCnt[inX] = cnt;
      YtoCnt[inY] = cnt;
      CntToX[cnt] = inX;
      CntToY[cnt] = inY;
      XtoY[inX] = inY;
      YtoX[inY] = inX;
      x.push_back(inX);
      y.push_back(inY);
      cnt++;
    }
  }
  sort(x.begin(), x.end());
  sort(y.begin(), y.end());
  Graph g(x.size());
  for (long long i = 0; i < x.size() - 1; i++) {
    long long yPos = XtoY[x[i]], yPos2 = XtoY[x[i + 1]];
    long long costX = abs(x[i] - x[i + 1]), costY = abs(yPos - yPos2);
    add_edge(g, XtoCnt[x[i]], XtoCnt[x[i + 1]], min(costX, costY));
    long long xPos = YtoX[y[i]], xPos2 = YtoX[y[i + 1]];
    costY = abs(y[i] - y[i + 1]);
    costX = abs(xPos - xPos2);
    add_edge(g, YtoCnt[y[i]], YtoCnt[y[i + 1]], min(costX, costY));
  }
  cout << kruskal(g).first << "\n";
  return 0;
}
