#include <iostream>
#include <cmath>
#include <vector>
#include <queue>
#include <iomanip>
#include <algorithm>
using namespace std;

typedef pair<double, double> Pd;
typedef pair<double, Pd> PPd;

int par[200];
int ran[200];
double x[200];
double y[200];
double z[200];
double r[200];

void init(int n){
  for(int i = 0; i < n; i++){
    par[i]  = i;
    ran[i] = 0;
  }
}

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

void unite(int x, int y){
  x = find(x);
  y = find(y);
  if(x == y) return ;
  if(ran[y] > ran[x]){
    par[x] = y;
  }else{
    par[y] = x;
    if(ran[y] == ran[x]) ran[x]++;
  }
}

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

int main(){
  int n;
  while(cin >> n && n){
    for(int i = 0; i < n; i++){
      scanf("%lf%lf%lf%lf", &x[i], &y[i], &z[i], &r[i]);
    }
    init(n);
    priority_queue<PPd, vector<PPd>, greater<PPd> > que;
    for(int i = 1; i < n; i++){
      for(int j= 0; j < i; j++){
	double dx = x[i] - x[j];
	double dy = y[i] - y[j];
	double dz = z[i] - z[j];
	que.push(PPd(sqrt(dx*dx + dy*dy + dz*dz) - r[i] - r[j], Pd(i, j)));
      }
    }
    double res = 0;
    while(!que.empty()){
      PPd ppd = que.top();
      que.pop();
      if(!same(ppd.second.first, ppd.second.second)){
	unite(ppd.second.first, ppd.second.second);
	res += max(0.0, ppd.first);
      }
    }
    cout << fixed << setprecision(3) << res << endl;
  }
  return 0;
}