#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <tuple>
#include <iomanip>
#include <cmath>

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#define dump(val) cerr << __LINE__ << ":\t" << #val << " = " << (val) << endl

using namespace std;

typedef long long int lli;
typedef tuple<double,int,int> T;

class UnionFind {
public:
    vector<int> par;
    int size;
    UnionFind(int n) {
        size = n;
        par.resize(n);
        REP (i, 0, n) par[i] = i;
    }
    int find(int n) {
        return (n == par[n] ? n : par[n] = find(par[n]));
    }
    bool unite(int a, int b) {
        a = find(a);
        b = find(b);
        if (a == b) return false;
        par[a] = b;
        size--;
        return true;
    }
    bool same(int a, int b) {
        return find(a) == find(b);
    }
};

int main() {
    int n;
    while (cin >> n, n) {
        vector<double> x(n), y(n), z(n), r(n);
        REP (i, 0, n) cin >> x[i] >> y[i] >> z[i] >> r[i];
        UnionFind uf(n);
        vector<T> v;
        v.reserve(n * n);
        REP (i, 0, n) REP (j, i + 1, n) {
            double dis = 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]));
            v.push_back(make_tuple(max(0.0, dis - r[i] - r[j]), i, j));
        }
        sort(begin(v), end(v));
        double ans = 0;
        REP (i, 0, v.size()) {
            T tp = v[i];
            if (uf.unite(get<1>(tp), get<2>(tp))) {
                ans += get<0>(tp);
            }
        }
        cout << fixed << setprecision(3) << ans << endl;
    }

    return 0;
}
