Problem: A country Gizevom is being under a sneak and fierce attack by their foe. They have to deploy one or more troops to every base immediately in order to defend their country. Otherwise their foe would take all the bases and declare "All your base are belong to us."

You are asked to write a program that calculates the minimum time required for deployment, given the present positions and marching speeds of troops and the positions of the bases.



Input

The input consists of multiple datasets. Each dataset has the following format:

N M
x1 y1 v1
x2 y2 v2
...
xN yN vN
x'1 y'1
x'2 y'2
...
x'M y'M


N is the number of troops (1 ≤ N ≤ 100); M is the number of bases (1 ≤ M ≤ 100); (xi, yi ) denotes the present position of i-th troop; vi is the speed of the i-th troop (1 ≤ vi ≤ 100); (x'j, y'j) is the position of the j-th base.

All the coordinates are integers between 0 and 10000 inclusive.

The last dataset is followed by a line containing two zeros. This line is not a part of any dataset and should not be processed.

Output

For each dataset, print the minimum required time in a line.

Example

Input

2 2
10 20 1
0 10 1
0 10
10 0
0 0


Output

14.14213562

Solution (in CPP):

Solution:
#include <bits/stdc++.h>

#define FOR(i,a,b) for(int i= (a); i<((int)b); ++i)
#define RFOR(i,a) for(int i=(a); i >= 0; --i)
#define FOE(i,a) for(auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
#define BIT(n) (1LL<<(n))
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

typedef long long LL;
template<typename T> using V = std::vector<T>;
template<typename T> using VV = std::vector<std::vector<T>>;
template<typename T> using VVV = std::vector<std::vector<std::vector<T>>>;
template<class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
template<class T> inline void print(T x) { std::cout << x << std::endl; }
template<class T> inline bool inside(T y, T x, T H, T W) {return 0 <= y and y < H and 0 <= x and x < W; }
inline double distance(double y1, double x1, double y2, double x2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); }

const int INF = 1L << 30;
const double EPS = 1e-9;
const std::string YES = "YES", Yes = "Yes", NO = "NO", No = "No";
const std::vector<int> dy = { 0, 1, 0, -1 }, dx = { 1, 0, -1, 0 };    // 4近傍（右, 下, 左, 上）

using namespace std;

struct Edge {
    const int to;         // 行き先のノードid
    int flow;             // 流量
    const int cap;        // 容量
    const int rev;        // 逆辺のノードid
    const bool is_rev;    // 逆辺かどうか
    Edge(int to, int flow, int cap, int rev, bool is_rev) : to(to), flow(flow), cap(cap), rev(rev), is_rev(is_rev) {
        assert(this->cap >= 0);
    }
};

// 最大流問題をO(F|E|)で解く
class FordFulkerson {
public:
    const unsigned int num_of_node = 0;   // ノード数
    map<int, vector<Edge>> G;             // グラフの隣接リスト表現

    FordFulkerson(unsigned int num_of_node) : num_of_node(num_of_node) {
    }

    // fromからtoへ向かう容量capの辺とその逆辺をグラフに追加する
    void add_edge(int from, int to, int cap) {
        this->G[from].emplace_back(Edge(to, 0, cap, (int)this->G[to].size(), false));          // 辺
        this->G[to].emplace_back(Edge(from, cap, cap, (int)this->G[from].size() - 1, true));   // 逆辺
    }

    // sからtへの最大流を求める O(F|E|)
    int max_flow(int s, int t) {
        int flow = 0;
        while (true) {
            vector<bool> used(this->num_of_node, false); // DFSですでに調べたかのフラグ
            int f = dfs(s, t, INT_MAX, used);
            if (f == 0) { return flow; }
            flow += f;
        }
    }

    // 水の流れたエッジを取得する
    set<pair<int, int>> get_used_edges() {
        set<pair<int, int>> used_edges;

        for (auto p : this->G) {
            int from = p.first;
            for (Edge edge : p.second) {
                int flow = edge.flow;
                bool is_rev = edge.is_rev;

                if (not is_rev and flow > 0) {
                    int to = edge.to;
                    used_edges.insert(make_pair(from , to));
                }
            }
        }
        return used_edges;
    }

private:
    // vからtへf流したときの流れた量
    int dfs(int from, int to, int f, vector<bool> &used) {
        if (from == to) { return f; }
        used[from] = true;
        for (Edge &e : G[from]) {
            int rest = e.cap - e.flow;
            if (!used[e.to] && rest > 0) {
                int d = dfs(e.to, to, min(f, rest), used);
                if (d > 0) {
                    e.flow += d;                 // 辺
                    G[e.to][e.rev].flow -= d;    // 逆辺
                    return d;
                }
            }
        }
        return 0;
    }

};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (true) {
        int N, M;
        cin >> N >> M;
        if (N == 0 and M == 0) { break; }

        V<tuple<int, int, int>> troops;
        FOR(i, 0, N) {
            int x, y, v;
            cin >> x >> y >> v;
            troops.emplace_back(make_tuple(x, y, v));
        }
        V<tuple<int, int>> bases;
        FOR(i, 0, M) {
            int x, y;
            cin >> x >> y;
            bases.emplace_back(make_tuple(x, y));

        }

        V<tuple<int, int, double>> data;    // 軍i、基地j、時間
        FOR(i, 0, troops.size()) {
            FOR(j, 0, bases.size()) {
                int x1, y1, v1, x2, y2;
                tie(x1, y1, v1) = troops[i];
                tie(x2, y2) = bases[j];
                double t = distance(y1, x1, y2, x2) / (1.0 * v1);
                data.emplace_back(make_tuple(i, troops.size() + j, t));
            }
        }

        // [low, high)
        double low = -1, high = INF - 1, ans = -1;
        FOR(_, 0, 100) {
            double middle = (low + high) / 2.0;

            FordFulkerson ff(N + M + 2);
            FOE(a, data) {
                int i, j;
                double t;
                tie(i, j, t) = a;
                if (t < middle + EPS) {
                    ff.add_edge(i, j, 1);
                }
            }
            int source = N + M;
            int sink = source + 1;

            FOR(i, 0, N) {
                ff.add_edge(source, i, 1);
            }
            FOR(j, 0, M) {
                ff.add_edge(N + j, sink, 1);
            }

            int flow = ff.max_flow(source, sink);

            if (flow == M) {
                ans = middle;
                high = middle;
            }
            else {
                low = middle;
            }
        }
        printf("%.10f\n", ans);
    }

    return 0;
}