// Original C++ solution (slower):
#include<iostream>

#include<algorithm>

#include<vector>

#include<string>

#include<cmath>

#include<cstdio>

#include<queue>

#include<deque>

#include<map>

#include<stack>

#include<set>

#include<utility>

using namespace std;

typedef pair<int,int> ii;

typedef long long ll;

typedef pair<ll,pair<int,int> > P;

typedef unsigned long long int ull;

const ll MOD=1e9+7;

int dy[]={1,0,-1,0};

int dx[]={0,1,0,-1};

const int MAXN=100000;

const int MAXE=100000;

const int MAXV=10000;

const ll INF=2e9;



int V,E;

struct edge{

    int to,cost;

};

struct pnt{

    int id,x,y;

};

bool cmpx(pnt p1,pnt p2){

    return p1.x<p2.x;

}

bool cmpy(pnt p1,pnt p2){

    return p1.y<p2.y;

}

int n;

vector<vector<edge> > G(MAXN);

vector<bool> used(MAXN,false);

vector<pnt> p(MAXN);



ll prim(){

    priority_queue<ii,vector<ii>,greater<ii> > que;

    que.push(ii(0,0));

    ll res=0;

    while(!que.empty()){

        int cnt=que.top().first;

        int v=que.top().second;

        que.pop();

        if(used[v]) continue;

        used[v]=true;

        res+=cnt;

        for(auto e:G[v]){

            que.push(ii(e.cost,e.to));

        }

    }

    return res;

}



int main(){

    cin>>n;

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

        int x,y;cin>>x>>y;

        p[i]=pnt{i,x,y};

    }

    sort(p.begin(),p.begin()+n,cmpx);

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

        G[p[i].id].push_back({p[i+1].id,min(abs(p[i+1].x-p[i].x),abs(p[i+1].y-p[i].y))});

        G[p[i+1].id].push_back({p[i].id,min(abs(p[i+1].x-p[i].x),abs(p[i+1].y-p[i].y))});

    }

    sort(p.begin(),p.begin()+n,cmpy);

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

        G[p[i].id].push_back({p[i+1].id,min(abs(p[i+1].x-p[i].x),abs(p[i+1].y-p[i].y))});

        G[p[i+1].id].push_back({p[i].id,min(abs(p[i+1].x-p[i].x),abs(p[i+1].y-p[i].y))});

    }

    ll ans=prim();

    cout<<ans<<endl;

    return 0;

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<algorithm>

#include<vector>

#include<string>

#include<cmath>

#include<cstdio>

#include<queue>

#include<deque>

#include<map>

#include<stack>

#include<set>

#include<utility>

using namespace std;

typedef pair<int,int> pii;

typedef long long ll;

typedef pair<int,ll> p;

typedef pair<pii,int> P;

int dy[]={1,0,-1,0};

int dx[]={0,1,0,-1};

const int MAXN=100000;

const int MAXE=100000;

const int MAXV=10000;

const ll INF=2e18;

const ll MOD=1e9+7;



struct UnionFind{

    vector<int> par,rank;

    UnionFind(int n):par(n),rank(n,0){

        for(int i=0;i<n;++i) par[i]=i;

    }

    int root(int x){

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

        return par[x]=root(par[x]);

    }

    void unite(int x,int y){

        int rx=root(x),ry=root(y);

        if(rx==ry) return ;

        if(rank[rx]<rank[ry]) par[rx]=ry;

        else par[ry]=rx;

        if(rank[rx]==rank[ry]) rank[rx]++;

    }

    bool same(int x,int y){

        return root(x)==root(y);

    }

};

struct edge{

    int u,v;

    ll cost;

};

vector<edge> G;

vector<P> C;

bool compx(P c1,P c2){

    if(c1.first.first==c2.first.first) return c1.first.second<c2.first.second;

    return c1.first.first<c2.first.first;

}

bool compy(P c1,P c2){

    if(c1.first.second==c2.first.second) return c1.first.first<c2.first.first;

    return c1.first.second<c2.first.second;

}

bool compedge(edge& e1,edge& e2){

    return e1.cost<e2.cost;

}

int n;

int main(){

    cin>>n;

    C=vector<P>(n);

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

        int x,y;cin>>x>>y;

        C[i]=P(pii(x,y),i);

    }

    sort(C.begin(),C.end(),compx);

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

        G.push_back(edge{C[i].second,C[i+1].second,C[i+1].first.first-C[i].first.first});

        G.push_back(edge{C[i].second,C[i+1].second,abs(C[i+1].first.second-C[i].first.second)});

    }

    sort(C.begin(),C.end(),compy);

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

        G.push_back(edge{C[i].second,C[i+1].second,abs(C[i+1].first.first-C[i].first.first)});

        G.push_back(edge{C[i].second,C[i+1].second,C[i+1].first.second-C[i].first.second});

    }

    sort(G.begin(),G.end(),compedge);

    int m=(int)G.size();

    UnionFind uf(n);

    ll ans=0;

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

        edge e=G[i];

        if(uf.same(e.u,e.v)) continue;

        uf.unite(e.u,e.v);

        ans+=e.cost;

    }

    cout<<ans<<endl;

    return 0;

}

// Fastest known solution for this problem: