Problem:
Score : 500 points

Problem Statement

There are N towns on a plane. The i-th town is located at the coordinates (x_i,y_i). There may be more than one town at the same coordinates.

You can build a road between two towns at coordinates (a,b) and (c,d) for a cost of min(|a-c|,|b-d|) yen (the currency of Japan). It is not possible to build other types of roads.

Your objective is to build roads so that it will be possible to travel between every pair of towns by traversing roads. At least how much money is necessary to achieve this?

Constraints

2 ≤ N ≤ 10^5

0 ≤ x_i,y_i ≤ 10^9

All input values are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_N y_N

Output

Print the minimum necessary amount of money in order to build roads so that it will be possible to travel between every pair of towns by traversing roads.

Sample Input 1

3
1 5
3 9
7 8

Sample Output 1

3

Build a road between Towns 1 and 2, and another between Towns 2 and 3. The total cost is 2+1=3 yen.

Sample Input 2

6
8 3
4 9
12 19
18 1
13 5
7 6

Sample Output 2

8

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Contest
{
	public static void Main()
	{
        int n;
		VT<int,int>[] xyl;
		MyIO.ReadMulti(out n);
		MyIO.ReadLines(n, out xyl);
 
		VT<int,int,int>[] xsl = new VT<int, int, int>[n];
		VT<int,int,int>[] ysl = new VT<int, int, int>[n];
		for(int i=0;i<n;i++) {
			xsl[i] = new VT<int, int, int>(xyl[i].Item1,xyl[i].Item2,i);
			ysl[i] = new VT<int, int, int>(xyl[i].Item1,xyl[i].Item2,i);
		}
		Array.Sort(xsl, (x,y)=>x.Item1-y.Item1);
		Array.Sort(ysl, (x,y)=>x.Item2-y.Item2);

		Dictionary<long,int> sl = new Dictionary<long, int>(10*n); 
		for(int i=0;i<n-1;i++){
			long i1 = (long)Math.Min(xsl[i].Item3,xsl[i+1].Item3) * (long)n + (long)Math.Max(xsl[i].Item3,xsl[i+1].Item3) ;
			int c1 = Math.Min( Math.Abs(xsl[i].Item1-xsl[i+1].Item1), Math.Abs(xsl[i].Item2-xsl[i+1].Item2) );
			if(sl.ContainsKey(i1)){
				if(c1<sl[i1]) sl[i1] = c1;
			}else{
				sl[i1] = c1;
			}
			long i2 = (long)Math.Min(ysl[i].Item3,ysl[i+1].Item3) * (long)n + (long)Math.Max(ysl[i].Item3,ysl[i+1].Item3) ;
			int c2 = Math.Min( Math.Abs(ysl[i].Item1-ysl[i+1].Item1), Math.Abs(ysl[i].Item2-ysl[i+1].Item2) );
			if(sl.ContainsKey(i2)){
				if(c2<sl[i2]) sl[i2] = c2;
			}else{
				sl[i2] = c2;
			}
		}

		List<VT<int,int,int>> g = new List<VT<int, int, int>>();
		foreach(var s in sl){
			int k = (int)s.Key / n;
			int l = (int)s.Key % n;
			g.Add(new VT<int, int, int>(k,l,s.Value));
		}

		VT<int,int,int>[] o;
		long r = Kruskal(g.ToArray(), n, out o);
 
		MyIO.WriteMulti(r);

	}




	public static long Kruskal(VT<int,int,int>[] inEdges, int V, out VT<int,int,int>[] outEdges) {
		Array.Sort(inEdges, (x,y)=>(x.Item3.CompareTo(y.Item3)));
		UnionFind tree = new UnionFind(V);
		long ret = 0;
		List<VT<int,int,int>> oedge = new List<VT<int, int, int>>();
		foreach(var e in inEdges) {
			if(tree.Unite(e.Item1, e.Item2)) {
				ret += e.Item3;
				oedge.Add(e);
			}
		}
		outEdges = oedge.ToArray();
		return ret;
	}

}


public class UnionFind {
    private int[] data;

    public UnionFind(int size) {
        data = new int[size];
        for (int i = 0; i < size; i++) data[i] = -1;
    }

    public bool Unite(int x, int y) {
        x = Find(x);
        y = Find(y);

        if (x != y) {
            if (data[y] < data[x]) {
                var tmp = y;
                y = x;
                x = tmp;
            }
            data[x] += data[y];
            data[y] = x;
        }
        return x != y;
    }

    public bool IsSameGroup(int x, int y) { return Find(x) == Find(y); }

    public int Find(int x) { return data[x] < 0 ? x : data[x] = Find(data[x]); }

    public int Size(int x) { return -data[Find(x)]; }

}



public struct VT<T, U>
{
	public T Item1; public U Item2;
    public VT(T a, U b) { Item1 = a; Item2 = b; }
}
public struct VT<T, U, V>
{
	public T Item1; public U Item2; public V Item3;
    public VT(T a, U b, V c) { Item1 = a; Item2 = b; Item3 = c; }
}
public struct VT<T, U, V, W>
{
	public T Item1; public U Item2; public V Item3; public W Item4;
    public VT(T a, U b, V c, W d) { Item1 = a; Item2 = b; Item3 = c; Item4 = d; }
}

public class Printer : System.IO.StreamWriter
{
	public override IFormatProvider FormatProvider { get { return System.Globalization.CultureInfo.InvariantCulture; } }
	public Printer(System.IO.Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	public Printer(System.IO.Stream stream, Encoding encoding) : base(stream, encoding) { }
}
public static class MyIO
{
	private static char[] splitter = new char[] {' '};
	private static bool eq<T, U>() => typeof(T).Equals(typeof(U));
	private static T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
	private static T cv<T>(string s) => eq<T, int>()    ? ct<T, int>(int.Parse(s))
	                                  : eq<T, long>()   ? ct<T, long>(long.Parse(s))
	                                  : eq<T, double>() ? ct<T, double>(double.Parse(s, System.Globalization.CultureInfo.InvariantCulture))
	                                  : eq<T, char>()   ? ct<T, char>(s[0])
	                                                    : ct<T, string>(s);				
	public static string[] ReadMulti<T>(out T a) {
		var ar = Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries); 
		a = cv<T>(ar[0]);
		return ar;
	}
	public static string[] ReadMulti<T, U>(out T a, out U b) {
		var ar = ReadMulti<T>(out a); 
        b = cv<U>(ar[1]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V>(out T a, out U b, out V c) {
		var ar = ReadMulti<T, U>(out a, out b); 
        c = cv<V>(ar[2]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W>(out T a, out U b, out V c, out W d) {
		var ar = ReadMulti<T, U, V>(out a, out b, out c); 
        d = cv<W>(ar[3]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e) {
		var ar = ReadMulti<T, U, V, W>(out a, out b, out c, out d); 
        e = cv<X>(ar[4]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W, X, Y>(out T a, out U b, out V c, out W d, out X e, out Y f) {
		var ar = ReadMulti<T, U, V, W, X>(out a, out b, out c, out d, out e); 
        f = cv<Y>(ar[5]);
		return ar;
	}
	public static string[] ReadArray<T>(out T[] a) {		
		var ar = Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries);
		a = ar.Select(cv<T>).ToArray();
		return ar;
	}		
	public static string[][] ReadLines<T>(int n, out T[] a) {
		a = new T[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) arr[i] = ReadMulti(out a[i]);
		return arr;
	}
	public static string[][] ReadLines<T, U>(int n, out VT<T, U>[] a) {
		a = new VT<T, U>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p;
			arr[i] = ReadMulti(out o, out p);
			a[i] = new VT<T, U>(o, p);
		}
		return arr;
	}
	public static string[][] ReadLines<T, U, V>(int n, out VT<T, U, V>[] a) {
		a = new VT<T, U, V>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p; V q;
			arr[i] = ReadMulti(out o, out p, out q);
			a[i] = new VT<T, U, V>(o, p, q);
		}
		return arr;
	}
	public static string[][] ReadLines<T, U, V, W>(int n, out VT<T, U, V, W>[] a) {
		a = new VT<T, U, V, W>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p; V q; W r;
			arr[i] = ReadMulti(out o, out p, out q, out r);
			a[i] = new VT<T, U, V, W>(o, p, q, r);
		}
		return arr;
	}
	public static string[][] ReadMatrix<T>(int n, out T[][] a) {
		a = new T[n][];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) arr[i] = ReadArray(out a[i]);
		return arr;
	}

	private static void wwp(Action act){
		var sw = new Printer(Console.OpenStandardOutput()){AutoFlush = false};
		Console.SetOut(sw);
		act();
		Console.Out.Flush();
		sw.AutoFlush = true;
		Console.SetOut(sw);
	}
	public static void WriteMulti(params object[] a) {
		wwp(()=>{
			foreach(object x in a) Console.Write("{0} ", x);
			Console.WriteLine();
		});
	}
	public static void WriteArray<T>(T[] a) {
		wwp(()=>{
			foreach(T x in a) Console.Write("{0} ", x);
			Console.WriteLine();
		});
	}
	public static void WriteLines<T>(T[] a) {
		wwp(()=>{
			foreach(T x in a) Console.WriteLine(x);
		});
	}



}