#include <bits/stdc++.h>
#define int long long
#define double long double
#define rep(i, a, n) for(int i = (int)(a);(i) < (int)(n);++(i))
#define repe(i, a, n) for(int i = (int)(a);(i) <= (int)(n);++(i))
#define repif(i, a, x) for(int i = (int)(a);(x);++(i))
#define repr(i, a, n) for(int i = ((int)(a)-1);(i) >= (int)(n);--(i))
#define reper(i, a, n) for(int i = (int)(a);(i) >= (int)(n);--(i))
#define SZ(x) ((int)(x).size())
#define ALL(x) begin(x), end(x)
#define CEIL(x) ((int)ceil(((double)x)))
#define POW(x, y) ((int)pow(x, y))
#define UNIQUE(x) (x).erase(unique(ALL((x))), end(x))
#define gcd(x, y) __gcd(x, y)
#define lcm(x, y) ((x)/gcd(x,y)*(y))
#define isin(x, l, r) ((l) <= (x) and (x) < (r))
#define fcout(n) cout << fixed << setprecision(n)
#define rcout(n) cout << right << setw(n)
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound
#define PI (acosl(-1))
#define EPS (1e-10)
#define INF LLONG_MAX
#define INF32 INT32_MAX
#define MOD 1000000007LL
using namespace std;
using VI = vector<int>;
using VVI = vector<vector<int>>;
using PII = pair<int, int>;
using TIII = tuple<int, int, int>;
using VPII = vector<pair<int, int>>;
using VTIII = vector<tuple<int, int, int>>;
using Complex = complex<double>;
template<typename T, template<typename> typename C = less> using PQ = priority_queue<T, vector<T>, C<T>>;
template<typename T> inline bool chmax(T& a, const T& b, bool t = false){ if(a<b or (t and a==b)){ a=b; return true; } return false; }
template<typename T> inline bool chmin(T& a, const T& b, bool t = false){ if(a>b or (t and a==b)){ a=b; return true; } return false; }


template<typename T>
struct Kruskal {
    struct Edge {
        int from, to;
        T cost;
        bool used;
        Edge(int from, int to, T cost) : from(from), to(to), cost(cost), used(false){}
        bool operator<(const Edge& e) const {
            return cost < e.cost;
        }
    };
    struct UF {
        vector<int> r, p;
        UF() = default;
        UF(int sz) : r(sz, 1), p(sz){ iota(begin(p), end(p), 0LL); }
        int find(int x){
            return (x == p[x] ? x : p[x] = find(p[x]));
        }
        bool same(int x, int y){
            return find(x) == find(y);
        }
        void unite(int x, int y){
            x = find(x), y = find(y);
            if(x == y) return;
            if(r[x] < r[y]) swap(x, y);
            r[x] += r[y];
            p[y] = x;
        }
    };
    vector<Edge> es;
    UF uf;
    Kruskal() = default;
    Kruskal(int n) : uf(n){}
    void addEdge(int u, int v, T c){
        es.emplace_back(u, v, c);
    }
    T build(){
        sort(begin(es), end(es));
        T res = 0;
        for(auto& e : es){
            if(!uf.same(e.from, e.to)){
                res += e.cost;
                uf.unite(e.from, e.to);
                e.used = true;
            }
        }
        return res;
    }
    Edge operator[](int i) const {
        return es[i];
    }
    vector<Edge> edgeSet(){
        return es;
    }
};


struct Point3D {
    double x, y, z;
    Point3D(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z){}
};
inline Point3D operator-(const Point3D& p, const Point3D& q){ return Point3D(p.x-q.x, p.y-q.y, p.z-q.z); }
inline double norm(const Point3D& p){ return p.x*p.x+p.y*p.y+p.z*p.z; }
inline double abs(const Point3D& p){ return sqrtl(norm(p)); }


struct Sphere {
    Point3D p;
    double r;
    Sphere(double x = 0, double y = 0, double z = 0, double r = 0) : p(x, y, z), r(r){}
};
inline double dist(const Sphere& a, const Sphere& b){ return abs(a.p-b.p)-a.r-b.r; }


signed main(){
    int n;
    while(cin >> n, n){
        vector<Sphere> s;
        rep(i, 0, n){
            double x, y, z, r;
            cin >> x >> y >> z >> r;
            s.emplace_back(x, y, z, r);
        }
        Kruskal<double> G(n);
        rep(i, 0, n) rep(j, i+1, n){
            double e = dist(s[i], s[j]);
            if(e > EPS) G.addEdge(i, j, e);
            else G.addEdge(i, j, 0);
        }
        fcout(3) << G.build() << endl;
    }

    return 0;
}


Measured memory_bytes: 3580