#include<iostream>
#include<climits>
#include<cassert>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<functional>
#include<iomanip>
#include<cstdio>
#include<set>

using namespace std;

const double inf = 1e80;

struct point3d{

  long long x,y,z;

  point3d():x(0),y(0),z(0){}
  point3d(long long x, long long y, long long z):x(x),y(y),z(z){}

  inline bool compare(int d, const point3d &t) const {
    if( d == 0 ){
      return x < t.x;
    }else if( d == 1 ){
      return y < t.y;
    }else if( d == 2 ){
      return z < t.z;
    }
    return false;
  }

  inline bool operator<(const point3d &t) const {
    if(x!=t.x)return x<t.x;
    if(y!=t.y)return y<t.y;
    if(z!=t.z)return z<t.z;
    return false;
  }
  
  inline long long dist2(const point3d &t) const {
    long long ret = (x-t.x)*(x-t.x) + (y-t.y) * (y-t.y) + (z-t.z) * (z-t.z);
    return ret;
  }

  inline long long ddist2(int d, const point3d &t)const{
    if( d == 0 ){
      return (x-t.x) * (x-t.x);
    }else if( d == 1 ){
      return (y-t.y) * (y-t.y);
    }else if( d == 2 ){
      return (z-t.z) * (z-t.z);
    }return 0;
  }
  
};

inline bool comp_x(const point3d &a, const point3d &b){return a.x<b.x;}
inline bool comp_y(const point3d &a, const point3d &b){return a.y<b.y;}
inline bool comp_z(const point3d &a, const point3d &b){return a.z<b.z;}


long long call = 0;

struct kdtree{

  struct node{
    point3d p;
    node *l;
    node *r;
    node(const point3d &p) : p(p), l(NULL), r(NULL){}
  }*root;

  kdtree() : root(NULL) { }

  void insert(const point3d &p){
    root = insert( root, 0, p );
  }

  node *insert(node *t, int d, const point3d &p){
    ++call;
    if( t == NULL ) return new node(p);
    if( p.compare(d,t->p) )
      t->l = insert(t->l, (d+1)%3, p);
    else
      t->r = insert(t->r, (d+1)%3, p);
    return t;
  }

  node * build(int d, point3d ps[], int l, int r){
    if(l+1==r){
      return new node(ps[l]);
    }
    if(d==0){
      sort(ps+l,ps+r,comp_x);
    }else if(d==1){
      sort(ps+l,ps+r,comp_y);
    }else if(d==2){
      sort(ps+l,ps+r,comp_z);
    }
    int m = (l+r)/2;
    node * ret = new node(ps[m]);
    if(m>l)
      ret->l = build((d+1)%3,ps,l,m);
    if(r>m+1)
      ret->r = build((d+1)%3,ps,m+1,r);
    return ret;
  }

  long long best;
  node * best_near;
  point3d nearest(const point3d &p){
    best = 1LL<<55;
    best_near = NULL;
    nearest(root,0,p);
    return best_near->p;
  }
  
  void nearest(node *cur, int d, const point3d &p){
    ++call;
    bool bc = p.compare(d,cur->p);
    node * next      = bc ? cur->l : cur->r;
    node * next_anoc = bc ? cur->r : cur->l;

    // refresh
    if( best > p.dist2(cur->p) ){
      best = p.dist2(cur->p);
      best_near = cur;
    }

    // down
    if( next ){
      nearest(next,(d+1)%3, p);
    }

    // refresh
    if( best > p.dist2(cur->p) ){
      best = p.dist2(cur->p);
      best_near = cur;
    }
    
    if( best >= p.ddist2(d,cur->p) ){
      // down another
      if( next_anoc ){
        nearest(next_anoc, (d+1)%3, p);
      }
    }
    
    // up
    return ;
  }

  void calc_depth(node *t, int cur_depth, int &depth){
    depth=max(depth,cur_depth);
    if(t==NULL)return ;
    calc_depth(t->l,cur_depth+1,depth);
    calc_depth(t->r,cur_depth+1,depth);
  }

};

namespace std{
  ostream &operator<<(ostream &o, const point3d &t){
    o << '(' << t.x << ',' << t.y << ',' << t.z <<')';
    return o;
  }
}

int main()
{
  int n,q;
  // while( scanf("%d%d", &n, &q) != EOF ){
  while(cin >> n >> q){
    if( n == 0 && q == 0 ) break;
    kdtree kd;
    point3d *ary = new point3d[n];
    
    for(int i = 0; i < n; ++i){
      cin >> ary[i].x >> ary[i].y >> ary[i].z;
    }
    kd.root = kd.build(0,ary,0,n);

    // m q n^(2/3)

    // int depth = 0;
    // kd.calc_depth(kd.root,0,depth);
    // cout <<"Depth : " << depth << endl;

    call = 0;
    int m;
    for(int qq = 0; qq < q; ++qq){
      double res = 0;
      vector<point3d> route;

      // scanf("%d", &m);
      cin >> m;

      for(int i = 0; i < m; ++i){
        int x,y,z;
        // scanf("%d %d %d", &x, &y, &z);
        cin >> x >> y >> z;
        route.push_back(point3d(x,y,z));
      }


      for(int i = 0; i < (int)route.size()-1; ++i){
        point3d cur = route[i];
        point3d next = route[1+i];
        
        // call = 0;
        point3d nw1 = kd.nearest( cur );
        point3d nw2 = kd.nearest( next );

        // cout << call << ' ' << 2*3*pow(n,0.66666) << endl;
        
        double d0 = sqrt( cur.dist2(next) );
        double d1 = sqrt( cur.dist2(nw1) );
        double d2 = sqrt( next.dist2(nw2) );
        double d = min( d0, d1 + d2 );
        res += d;
        
      }
      
      printf("%.9lf\n", res);
    }
    
    // 11006221817
    // 1.29e09 = 1290000000

    // cout << "Total Call 2 : " << call << ' ' << m*q*2*(long long)3*pow(n,0.66666) << endl;
    // cout << "(ratio): " << (call / (double)(2*m*q*lgn) * 100) << " %" << endl;
  }
  return 0;
}

Measured memory_bytes: 8280