import core.stdc.string;
import std.algorithm;
import std.array;
import std.ascii;
import std.container;
import std.conv;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.random;
import std.typecons;
void log(A...)(A arg) { stderr.writeln(arg); }
int size(T)(in T s) { return cast(int)s.length; }
static const EPS = 1e-7;

struct Point {
        double x, y;
        Point opBinary(string op)(in Point p) const if (op == "+" || op == "-") {
            return Point(mixin("x" ~ op ~ "p.x"), mixin("y" ~ op ~ "p.y"));
        }
        Point opBinary(string op)(double k) const if (op == "*" || op == "/") {
            return Point(mixin("x" ~ op ~ "k"), mixin("y" ~ op ~ "k"));
        }
        Point opBinaryRight(string op)(double k) const if (op == "*") {
            return this * k;
        }
};
double dot(in Point a, in Point b) { return a.x * b.x + a.y * b.y; }
double cross(in Point a, in Point b) { return a.x * b.y - a.y * b.x; }
double dist_sq(in Point a, in Point b) { return dot(b - a, b - a); }
double norm(in Point a) { return sqrt(dot(a, a)); }
Point rot90(in Point p) { return Point(-p.y, p.x); }
double angle(in Point a) { return atan2(a.y, a.x); }
struct Circle {
        Point p;
        double r;
};
bool contains(in Circle c, in Point p, double eps = EPS) { return dist_sq(c.p, p) <= c.r * c.r + eps; }
bool contains(in Circle a, in Circle b, double eps = EPS) { 
    if (a.r < b.r) return false;
    return dist_sq(a.p, b.p) <= (a.r - b.r) * (a.r - b.r) + eps; 
}
bool intersects(in Circle a, in Circle b, double eps = EPS) {
    if (contains(a, b, eps) || contains(b, a, eps)) return false;
    return dist_sq(a.p, b.p) <= (a.r + b.r) * (a.r + b.r) + eps;
}
Point[] crosspoints(Circle a, Circle b) {
    if (a.r < b.r) swap(a, b);
    double R = a.r;
    double r = b.r;
    double d = norm(b.p - a.p);
    double x = (R * R - r * r + d * d) / (2 * d);
    double y = sqrt(R * R - x * x);
    Point v = (b.p - a.p) / norm(b.p - a.p);
    Point u = v.rot90();
    Point p = a.p + v * x;
    return [p - y * u, p + y * u];
}
int ccw(Point a, Point b, Point c){
    b = b - a; c = c - a;                                          
    if (cross(b, c) > EPS) return +1; 
    if (cross(b, c) < -EPS) return -1;
    if (dot(b, c) < 0) return +2;
    if (norm(b) < norm(c)) return -2;
    return 0;                          
}

void main() {
    int N, M;
    Point[] ps;
    int[] srcs, dsts; double[] vs;
    bool input() {
        readf("%d %d\n", &N, &M);
        if (N == 0 && M == 0) return false;
        ps = new Point[N];
        foreach (i; 0 .. N) {
            double x, y; readf("%f %f\n", &x, &y);
            ps[i] = Point(x, y);
        }
        srcs = new int[M];
        dsts = new int[M];
        vs = new double[M];
        foreach (i; 0 .. M) {
            readf("%d %d %f\n", &srcs[i], &dsts[i], &vs[i]);
            srcs[i]--;
            dsts[i]--;
        }
        return true;
    }

    void solve() {
        struct T {
            Point src, dst;
            double v;
        }

        auto gen = Random(15);
        double solve_sub(in T[] pairs) {
            auto cs = pairs.map!((p) => Circle(p.src, norm(p.dst - p.src))).array;
            long m = cs.length;
            Point[] corners;
            for (int i = 0; i < m; i++) {
                bool intersect = false;
                for (int j = i + 1; j < m; j++) {
                    if (! cs[i].intersects(cs[j])) continue;
                    intersect = true;
                    auto cps = cs[i].crosspoints(cs[j]);
                    foreach (cp; cps) {
                        auto dx = uniform(-(1<<16), 1<<16, gen);
                        auto dy = uniform(-(1<<16), 1<<16, gen);
                        auto d = Point(dx, dy) / norm(Point(dx, dy)) * EPS;
                        corners ~= cp + d;
                    }
                    corners ~= cps;
                }
                if (!intersect) corners ~= cs[i].p;
            }

            bool[long] map;
            foreach (p; corners) {
                long bit = 0;
                foreach (j, c; pairs) {
                    if (dist_sq(c.src, p) <= dist_sq(c.src, c.dst) + EPS) {
                        bit |= 1L << j;
                    }
                }
                map[bit] = true;
            }

            Point[] warp_cs; // warp point candidates
            auto as = map.keys;
            foreach (a; as) {
                double den = 0;
                double x_num = 0, y_num = 0;
                foreach (i; 0 .. m) if (a & (1L << i)) {
                    double v = pairs[i].v;
                    auto src = pairs[i].src;
                    auto dst = pairs[i].dst;
                    double d = v * v;
                    den += 1.0L / d;
                    x_num += src.x / d;
                    y_num += src.y / d;
                }
                warp_cs ~= Point(x_num / den, y_num / den);
                next:;
            }

            double cost(in Point a, int i) { // from i-th start to 'a'
                auto z = a - pairs[i].src;
                auto v = pairs[i].v;
                return dist_sq(a, pairs[i].src) / (v * v);
            }

            double ans = 1e10;
            foreach (a; warp_cs) {
                double cand = 0;
                foreach (int i, p; pairs) {
                    cand += min(cost(a, i), cost(p.dst, i));
                }
                ans = min(ans, cand);
            }
            return ans;
        }

        double ans = 1e10;
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                auto cs = new T[][2];
                auto x = ps[i];
                auto y = ps[j];
                auto u = (y - x) / norm(y - x);
                auto coef_a = 1e-5, coef_b = sqrt(3.0) * 1e-5;
                Point s = x + coef_a * u.rot90, t = y - coef_b * u.rot90;
                foreach (int k; 0 .. M) {
                    auto src = ps[ srcs[k] ];
                    auto dst = ps[ dsts[k] ];
                    auto v = vs[k];
                    cs[ccw(s, t, src) > 0 ? 0 : 1] ~= T(src, dst, v);
                }
                ans = min(ans, ((solve_sub(cs[0]) + solve_sub(cs[1])) / M).sqrt);
            }
        }
        writefln("%.9f", ans);
    }
    while (input()) solve();
}

Measured memory_bytes: 4416