using System;
using System.Collections.Generic;

public class PriorityQueue<T> where T:IComparable<T>
{
	IComparer<T> comparer;
	T[] heap;
	int heapSize;

	public PriorityQueue(int maxSize, IComparer<T> comparer=null)
	{
		heap = new T[maxSize+1];
		heapSize = 0;
		this.comparer = comparer;
	}

	int compare(T x, T y)
	{
		if(comparer == null)
		{
			return x.CompareTo(y);
		}
		else
		{
			return comparer.Compare(x, y);
		}
	}

	public void Push(T x)
	{
		heapSize++;
		int i = heapSize;
		heap[i] = x;
		while(i > 1 && compare(heap[i/2], heap[i]) < 0)
		{
			T t = heap[i/2];
			heap[i/2] = heap[i];
			heap[i] = t;
			i = i / 2;
		}
		
	}

	void maxHeapify(int i)
	{
		int l, r, largest;
		l = i * 2;
		r = i * 2 + 1;
		largest = i;
		if(l <= heapSize && compare(heap[l], heap[i]) > 0)
				largest = l;
		if(r <= heapSize && compare(heap[r], heap[largest]) > 0)
				largest = r;

		if(largest != i)
		{
			T t = heap[i];
			heap[i] = heap[largest];
			heap[largest] = t;
			maxHeapify(largest);
		}
	}

	public T Pop()
	{
		if(heapSize == 0)
			return default(T);
		T max = heap[1];
		heap[1] = heap[heapSize];
		heapSize--;
		maxHeapify(1);
		return max;
	}

}

class Node
{
	int x;
	int y;
	bool visited;
	List<Edge> edges;

	public int X
	{
		get { return x; }
	}

	public int Y
	{
		get { return y; }
	}

	public bool Visited
	{
		get { return visited; }
		set { visited = value; }
	}

	public List<Edge> Edges
	{
		get { return edges; }
	}

	public Node(int x, int y)
	{
		this.x = x;
		this.y = y;
		visited = false;
		edges = new List<Edge>();
	}
}

class Edge : IComparable<Edge>
{
	Node to;
	int weight;


	public Node To
	{
		get { return to; }
	}

	public int Weight
	{
		get { return weight; }
	}

	public Edge(Node to, int weight)
	{
		this.to = to;
		this.weight = weight;
	}
	
	public int CompareTo(Edge e)
	{
		return e.weight - this.weight;
	}
}

class ABC065D
{
	static public void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] vals;
		List<Node> nodes = new List<Node>();
		for(int i=0; i < N; i++)
		{
			vals = Console.ReadLine().Split(' ');
			nodes.Add(new Node(int.Parse(vals[0]), int.Parse(vals[1])));
		}

		nodes.Sort((a,b) => (a.X - b.X));
		for(int i=0; i<nodes.Count-1; i++)
		{
			nodes[i].Edges.Add(new Edge(nodes[i+1], nodes[i+1].X - nodes[i].X));
			//Console.WriteLine("{0} to {1} weight = {2}", i, i+1, nodes[i+1].X-nodes[i].X);
			nodes[i+1].Edges.Add(new Edge(nodes[i], nodes[i+1].X - nodes[i].X));
			//Console.WriteLine("{0} to {1} weight = {2}", i+1, i, nodes[i+1].X-nodes[i].X);
		}

		nodes.Sort((a,b) => (a.Y - b.Y));
		for(int i=0; i<nodes.Count-1; i++)
		{
			nodes[i].Edges.Add(new Edge(nodes[i+1], nodes[i+1].Y - nodes[i].Y));
			//Console.WriteLine("{0} to {1} weight = {2}", i, i+1, nodes[i+1].Y-nodes[i].Y);
			nodes[i+1].Edges.Add(new Edge(nodes[i], nodes[i+1].Y - nodes[i].Y));
			//Console.WriteLine("{0} to {1} weight = {2}", i+1, i, nodes[i+1].Y-nodes[i].Y);
		}

		PriorityQueue<Edge> queue = new PriorityQueue<Edge>(N*4);
		queue.Push(new Edge(nodes[0], 0));

		long ans = 0;
		Edge e;
		while((e = queue.Pop()) != null)
		{
			if(e.To.Visited)
				continue;
			//Console.WriteLine("edge weight={0}", e.Weight);
			ans += e.Weight;
			e.To.Visited = true;
			foreach(Edge f in e.To.Edges)
			{
				if(f.To.Visited)
					continue;
				queue.Push(f);
			}
		}
		Console.WriteLine(ans);
	}

}


Measured memory_bytes: 48092