// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define ll long long

struct p {

	int x, y;

	int indx;

};

const int N = 1e5 + 5;

p points[N];

int n;

int par[N];

int get(int n) {

	if (par[n] == n) return n;

	return par[n] = get(par[n]);

}

vector<int> g[N];

void solve() {

	for (int i = 0; i < N; i++)

		par[i] = i;

	vector<pair<int, pair<int, int> >> edg;

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

//		g[i].clear();

//		g[i].resize(n);

		for (int j = 0; j < g[i].size(); j++) {

//			g[i][j] = j;

			int v = g[i][j];

			ll c = min(abs(points[i].x - points[v].x),

					abs(points[i].y - points[v].y));

			edg.push_back(make_pair(c, make_pair(i, v)));

		}

	}

	sort(edg.begin(), edg.end());

	ll ans = 0;

	for (int i = 0; i < edg.size(); i++) {

		int u = edg[i].second.first;

		int v = edg[i].second.second;

		int r1 = get(u);

		int r2 = get(v);

		if (r1 == r2) continue;

		//cout << u << "  " << v << endl;

		ans += edg[i].first;

		par[r1] = r2;

	}

	cout << ans << endl;

}

void gen(vector<pair<int, int> > &a, vector<pair<int, int> > &b) {



	sort(b.begin(), b.end());



	for (int i = 0; i < a.size(); i++) {



		auto it = lower_bound(b.begin(), b.end(), make_pair(a[i].first, -1));

		if (it != b.end()) {

			g[a[i].second].push_back(it->second);

			g[it->second].push_back(a[i].second);

		}

		if (it != b.begin()) {

			it--;



			g[a[i].second].push_back(it->second);

			g[it->second].push_back(a[i].second);

		}

	}

}

int main() {

	ios_base::sync_with_stdio(0);

	cin.tie(0);

	cin >> n;

	vector<pair<int, pair<int, int> > > v;

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

		cin >> points[i].x >> points[i].y;

		points[i].indx = i;

		v.push_back(make_pair(points[i].x, make_pair(points[i].y, i)));

	}

	sort(v.begin(), v.end());

	vector<pair<int, int> > last, cur;

	for (int i = 0; i < n;) {

		int X = v[i].first;

		while (i < n && v[i].first == X) {

			cur.push_back(v[i].second);

			i++;

		}

		if (last.size()) gen(last, cur);

		last = cur;

		cur.clear();

	}

	for (int i = 0; i + 1 < n; i++) {

		int u = v[i].second.second;

		int V = v[i + 1].second.second;

		g[u].push_back(V);

		g[V].push_back(u);

	}

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

		swap(v[i].first, v[i].second.first);

	last.clear();

	sort(v.begin(), v.end());

	for (int i = 0; i < n;) {

		int X = v[i].first;



		while (i < n && v[i].first == X) {

			cur.push_back(v[i].second);

			i++;

		}

		if (last.size()) gen(last, cur);

		last = cur;

		cur.clear();

	}

	for (int i = 0; i + 1 < n; i++) {

		int u = v[i].second.second;

		int V = v[i + 1].second.second;

		g[u].push_back(V);

		g[V].push_back(u);

	}



	solve();

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.9216825873223042x):
// #define FNAME "template"



#define NDEBUG



#include <bits/stdc++.h>

using namespace std;



typedef long long inte;

const int maxn = 100005;



#ifndef NDEBUG

#    define dprint(x) (cerr << (#x) << " = "<< (x) << endl)

#else

#    define dprint(x) (NULL)

#endif



template<typename T>

inline void readFig(T& x)

{

#   ifdef FTREAD

        static int c = 0;

        int op = 1;

        x = 0;

        while (!isdigit(c)) {

            if (c == '-')

                op = -1;

            c = getchar();

        }

        while (isdigit(c)) {

            x *= 10;

            x += c - '0';

            c = getchar();

        }

        x *= op;

#   else

        cin >> x;

#   endif

}



int N, M;

struct Edge {

    int u, v, w;

} edges[maxn * 2];

inline bool operator < (const Edge &a, const Edge &b)

{

    return a.w < b.w;

}



int par[maxn];

int getPar(int x)

{

    static int st[maxn];

    int stop = 0;

    while (par[x] != x) {

        x = par[x];

        st[stop++] = x;

    }

    while (stop--)

        par[st[stop]] = x;

    return x;

}

inline inte genMST()

{

    for (int i = 1; i <= N; ++i)

        par[i] = i;

    int cnt = 0;

    inte ans = 0;

    for (int i = 1; i <= M; ++i) {

        int u = getPar(edges[i].u), v = getPar(edges[i].v);

        if (u != v) {

            par[u] = v;

            ++cnt;

            ans += edges[i].w;

            dprint(ans);

        }

    }

    //assert(cnt == N - 1);

    return ans;

}



struct City {

    int x, y, id;

} cities[maxn];



inline bool compx(const City &a, const City &b)

{

    return a.x < b.x;

}

inline bool compy(const City &a, const City &b)

{

    return a.y < b.y;

}

inline int getdis(const City &a, const City &b)

{

    return min(abs(a.x - b.x), abs(a.y - b.y));

}



inline void solve()

{

    readFig(N);

    for (int i = 1; i <= N; ++i) {

        readFig(cities[i].x); readFig(cities[i].y);

        cities[i].id = i;

    }

    sort(cities + 1, cities + N + 1, compx);

    for (int i = 1; i < N; ++i) {

        edges[++M].u = cities[i].id;

        edges[M].v = cities[i + 1].id;

        edges[M].w = getdis(cities[i], cities[i + 1]);

    }

    sort(cities + 1, cities + N + 1, compy);

    for (int i = 1; i < N; ++i) {

        edges[++M].u = cities[i].id;

        edges[M].v = cities[i + 1].id;

        edges[M].w = getdis(cities[i], cities[i + 1]);

    }

    sort(edges + 1, edges + M + 1);

    cout << genMST() << endl;

}



signed main()

{

#   ifdef FNAME

        freopen(FNAME".in", "r", stdin);

        freopen(FNAME".out", "w", stdout);

#   endif

#   ifndef FTREAD

    	ios::sync_with_stdio(false);

    	cin.tie(0);

#   endif



#   ifdef MULTEST

        int T;

        readFig(T);

        while (T--)

            solve();

#   else

        solve();

#   endif



#   ifdef FNAME

        fclose(stdin);

        fclose(stdout);

#   endif

    	return 0;

}