#include <iostream>
#include <string>
#include <set>
#include <cstdio>
#include <utility>
#include <vector>
#include <algorithm>
#include <cmath>
#define llint long long

using namespace std;
typedef pair<llint, llint> P;
typedef pair<double, P> E;

struct UnionFind
{
	int size;
	vector<int> parent;
	
	UnionFind(){}
	UnionFind(int size){
		this->size = size;
		parent.resize(size+1);
		init();
	}
	void init(){
		for(int i = 0; i <= size; i++) parent[i] = i;
	}
	int root(int i){
		if(parent[i] == i) return i;
		return parent[i] = root(parent[i]);
	}
	bool same(int i, int j){
		return root(i) == root(j);
	}
	void unite(int i, int j){
		int root_i = root(i), root_j = root(j);
		if(root_i == root_j) return;
		parent[root_i] = root_j;
	}
};

llint n;
double x[105], y[105], z[105], r[105];
vector<E> vec;
UnionFind uf(105);

int main(void)
{
	while(1){
		cin >> n;
		if(n == 0) break;
		
		for(int i = 1; i <= n; i++) cin >> x[i] >> y[i] >> z[i] >> r[i];
		
		vec.clear();
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= n; j++){
				if(i >= j) continue;
				double dist = sqrt((x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) + (z[i]-z[j])*(z[i]-z[j])) - (r[i]+r[j]);
				vec.push_back(E(max(0.0, dist), P(i, j)));
			}
		}
		sort(vec.begin(), vec.end());
		
		uf.init();
		double ans = 0, w; llint u, v;
		for(int i = 0; i < vec.size(); i++){
			w = vec[i].first, u = vec[i].second.first, v = vec[i].second.second;
			if(uf.same(u, v)) continue;
			uf.unite(u, v);
			ans += w;
		}
		printf("%.3f\n", ans);
	}
	
	return 0;
}
