#include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
#define pr(...) GET_MACRO(__VA_ARGS__,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__)
#define pr1(a) (#a)<<"="<<(a)
#define pr2(a,b) pr1(a)<<", "<<pr1(b)
#define pr3(a,b,c) pr2(a,b)<<", "<<pr1(c)
#define pr4(a,b,c,d) pr3(a,b,c)<<", "<<pr1(d)
#define pr5(a,b,c,d,e) pr4(a,b,c,d)<<", "<<pr1(e)
#define int long long
#define double long double
using namespace std;
const int N = 100010;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
typedef pair<int,int> P;
typedef long long ll;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
ostream& operator<<(ostream& o,P p){return o<<"("<<p.first<<","<<p.second<<")";}
istream& operator>>(istream& i,P &p){return i>>p.first>>p.second;}
ostream& operator<<(ostream& o,vector<auto> &a){int i=0;for(auto t:a)o<<(i++?" ":"")<<t;return o;}
istream& operator>>(istream& i,vector<auto> &a){for(auto &t:a)i>>t;return i;}
void prArr(auto a,string s=" "){int i=0;for(auto t:a)cout<<(i++?s:"")<<t;cout<<endl;}

/*最小費用流(ワーシャルフロイド使用) O(F|V||E|)*/
class MinCostFlow{
public:
  //辺を表す構造体(行き先、容量、コスト、逆辺)
  typedef double ctype;
  ctype INF = 1LL<<55;

  struct edge{
    int to,cap;
    ctype cost;
    int rev;
    edge();
    edge(int to,int cap,ctype cost,int rev):to(to),cap(cap),cost(cost),rev(rev){}
  };
  
  int V;                          //頂点数
  vector<vector<edge> > G;        //グラフの隣接リスト表現
  vector<ctype> dist;             //最短距離
  vector<int> prevv,preve;        //直前の頂点と辺

  MinCostFlow():V(-1){}
  MinCostFlow(int V):V(V), G(V), dist(V), prevv(V), preve(V){};
  
  // fromからtoへ向かう容量cap、コストcostの辺をグラフに追加する。
  void add_edge(int from,int to,int cap ,ctype cost){
    assert(from>=0 && to >= 0);
    assert(from<V && to<V);
    G[from].push_back((edge){to,cap,cost,(int)G[to].size()});
    G[to].push_back((edge){from,0,-cost,(int)G[from].size()-1});
  }
  
  //sからtへの流量fの最小費用流を求める
  //流せない場合-1を返す
  ctype flow(int s, int t, int f){
    ctype res = 0;

    while(f>0){
      //ベルマンフォード法により,s-t間最短路を求める
      fill(dist.begin(),dist.end(),INF);
      dist[s] = 0;
      bool update = true;
      while(update){
        update = false;
        for(int v=0; v<V ;v++){
          if(dist[v]==INF) continue;
          for(int i=0; i<(int)G[v].size(); i++){
            edge &e = G[v][i];
            if(e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
              if(abs(dist[e.to] - dist[v] - e.cost) < EPS) continue;
              dist[e.to] = dist[v] + e.cost;
              prevv[e.to] = v;
              preve[e.to] = i;
              update = true;
            }
          }
        }
      }

      if(dist[t]==INF) return -1; //これ以上流せない。
    
      //s−t間短路に沿って目一杯流す
      int d = f;
      for(int v=t; v!=s; v=prevv[v]) d = min(d, G[prevv[v]][preve[v]].cap);
      f -= d;
      res += d * dist[t];
      for(int v=t; v!=s; v=prevv[v]){
        edge &e = G[prevv[v]][preve[v]];
        e.cap -= d;
        G[v][e.rev].cap += d;
      }
    }
    return res;
  }
};



signed main(){
  while(1){
  int n,K;
  cin>>n>>K;
  if(n == 0 && K == 0) return 0;
  Min(K,n);
  
  vector<double> X(n),Y(n),Z(n);
  for(int i=0;i<n;i++) cin>>X[i]>>Y[i]>>Z[i];

  MinCostFlow mcf(2 * n + 10);
  const int S = mcf.V-1, T = S - 1;
  
  const double inf = 1e7;
  for(int i=0;i<n;i++) mcf.add_edge(S,i,1,0);
  for(int i=0;i<n;i++) mcf.add_edge(i,n+i,1,-inf);
  for(int i=0;i<n;i++) mcf.add_edge(n+i,T,1,0); 

  auto dis=[&](int i,int j){
    double x = X[i] - X[j];
    double y = Y[i] - Y[j];
    double z = Z[i] - Z[j];
    return sqrt(x * x + y * y + z * z);
  };

  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++){
      if(Z[i] <= Z[j]) continue;
      double d = dis(i,j);
      mcf.add_edge(n + i, j, 1, d);
    }

  double c = mcf.flow(S,T,K);
  if(c == -1) {cout<<-1<<endl;return 0;}
  
  double ans = c + n * inf;
  if(ans >= inf) cout<<-1<<endl;
  else printf("%.10Lf\n",ans);
  
  }
  return 0;
}



Measured memory_bytes: 3772