// Arup Guha
// 11/11/2010
// Solution to 2010 SE Regional Problem J: Underground Cables
// Edited on 2/6/2018 to use my disjoint set class with path compression.

import java.util.*;

class djset {

	final public static int N = 10;

	public int[] parent;

	// Creates a disjoint set of size n (0, 1, ..., n-1)
	public djset(int n) {
		parent = new int[n];
		for (int i=0; i<n; i++)
			parent[i] = i;
	}

	public int find(int v) {

		// I am the club president!!! (root of the tree)
		if (parent[v] == v) return v;

		// Find my parent's root.
		int res = find(parent[v]);

		// Attach me directly to the root of my tree.
		parent[v] = res;
		return res;
	}

	public boolean union(int v1, int v2) {

		// Find respective roots.
		int rootv1 = find(v1);
		int rootv2 = find(v2);

		// No union done, v1, v2 already together.
		if (rootv1 == rootv2) return false;

		// Attach tree of v2 to tree of v1.
		parent[rootv2] = rootv1;
		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 cables {

	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) {

		djset mydset = new djset(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;
	}
}