#include <bits/stdc++.h>
 
#define REP(i,n) for(int i=0; i<(int)(n); ++i)
#define FOR(i,k,n) for(int i=(k);i<(int)(n);++i)
typedef long long int ll;
using namespace std;

struct UnionFind {
  vector<int> par;
  vector<int> rank;

  UnionFind(int n) : par(n), rank(n, 1) {
    for(int i=0; i<n; ++i) par[i] = i;
  }

  int find(int x) {
    if (x == par[x]) return x;
    return par[x] = find(par[x]);
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rank[x] < rank[y]) swap(x, y);
    par[y] = x;
    rank[x] += rank[y];
  }

  bool same(int x, int y) {
    return find(x) == find(y);
  }
};

typedef double Cost;

struct edge{
    int src, dst; Cost cost;
    edge(int s, int t, Cost c) : src(s), dst(t), cost(c) {}
    bool operator < (const edge &rhs) const {return cost < rhs.cost;}
};

Cost kruskal(int V, vector<edge> &edges) {
    UnionFind uf(V);
    sort(edges.begin(), edges.end());
    Cost ans = 0;
    for(auto e : edges) {
        if(!uf.same(e.src, e.dst)) {
            uf.unite(e.src, e.dst);
            ans += e.cost;
        }
    }
    return ans;
}

int main(void) {
    int n;
    while(cin >> n && n) {
        vector<double> x(n), y(n), z(n), r(n);
        vector<edge> edges;
        REP(i, n) {
            cin >> x[i] >> y[i] >> z[i] >> r[i];
        }
        REP(i, n)  {
            REP(j, n) {
                if(i == j) continue;
                double c = sqrt(pow(x[i]-x[j], 2.0) + pow(y[i]-y[j], 2.0) + pow(z[i]-z[j], 2.0)) - r[i] - r[j];
                edges.push_back(edge(i, j, max(0.0, c)));
            }
        }
        printf("%.3f\n", kruskal(n, edges));
    }
}
