// #define _GLIBCXX_DEBUG
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;using pll = pair<ll, ll>;using pdd = pair<double, double>;using pss = pair<string, string>;using pbb = pair<bool, bool>;
using ti3 = tuple<int, int, int>;using tl3 = tuple<ll, ll, ll>;using td3 = tuple<double, double, double>;using ts3 = tuple<string, string, string>;using tb3 = tuple<bool, bool, bool>;
using ti4 = tuple<int, int, int, int>;using tl4 = tuple<ll, ll, ll, ll>;using td4 = tuple<double, double, double, double>;using ts4 = tuple<string, string, string, string>;using tb4 = tuple<bool, bool, bool, bool>;
using vi = vector<int>;using vl = vector<ll>;using vd = vector<double>;using vs = vector<string>;using vb = vector<bool>;
using vvi = vector<vi>;using vvl = vector<vl>;using vvd = vector<vd>;using vvs = vector<vs>;using vvb = vector<vb>;
using v3i = vector<vvi>;using v3l = vector<vvl>;using v3d = vector<vvd>;using v3s = vector<vvs>;using v3b = vector<vvb>;
using vpii = vector<pii>;using vpll = vector<pll>;using vpdd = vector<pdd>;using vpss = vector<pss>;using vpbb = vector<pbb>;
using vti3 = vector<ti3>;using vtl3 = vector<tl3>;using vtd3 = vector<td3>;using vts3 = vector<ts3>;using vtb3 = vector<tb3>;
using mii = map<int, int>;using mll = map<ll, ll>;using mci = map<char, int>;using msi = map<string, int>;
using si = set<int>;using sl = set<ll>;using sd = set<double>;using ss = set<string>;using sb = set<bool>;
using spii = set<pii>;using spll = set<pll>;using spdd = set<pdd>;using spss = set<pss>;using spbb = set<pbb>;
using sti3 = set<ti3>;using stl3 = set<tl3>;using std3 = set<td3>;using sts3 = set<ts3>;using stb3 = set<tb3>;
#define rep0(TIMES) for (int CNT = 0; CNT < (int)(TIMES); CNT++)
#define rep(CNT, GOAL) for (int CNT = 0; CNT < (int)(GOAL); CNT++)
#define rep2(CNT, START, GOAL) for (ll CNT = (ll)(START); CNT < (ll)(GOAL); CNT++)
#define rep3(CNT, START, GOAL) for (ll CNT = (ll)(START); CNT > (ll)(GOAL); CNT--)
#define all(CONT) begin(CONT), end(CONT)
#define fr1(CONT) next(begin(CONT)), end(CONT)
#define itrep(ITR, CONT) for (auto ITR = begin(CONT); ITR != end(CONT); ITR++)
#define itrep1(ITR, CONT) for (auto ITR = next(begin(CONT)); ITR != end(CONT); ITR++)
#define maxel(CONT) *max_element(all(CONT))
#define minel(CONT) *min_element(all(CONT))
template <typename T> bool chmax(T &a, const T &b) { if (a < b) {	a = b; return true;	}	return false; }
template <typename T> bool chmin(T &a, const T &b) { if (a > b) {	a = b; return true;	}	return false; }
template <typename T> T sum(const vector<T> &VEC) { return accumulate(all(VEC), 0.0); }
template <typename T> vector<T> acm(const vector<T> &VEC) { vector<T> RES(VEC.size() + 1); rep(CNT, VEC.size()) RES[CNT + 1] = RES[CNT] + VEC[CNT];	return RES; }
template <typename T> void fil(vector<T> &VEC, const int NUM, const T &VAL) { VEC.assign(NUM, VAL); }
template <typename T> void fil(vector<T> &VEC, const int NUM) { VEC.assign(NUM, 0.0); }
template <typename T> void fil(vector<vector<T>> &VV, const int RNUM, const int CNUM, const T &VAL) { fil(VV, RNUM, vector<T>()); rep(CNT, RNUM) fil(VV[CNT], CNUM, VAL); }
template <typename T> void fil(vector<vector<T>> &VV, const int RNUM, const int CNUM) { fil(VV, RNUM, vector<T>()); rep(CNT, RNUM) fil(VV[CNT], CNUM); }
template <typename T> void fil(vector<vector<T>> &VV, const int RNUM) { fil(VV, RNUM, vector<T>()); }
void prec(const int &DIG) { cerr << fixed << setprecision(DIG); cout << fixed << setprecision(DIG); }
template <typename T> void COUT(const T &ELEM) { cout << ELEM; }
template <typename T> void pout(const T &ELEM) { COUT(ELEM); cout << " "; }
template <typename T, typename ...Ts> void pout(const T &FIRST, const Ts &...REST) { pout(FIRST); pout(REST...); }
template <typename T> void print(T ELEM) { COUT(ELEM); cout << "\n"; }
template <typename T, typename ...Ts> void print(const T &FIRST, const Ts &...REST) { print(FIRST); print(REST...); }
void CERR() { cerr << "\n"; }
template <typename T> void CERR(const T &ELEM) { cerr << ELEM; }
template <typename T, typename ...Ts> void CERR(const T &FIRST, const Ts &...REST) { CERR(FIRST); cerr << ", "; CERR(REST...); }
template <typename T1, typename T2> void CERR(const pair<T1, T2> &PAIR) { cerr << "("; CERR(PAIR.first); cerr << ", "; CERR(PAIR.second); cerr << ")"; }
template <typename T1, typename T2, typename T3> void CERR(const tuple<T1, T2, T3> &TUP3) { cerr << "("; CERR(get<0>(TUP3)); cerr << ", "; CERR(get<1>(TUP3)); cerr << ", "; CERR(get<2>(TUP3)); cerr << ")"; }
template <typename T1, typename T2, typename T3, typename T4> void CERR(const tuple<T1, T2, T3, T4> &TUP4) { cerr << "("; CERR(get<0>(TUP4)); cerr << ", "; CERR(get<1>(TUP4)); cerr << ", "; CERR(get<2>(TUP4)); cerr << ", "; CERR(get<3>(TUP4)); cerr << ")"; }
template <typename T> void CERR(const vector<T> &VEC) { cerr << "{ "; itrep(ITR, VEC) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
template <typename T> void CERR1(const vector<T> &VEC) { cerr << "{ "; itrep1(ITR, VEC) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
template <typename T> void CERR(const set<T> &SET) { cerr << "{ "; itrep(ITR, SET) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
template <typename T1, typename T2> void CERR(const map<T1, T2> &MAP) { cerr << "{ "; itrep(ITR, MAP) { CERR(*ITR); cerr << ", "; } cerr << "}"; }
#define db(OBJ) cerr << #OBJ << ": "; CERR(OBJ); cerr << ", "
#define dbl(OBJ) cerr << #OBJ << ": "; CERR(OBJ); cerr << "\n"
#define db1(OBJ) cerr << #OBJ << ": "; CERR1(OBJ); cerr << "\n"
#define dbs(...) cerr << "(" << #__VA_ARGS__ << "): ("; CERR(__VA_ARGS__); cerr << ")\n"
#define dbvv(VV) cerr << #VV << ": {\n"; rep(CNT, VV.size()) { cerr << #VV << "[" << CNT << "]: "; CERR(VV[CNT]); cerr << ",\n"; } cerr << "}\n"
#define db01(VV) cerr << #VV << ": {\n"; rep(CNT, VV.size()) { cerr << #VV << "[" << CNT << "]: "; CERR1(VV[CNT]); cerr << ",\n"; } cerr << "}\n"
#define db10(VV) cerr << #VV << ": {\n"; rep2(CNT, 1, VV.size()) { cerr << #VV << "[" << CNT << "]: "; CERR(VV[CNT]); cerr << ",\n"; } cerr << "}\n"
#define db11(VV) cerr << #VV << ": {\n"; rep2(CNT, 1, VV.size()) { cerr << #VV << "[" << CNT << "]: "; CERR1(VV[CNT]); cerr << ",\n"; } cerr << "}\n"
#define YN(f) cout << (f ? "YES" : "NO") << "\n"
#define Yn(f) cout << (f ? "Yes" : "No") << "\n"
#define yn(f) cout << (f ? "yes" : "no") << "\n"
#define pcase(NUM) cout << "Case #" << NUM << ":" << " "
#define pcasel(NUM) cout << "Case #" << NUM << ":" << "\n"
const int INF = 1e9 + 7;
// db

using tdii = tuple<double, int, int>;

vi par; // par[i]: 要素iの親
vi dep; // dep[i]: 要素iが根であるときは，iを含む木の最も深い要素の(根を0とした)深さ(rank)。iが根であるといえなければ dep[root(i)] とする。
vi siz; // siz[i]: 要素iが根であるときは，iを含む木の大きさ(要素数，size)。iが根であるといえなければ siz[root(i)] とする。

int root(int x) {
	if (par[x] == x) return x;
	else return par[x] = root(par[x]); // 縮約
}

void unite(int x, int y) {
	x = root(x); y = root(y);
	if (x == y) return;
	if (dep[x] > dep[y]) { // xを根とする木の方が深い場合
		par[y] = x; // xが根となる
		siz[x] += siz[y];
	} else if (dep[x] < dep[y]) {
		par[x] = y;
		siz[y] += siz[x];
	} else { // 深さが等しい場合，xを根とすることとする
		par[y] = x;
		dep[x] ++;
		siz[x] += siz[y];
	}
}

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

void UF(int N) { // 0-ind，要素数Nでの初期化に使用する
	par.assign(N, -1); dep.assign(N, 0); siz.assign(N, 1);
	rep(i, N) par[i] = i; // 全ての要素につき自身が根であるとして初期化
}

// 最小全域木とする
void solve(int n) {
	// 0-ind
	vd x(n), y(n), z(n), r(n);
	rep(i, n) cin >> x[i] >> y[i] >> z[i] >> r[i];
	// dbv(x); dbv(y); dbv(z); dbv(r);
	priority_queue<tdii, vector<tdii>, greater<tdii>> q; // tdiiの第1要素の降順
	vvd g(n, vd(n)); // costmat;
	/* グラフ入力受取 */	
	rep(i, n - 1) rep2(j, 1, n)	{
		double d = max(sqrt(pow(x[j] - x[i], 2.0) + pow(y[j] - y[i], 2.0) + pow(z[j] - z[i], 2.0)) - (r[i] + r[j]), 0.0);
		q.push(tdii(d, i, j));
		g[i][j] = g[j][i] = d;
	}
	// dbvv(g);
	UF(n);
	int cnt = 0; // cnt: uniteの回数。N-K回行うとN-木森がK-木森になる
	double ans = 0.0;
	while (cnt < n - 1) {
		double d; int i, j; tie(d, i, j) = q.top(); q.pop();
		if (!same(i, j)) {			
			unite(i, j);
			cnt++;
			ans += d;
			// dbs(i, j, d, cnt, ans);
		}
	}
	print(ans);
}

int main() {
	prec(3);
	while (true) {
		int n; cin >> n;
		if (n) solve(n);
		else break;
	}	
}


Measured memory_bytes: 3500