// Arup Guha
// 11/11/2010
// Solution to 2010 SE Regional Problem J: Underground Cables

import java.util.*;

//  Just used for the Disjoint set class.
class pair {
	public int parent;
	public int height;
	
	public pair(int a, int b) {
		parent = a;
		height = b;
	}
}

// Basic Disjoint Set without path compression.
class dset {
	
	private pair[] parents;
	
	public dset(int n) {
		parents = new pair[n];
		for (int i=0; i<n; i++)
			parents[i] = new pair(i,0);
	}
	
	public int find(int child) {
		while (parents[child].parent != child)
			child = parents[child].parent;
		return child;
	}
	
	public boolean union(int c1, int c2) {
		int root1 = find(c1);
		int root2 = find(c2);
		
		// Nothing to union.
		if (root1 == root2)
			return false;
			
		// Root 1 stays parent.
		if (parents[root1].height > parents[root2].height) {
			parents[root2].parent = root1;
		}
		
		// Tie case get assigned to root 1 also.
		else if (parents[root1].height == parents[root2].height) {
			parents[root2].parent = root1;
			parents[root1].height++;
		}
		
		// Must use root 2 here.
		else {
			parents[root1].parent = root2;
		}
		
		return true;
	}
}

// Stores each possible edge for the minimum spanning tree.
class edge implements Comparable<edge> {
	
	public int v1;
	public int v2;
	public double distance;
	
	public edge(int start, int end, double d) {
		v1 = start;
		v2 = end;
		distance = d;
	}
	
	// Basic compareTo.
	public int compareTo(edge other) {
		if (this.distance < other.distance)
			return -1;
		else if (this.distance > other.distance)
			return 1;
		return 0;
	}
}

// Stores a Cartesian point.
class point {
	public int x;
	public int y;
	
	public point(int myx, int myy) {
		x = myx;
		y = myy;
	}
	
	public double getDistance(point p) {
		return Math.sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
	}
}

public class j {
	
	public static void main(String[] args) {
		
		Scanner stdin = new Scanner(System.in);
		
		int n = stdin.nextInt();
		
		// Go through each case.
		while (n != 0) {
			
			// Read in raw data.
			point[] cities = new point[n];
			for (int i=0; i<n; i++) {
				int x = stdin.nextInt();
				int y = stdin.nextInt();
				cities[i] = new point(x,y);
			}
			
			// Store all edges...
			ArrayList<edge> allEdges = new ArrayList<edge>();
			for (int i=0; i<n; i++) 
				for (int j=i+1; j<n; j++) 
					allEdges.add(new edge(i,j,cities[i].getDistance(cities[j])));
				
			// Sort these guys.
			Collections.sort(allEdges);
			
			// Output the answer for this case.
			System.out.printf("%.2f\n",mst(allEdges, n));
			
			// Go to the next case.
			n = stdin.nextInt();
		}
	}
	
	// Return the length of the sum of the edges in the mst of the graph
	// of n vertices represented in allEdges.
	public static double mst(ArrayList<edge> allEdges, int n) {
		
		dset mydset = new dset(n);
		double answer = 0;
		
		int numedges = 0;
		int index = 0;
		
		// Keep on going until we get the right number of edges.
		while (numedges < n-1) {
			
			// Next edge to try.
			edge next = allEdges.get(index);
			
			// We add this edge.
			if (mydset.union(next.v1, next.v2)) {
				answer += next.distance;
				numedges++;
			}
			
			// Always go to the next item.
			index++;
		}
		
		return answer;
	}
}