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

using namespace std;

typedef long long ll;

const int maxn=1e6+10;

const int MAXM=1e6+10;

int F[maxn];

struct node

{

    int x,y,id;

}sp[maxn];

bool cmp2(node a,node b)

{

    return a.x<b.x;

}

bool cmp3(node a,node b)

{

    return a.y<b.y;

}

struct Edge

{

    int u,v,w;

}e[MAXM];

int tol;

void addedge(int u,int v,int w)

{

    e[tol].u=u;

    e[tol].v=v;

    e[tol++].w=w;

}

bool cmp(Edge a,Edge b)

{

    return a.w<b.w;

}

int Find(int x)

{

    if(F[x]==-1)return x;

    else return F[x]=Find(F[x]);

}

int Krustal(int n)

{

    memset(F,-1,sizeof(F));

    sort(e,e+tol,cmp);

    int cnt=0;

    int ans=0;

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

    {

        int u=e[i].u;

        int v=e[i].v;

        int w=e[i].w;

        int t1=Find(u);

        int t2=Find(v);

       // cout<<t1<<' '<<t2<<endl;

        if(t1!=t2)

        {

            ans+=w;

            F[t1]=t2;

            cnt++;

        }

        if(cnt==n-1) break;

    }

   // cout<<cnt<<endl;

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

    else return ans;

}

int main()

{

    int n;

    cin>>n;

    tol=0;

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

    {

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

        sp[i].id=i;

    }

    sort(sp+1,sp+1+n,cmp2);

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

    {

        addedge(sp[i].id,sp[i+1].id,sp[i+1].x-sp[i].x);

    }

    sort(sp+1,sp+1+n,cmp3);

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

    {

        addedge(sp[i].id,sp[i+1].id,sp[i+1].y-sp[i].y);

    }

    int ans=Krustal(n);

    cout<<ans<<endl;

    return 0;

}


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

using namespace std;

typedef long long ll;

const int N = 200000+5;

struct Edge{

    int x,y;

    int dis;

    Edge(){}

    Edge(int x,int y,int dis):x(x),y(y),dis(dis){}

    bool operator <(const Edge &rhs)const{

        return dis<rhs.dis;

    }

}edge[N];

int tot;

struct Node{

    int x,y;

}node[N];

int father[N];

 

bool cmpX(int a,int b){

    return node[a].x<node[b].x;

}

bool cmpY(int a,int b){

    return node[a].y<node[b].y;

}

int Find(int x){

    if(father[x]!=x)

        return father[x]=Find(father[x]);

    return x;

}

int n;

int Kruskal(){

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

        father[i]=i;

 

    int mst=0;

    sort(edge+1,edge+1+tot);

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

        int x=Find(edge[i].x);

        int y=Find(edge[i].y);

        if(x!=y){

            mst+=edge[i].dis;

            father[x]=y;

        }

    }

    return mst;

}

int main(){

    scanf("%d",&n);

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

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

 

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

        father[i]=i;

    sort(father+1,father+1+n,cmpX);

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

        int x=father[i];

        int y=father[i+1];

        int dis=node[y].x-node[x].x;

        edge[++tot]=Edge(x,y,dis);

    }

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

        father[i]=i;

    sort(father+1,father+1+n,cmpY);

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

        int x=father[i];

        int y=father[i+1];

        int dis=node[y].y-node[x].y;

        edge[++tot]=Edge(x,y,dis);

    }

 

    int mst=Kruskal();

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

    return 0;

}