#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>

using namespace std;

typedef double elem;

struct node{
  elem x,y,z,r;
  vector<int> con;
  vector<elem> cost;
};

struct edge{
  int src;
  int dst;
  elem cost;
  edge(int s, int d, elem c):src(s),dst(d),cost(c){}
  bool operator>(const edge &e)const{
    return cost>e.cost;
  }
};

elem dist(const node &a, const node &b){
  double ret = sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0)+pow(a.z-b.z,2.0))-a.r-b.r;
  if(ret<0)ret=0;
  return ret;
}

typedef vector<node> Graph;

elem MST(Graph &G){
  bool vis[G.size()];
  elem ret=0;
  for(int i = 0; i <(int)G.size(); ++i)vis[i]=false;
  priority_queue<edge,vector<edge>,greater<edge> > Q;
  Q.push( edge(-1,0,0) );
  while(!Q.empty()){
    edge e = Q.top(); Q.pop();
    if( vis[e.dst] ) continue;
    ret+=e.cost;
    vis[e.dst]=true;
    for(int i=0;i<(int)G[e.dst].con.size();++i){
      if(!vis[G[e.dst].con[i]]){
	Q.push(edge(e.dst,G[e.dst].con[i],G[e.dst].cost[i]));
      }
    }
  }
  return ret;
}

int main()
{
  while(true){
    int n;
    cin >> n;
    if(n==0)break;
    Graph G;
    for(int i = 0; i < n; ++i){
      node t;
      cin >> t.x >> t.y >> t.z >> t.r;
      G.push_back(t);
    }
    for(int i = 0; i < n; ++i){
      for(int j = i+1; j < n; ++j){
	elem d = dist(G[i],G[j]);
	G[i].con.push_back(j);
	G[j].con.push_back(i);
	G[i].cost.push_back(d);
	G[j].cost.push_back(d);
      }
    }

    cout.precision(3);
    cout << fixed << MST(G) << endl;
  }
  return 0;
}