// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<queue>

#include<cmath>

#include<iostream>

using namespace std;

const int inf=0x3f3f3f3f;

const int maxn=1e5+10;



struct edge{

    int u,v,w;

    edge(int _u=0,int _v=0,int _w=0):u(_u),v(_v),w(_w){

    }

    bool operator<(const edge & a)const{

        return w<a.w;

    }

}es[2*maxn];



struct point{

    int x,y,id;

    point(int _x=0,int _y=0,int _id=0):x(_x),y(_y),id(_id){}

} ps[maxn];



int n,cnt,f[maxn];



bool cmpx(point a,point b){

    return a.x<b.x;

}



bool cmpy(point a,point b){

    return a.y<b.y;

}



int findf(int a){

    return ((f[a]==-1)?a:f[a]=findf(f[a]));

}



int kruskal(){

    int i,ans=0,cc=0;

    memset(f,0xff,sizeof(f));

    sort(es,es+cnt);

    for(i=0;i<cnt;i++){

        int u=es[i].u,v=es[i].v,w=es[i].w;

        int fu=findf(u),fv=findf(v);

        if(fu!=fv){

            ans+=w,++cc;

            f[fu]=fv;

        }

        if(cc==n-1)break;

    }

    if(cc<n-1)return -1;

    return ans;

}

int main(){

    int i,j,k,c,un,vn;

    scanf("%d",&n);

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

        scanf("%d%d",&ps[i].x,&ps[i].y);

        ps[i].id=i;

    }

    sort(ps+1,ps+n+1,cmpx);

    for(i=1;i<=n-1;i++){

        es[cnt++]=edge(ps[i].id,ps[i+1].id,(ps[i+1].x-ps[i].x));

    }

    sort(ps+1,ps+n+1,cmpy);

    for(i=1;i<=n-1;i++){

        es[cnt++]=edge(ps[i].id,ps[i+1].id,(ps[i+1].y-ps[i].y));

    }

    printf("%d\n",kruskal());

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 4.9658784045100575x):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

#define mst(a,b) memset(a,b,sizeof(a))

#define lowbit(x) ((x)&(-x))

#define X first

#define Y second

using namespace std;

using namespace __gnu_cxx;

using namespace __gnu_pbds;

typedef long long LL;

typedef long long ll;

typedef unsigned long long ull;

typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

const int inf = 0x3f3f3f3f;

const ll INF = 0x3f3f3f3f3f3f3f3f;

const int maxn = 100000+10;

const int maxm = 200000+10;

const int mod = 1e9+7;

const double eps = 1e-9;

struct Edge{

    int u,v,w;

    Edge(){}

    bool operator < (const Edge &rhs){

        return w<rhs.w;

    }

}edge[maxn<<1];

pii x[maxn],y[maxn];

int fa[maxn];

int Find(int u){

    return u==fa[u]?u:fa[u]=Find(fa[u]);

}

int main() {

#ifdef local

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

//    freopen("out.txt", "w", stdout);

#endif

    ios::sync_with_stdio(0);

    cin.tie(0);cout.tie(0);

    int n; cin>>n;

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

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

        x[i].Y=y[i].Y=i;

        fa[i]=i;

    }

    sort(x,x+n);

    sort(y,y+n);

    int tot=0;

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

        edge[tot].u=x[i-1].Y; edge[tot].v=x[i].Y; edge[tot++].w=x[i].X-x[i-1].X;

        edge[tot].u=y[i-1].Y; edge[tot].v=y[i].Y; edge[tot++].w=y[i].X-y[i-1].X;

    }

    sort(edge,edge+tot);

    int ans=0;

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

        int u=Find(edge[i].u),v=Find(edge[i].v);

        if (u!=v){

            ans+=edge[i].w;

            fa[u]=v;

        }

    }

    cout<<ans<<"\n";

    return 0;

}