#pragma region Include/Defines
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <limits.h>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <string>
#include <algorithm>
#include <functional>
#include <cassert>
#include <map>
#include <set>
#include <iostream>
#include <queue>
#include <time.h>
#include <list>

using namespace std;
typedef long long lli;
typedef vector<int> vi;
typedef vector<lli> vli;
typedef pair<int, int> pii;
typedef pair<lli, lli> pll;
typedef vector<pii> vpii;
typedef vector <pll> vpll;
typedef long double ld;
#define all(a) std::begin(a), std::end(a)

const int INF = 0x3f3f3f3f;
const lli LINF = 0x3f3f3f3f3f3f3f3f;

template<typename T, typename T2> inline void _max(T &a, T2 b) { a = max((T)a, (T)b); }
template<typename T, typename T2> inline void _min(T &a, T2 b) { a = min((T)a, (T)b); }

#ifdef _DEBUG
#define epr(...) fprintf(stderr,__VA_ARGS__)
#else
#define epr(...) 
#endif
#pragma endregion

const int MAX = 1e5 + 10;
int x[MAX], y[MAX], n;
list<int>::iterator px[MAX], py[MAX];

void clear() {
}

void read() {
	for (int i = 0; i < n; i++) scanf("%d%d", &x[i], &y[i]);
}

#pragma region DSU
int parent[MAX] = { 0 };
int rnk[MAX] = { 0 };

void makeSet(int v) {
	parent[v] = v;
	rnk[v] = 0;
}

int findSet(int v) {
	if (v == parent[v])
		return v;
	return parent[v] = findSet(parent[v]);
}

void unionSets(int a, int b) {
	a = findSet(a);
	b = findSet(b);
	if (a != b) {
		if (rnk[a] < rnk[b])
			swap(a, b);
		parent[b] = a;
		if (rnk[a] == rnk[b])
			++rnk[a];
	}
}
#pragma endregion DSU

int solve2() {
	vpii vp(n * (n - 1) / 2);
	int nvp = 0;
	for (int i = 0; i < n; i++)
		for (int j = i + 1; j < n; j++)
			vp[nvp++] = { i, j };

	sort(all(vp), [](pii &p1, pii &p2) -> bool { 
		int d1 = min(abs(x[p1.first] - x[p1.second]), abs(y[p1.first] - y[p1.second]));
		int d2 = min(abs(x[p2.first] - x[p2.second]), abs(y[p2.first] - y[p2.second]));
		return d1 < d2;
	});

	for (int i = 0; i < n; i++) makeSet(i);

	int res = 0;
	for (auto &p : vp) {
		if (findSet(p.first) == findSet(p.second)) continue;
		unionSets(p.first, p.second);
		int d = min(abs(x[p.first] - x[p.second]), abs(y[p.first] - y[p.second]));
		res += d;
	}
	return res;
}

int solve() {
	int idx[MAX] = { 0 }, idy[MAX] = { 0 };
	for (int i = 0; i < n; i++) idx[i] = idy[i] = i;
	sort(idx, idx + n, [](int i, int j) -> bool { return x[i] < x[j]; });
	sort(idy, idy + n, [](int i, int j) -> bool { return y[i] < y[j]; });
	vpii vp;
	for (int i = 0; i < n - 1; i++)
		vp.push_back({ idx[i], idx[i + 1] }),
		vp.push_back({ idy[i], idy[i + 1] });
	sort(all(vp), [](pii &p1, pii &p2) -> bool {
		int d1 = min(abs(x[p1.first] - x[p1.second]), abs(y[p1.first] - y[p1.second]));
		int d2 = min(abs(x[p2.first] - x[p2.second]), abs(y[p2.first] - y[p2.second]));
		return d1 < d2;
	});
	for (int i = 0; i < n; i++) makeSet(i);
	int res = 0;
	for (auto &p : vp) {
		if (findSet(p.first) == findSet(p.second)) continue;
		unionSets(p.first, p.second);
		int d = min(abs(x[p.first] - x[p.second]), abs(y[p.first] - y[p.second]));
		res += d;
	}
	return res;
}

int main() {
#ifdef _LOCAL_VAN
	freopen("in.txt", "r", stdin);
#endif
	while (scanf("%d", &n) == 1) {
		clear();
		read();
		auto res = solve();
#ifdef _LOCAL_VAN
		auto res2 = solve();
		assert(res == res2);
#endif

		printf("%d\n", res);
#ifndef _LOCAL_VAN
		return 0;
#endif
	}
	return 0;
}

Measured memory_bytes: 5872