Problem: Klein is trying to get her dog Jack into the Frisbee Dog Tournament. But she's not sure if Jack will get a good grade. For her, she simulates the tournament to get Jack's grade. I want you to create a program to estimate.

The tournament is held by N dogs on a two-dimensional plane. At the start of the tournament, the i-th dog is in the (Dix, Diy) position. The i-th dog is Vi [m / s] All dogs are small enough to be considered points. At any given time, two or more dogs may be in the same position.

The tournament begins with the launch of the first Frisbee, from which the dogs are allowed to move. Frisbee can also be considered a point, the i Frisbee from the (FPix, FPiy) position ( FVix, FViy) Fired at a velocity vector of [m / s] and continues a constant velocity linear motion. When a dog's position and a Frisbee's position are equal, the dog can get a Frisbee.

The moment the first Frisbee is acquired by one of the dogs, the second Frisbee is fired. The moment the second Frisbee is acquired, the third is fired, and so on. Immediately after, the next Frisbee will be fired. The tournament will end when the Mth Frisbee is acquired.

Needless to say, the dogs' goal is to get more Frisbee. Dogs take the following strategies.

When the Frisbee is fired, the dog moves to get it at the earliest possible time and gets the Frisbee. However, if it cannot get the Frisbee, it waits where it is.

The determination of whether a dog can get a frisbee is made regardless of the behavior of the other dog. That is, one dog moves to get a frisbee, but the other dog gets it first. The moment one of the dogs gets the Frisbee and a new Frisbee is launched, the dogs take the above strategy against the new Frisbee.

The program you create must output the number of Frisbees obtained by each dog.



Input

The input file consists of multiple datasets.

The first row of the dataset gives the number of dogs N (1 ≤ N ≤ 10) and the number of Frisbees M (1 ≤ M ≤ 1000).

The following N lines are given the dog's initial position and velocity Dix, Diy, Vi, separated by a single blank.

The following M lines are given the Frisbee launch position and velocity FPix, FPiy, FVix, FViy, separated by a single space character.

The coordinate values ​​given are real numbers and their absolute values ​​do not exceed 1000. The speeds given are real numbers 1 ≤ DVi ≤ 100, -25 ≤ FVix, FViy ≤ 25. Frisbees that cannot be obtained by any dog You can assume that there is no.

When a dog with any Frisbee was obtained at time t, no dog could get it before time t + 1e-6.

During the simulation, the absolute values ​​of the dog's x and y coordinates do not exceed 1e + 8.

When both N and M are 0, the end of input is indicated.

Output

Output the number of Frisbees obtained by each dog on one line separated by a space character. The order of output must be the same as the order given in the input.

Example

Input

2 1
12 5 3
0 17 3
0 0 2 2
2 3
2 0 2
100 100 2
0 0 -1 0
-2 -5 0 3
100 100 1 1
0 0


Output

1 0
2 1

Solution (in CPP):

Solution:
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s << endl; }



typedef long double DD;

const DD INF = 1LL<<60;
const DD EPS = 1e-7;
const DD PI = acos(-1.0);
DD torad(int deg) {return (DD)(deg) * PI / 180;}
DD todeg(DD ang) {return ang * 180 / PI;}

struct Point {
    DD x, y;
    Point(DD x = 0.0, DD y = 0.0) : x(x), y(y) {}
    friend ostream& operator << (ostream &s, const Point &p) {return s << '(' << p.x << ", " << p.y << ')';}
};

Point operator + (const Point &p, const Point &q) {return Point(p.x + q.x, p.y + q.y);}
Point operator - (const Point &p, const Point &q) {return Point(p.x - q.x, p.y - q.y);}
Point operator * (const Point &p, DD a) {return Point(p.x * a, p.y * a);}
Point operator * (DD a, const Point &p) {return Point(a * p.x, a * p.y);}
Point operator * (const Point &p, const Point &q) {return Point(p.x * q.x - p.y * q.y, p.x * q.y + p.y * q.x);}
Point operator / (const Point &p, DD a) {return Point(p.x / a, p.y / a);}
Point conj(const Point &p) {return Point(p.x, -p.y);}
Point rot(const Point &p, DD ang) {return Point(cos(ang) * p.x - sin(ang) * p.y, sin(ang) * p.x + cos(ang) * p.y);}
Point rot90(const Point &p) {return Point(-p.y, p.x);}
DD cross(const Point &p, const Point &q) {return p.x * q.y - p.y * q.x;}
DD dot(const Point &p, const Point &q) {return p.x * q.x + p.y * q.y;}
DD norm(const Point &p) {return dot(p, p);}
DD abs(const Point &p) {return sqrt(dot(p, p));}
DD amp(const Point &p) {DD res = atan2(p.y, p.x); if (res < 0) res += PI*2; return res;}
bool eq(const Point &p, const Point &q) {return abs(p - q) < EPS;}
bool operator < (const Point &p, const Point &q) {return (abs(p.x - q.x) > EPS ? p.x < q.x : p.y < q.y);}
bool operator > (const Point &p, const Point &q) {return (abs(p.x - q.x) > EPS ? p.x > q.x : p.y > q.y);}
Point operator / (const Point &p, const Point &q) {return p * conj(q) / norm(q);}

struct Line : vector<Point> {
    Line(Point a = Point(0.0, 0.0), Point b = Point(0.0, 0.0)) {
        this->push_back(a);
        this->push_back(b);
    }
};


struct Circle : Point{
    DD r;
    Circle(Point p = Point(0.0, 0.0), DD r = 0.0) : Point(p), r(r) {}
};

Point proj(Point p, Line l) {
    DD t = dot(p - l[0], l[1] - l[0]) / norm(l[1] - l[0]);
    return l[0] + (l[1] - l[0]) * t;
}
vector<Point> crosspoint(Line l, Line m) {
    vector<Point> res;
    DD d = cross(m[1] - m[0], l[1] - l[0]);
    if (abs(d) < EPS) return vector<Point>();
    res.push_back(l[0] + (l[1] - l[0]) * cross(m[1] - m[0], m[1] - l[0]) / d);
    return res;
}
vector<Point> crosspoint(Circle e, Circle f) {
    vector<Point> res;
    DD d = abs(e - f);
    if (d < EPS) return vector<Point>();
    DD rcos = (d * d + e.r * e.r - f.r * f.r) / (2.0 * d);
    DD rsin = sqrt(e.r * e.r - rcos * rcos);
    Point dir = (f - e) / d;
    Point p1 = e + dir * Point(rcos, rsin);
    Point p2 = e + dir * Point(rcos, -rsin);
    res.push_back(p1);
    if (!eq(p1, p2)) res.push_back(p2);
    return res;
}
vector<Point> crosspoint(Circle e, Line l) {
    vector<Point> res;
    Point p = proj(e, l);
    DD rcos = abs(e - p), rsin;
    if (rcos > e.r + EPS) return vector<Point>();
    else if (e.r - rcos < EPS) rsin = 0;
    else rsin = sqrt(e.r * e.r - rcos * rcos);
    Point dir = (l[1] - l[0]) / abs(l[1] - l[0]);
    Point p1 = p + dir * rsin;
    Point p2 = p - dir * rsin;
    res.push_back(p1);
    if (!eq(p1, p2)) res.push_back(p2);
    return res;
}



const int MAX_N = 15;
const int MAX_M = 2000;
int res[MAX_N];

Point pd[MAX_N];
DD vd[MAX_N];
Point pf[MAX_M];
DD vxf[MAX_M], vyf[MAX_M], vf[MAX_M];

int n, m;


// 1：a-bから見てcは左側(反時計回り)、-1：a-bから見てcは右側(時計回り)
// 2：c-a-bの順に一直線上、-2：a-b-cの順に一直線上、0：a-c-bの順に一直線上
int ccw(const Point &a, const Point &b, const Point &c) {
    if (cross(b-a, c-a) > EPS) return 1;
    if (cross(b-a, c-a) < -EPS) return -1;
    if (dot(b-a, c-a) < 0) return 2;
    if (norm(b-a) < norm(c-a)) return -2;
    return 0;
}

Circle Apporonius(Point p, Point q, DD a, DD b) {
    if ( abs(a-b) < EPS ) return Circle(Point(0,0),0);
    Point c1 = (p * b + q * a) / (a + b);
    Point c2 = (p * b - q * a) / (b - a);
    Point c = (c1 + c2) / 2;
    DD r = abs(c - c1);
    
    return Circle(c, r);
}

pair<Point, DD> next(Point dog, DD tvd, Point fr, DD tvxf, DD tvyf, bool &ok) {
    Point res(0, 0);
    
    ok = true;
    DD tvf = sqrt( tvxf * tvxf + tvyf * tvyf );
    
    Line lf( fr, fr + Point(tvxf, tvyf) );
    
    if ( abs(tvd - tvf) < EPS ) {
        Line ld( (dog + fr)/2, (dog + fr)/2 + rot90(fr - dog) );
        vector<Point> tmp = crosspoint(ld, lf);
        
        if (tmp.size() == 0) {
            ok = false;
            return MP(res, 0);
        }
        else {
            DD Min = INF;
            Point pMin;
            for (int i = 0; i < tmp.size(); ++i) {
                DD s = ( abs(tmp[i] - fr) / tvf );
                if ( ccw(fr, fr + Point(tvxf, tvyf), tmp[i]) != 2 ) {
                    if ( chmin(Min, s) ) {
                        pMin = tmp[i];
                    }
                }
            }  
            return MP(pMin, Min);
        }
    }
    else {
        Circle cd = Apporonius(dog, fr, tvd, tvf);
        vector<Point> tmp = crosspoint(cd, lf);
        
        if (tmp.size() == 0) {
            ok = false;
            return MP(res, 0);
        }
        else {
            DD Min = INF;
            Point pMin;
            for (int i = 0; i < tmp.size(); ++i) {
                DD s = ( abs(tmp[i] - fr) / tvf );
                if ( ccw(fr, fr + Point(tvxf, tvyf), tmp[i]) != 2 ) {
                    if ( chmin(Min, s) ) {
                        pMin = tmp[i];
                    }
                }
            }  
            return MP(pMin, Min); 
        }
    }
    
    ok = false;
    return MP(res, 0);
}

int main() {
    while (cin >> n >> m) {
        if (n == 0 || m == 0) break;
        
        memset(res, 0, sizeof(res));
        for (int i = 0; i < n; ++i) {
            cin >> pd[i].x >> pd[i].y >> vd[i];
        }
        for (int i = 0; i < m; ++i) {
            cin >> pf[i].x >> pf[i].y >> vxf[i] >> vyf[i];
        }
        
        for (int i = 0; i < m; ++i) {
            double Min = INF;
            int mem = -1;
            
            for (int j = 0; j < n; ++j) {
                bool ok = true;
                pair<Point, double> pa = next(pd[j], vd[j], pf[i], vxf[i], vyf[i], ok);
                
                if (ok) {
                    if (chmin(Min, pa.second)) {
                        mem = j;
                    }
                }
            }
            
            res[mem]++;
            
            
//            COUT(i);
//            COUT(mem);
            
            for (int j = 0; j < n; ++j) {
                bool ok = true;
                pair<Point, double> pa = next(pd[j], vd[j], pf[i], vxf[i], vyf[i], ok);
                
                if (ok) {
                    pd[j] = (pd[j] * (pa.second - Min) + pa.first * Min) / pa.second;
                }
                
                //cout << j << " : " << pa << ", " << pd[j] << endl;
            }
        }
        
        for (int i = 0; i < n; ++i) {
            cout << res[i];
            if (i != n-1) cout << " ";
        }
        cout << endl;
    }
    
    return 0;
}