// 参考: http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2137009#1
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <memory>  // unique_ptr
#include <cmath>
#include <iomanip>

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#ifdef _DEBUG_
#define dump(val) cerr << __LINE__ << ":\t" << #val << " = " << (val) << endl
#else
#define dump(val)
#endif

using namespace std;

typedef long long int ll;

template<typename T>
vector<T> make_v(size_t a, T b) {
    return vector<T>(a, b);
}
template<typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

template<class T>
class kdTree {
    using VV = vector<vector<T>>;
    vector<T> vec;
    int axis;
    unique_ptr<kdTree> ltree, rtree;
    void make_tree(VV &v, int l, int r, int depth = 0) {
        if (l >= r) return;
        int mid = (l + r) / 2;
        axis = depth % v[mid].size();
        auto cmp = [&](vector<T> &a, vector<T> &b) -> bool {
            return a[axis] < b[axis];
        };
        nth_element(v.begin() + l, v.begin() + mid, v.begin() + r, cmp);
        ltree = kdTree::get_tree(v, l, mid, depth + 1);
        rtree = kdTree::get_tree(v, mid + 1, r, depth + 1);
        vec = v[mid];
    }
    T dist(vector<T> &d1, vector<T> &d2) {
        T ans = T();
        REP(i, 0, d1.size()) {
            ans += pow(d1[i] - d2[i], 2.0);
        }
        return sqrt(ans);
    }
    static unique_ptr<kdTree> get_tree(VV &v, int l, int r, int depth) {
        if (l >= r) {
            return nullptr;
        } else {
            return make_unique<kdTree>(v, l, r, depth);
        }
    }
public:
    kdTree(VV &v): kdTree(v, 0, v.size(), 0) {}
    kdTree(VV &v, int l, int r, int depth) {
        make_tree(v, l, r, depth);
    }
    void nearest(vector<T> &query, double &ans) {
        ans = min(ans, dist(vec, query));
        if (query[axis] <= vec[axis]) {
            if (ltree) {
                ltree->nearest(query, ans);
            }
            if (vec[axis] - query[axis] >= ans) return;
            if (rtree) {
                rtree->nearest(query, ans);
            }
        } else {
            if (rtree) {
                rtree->nearest(query, ans);
            }
            if (query[axis] - vec[axis] >= ans) return;
            if (ltree) {
                ltree->nearest(query, ans);
            }
        }
    }
};

double dist(vector<double> &v1, vector<double> &v2) {
    double ans = 0.0;
    REP (i, 0, v1.size()) {
        ans += pow(v1[i] - v2[i], 2);
    }
    return sqrt(ans);
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n, q;
    while (cin >> n >> q, n + q) {
        auto p = make_v(n, 3, 0.0);
        REP(i, 0, n) {
            REP(j, 0, 3) {
                cin >> p[i][j];
            }
        }
        kdTree<double> kdtree(p);
        REP(Q, 0, q) {
            int m;
            cin >> m;
            double ans = 0.0;
            vector<double> prev(3), curr(3);
            REP(i, 0, 3) {
                cin >> prev[i];
            }
            REP(i, 1, m) {
                REP (j, 0, 3) {
                    cin >> curr[j];
                }
                double ans1 = 1e+15, ans2 = 1e+15;
                kdtree.nearest(prev, ans1);
                kdtree.nearest(curr, ans2);
                ans += min(dist(curr, prev), ans1 + ans2);
                prev = curr;
            }
            cout << fixed << setprecision(10) << ans << endl;
        }
    }

    return 0;
}



Measured memory_bytes: 17664