#include<iostream>
#include<complex>
#include<vector>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cassert>
 
using namespace std;
 
#define rep(i, n) for (int i = 0; i < int(n); ++i)
 
#define X real()
#define Y imag()
 
typedef complex<double> P;
typedef pair<P, P> L;
typedef vector<P> Pol;
 
const double INF = 1e40;
const double EPS = 1e-8;
const double PI = acos(-1);
 
int sig(double r) {return (r < -EPS) ? -1 : (r > EPS) ? 1: 0;}
bool eq(double a, double b) {return abs(a - b) < EPS;}
bool near(P a, P b) {return abs(b - a) < EPS;}
 
ostream &operator<<(ostream &os, const L &a) {
  os << a.first << "-" << a.second;
  return os;
}
 
double sq(double a) {return a * a;}
 
namespace std{
  bool operator<(const P &a, const P &b){
    if(!eq(a.X, b.X)) return a.X < b.X;
    if(!eq(a.Y, b.Y)) return a.Y < b.Y;
    return false;
  }
}
 
// 内積
double dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
// 外積
double cross(P a, P b) {return a.X * b.Y - a.Y * b.X;}
 
// 線分のベクトル
P vec(L a) {return a.second - a.first;}
 
// 線分abに対する点xの位置
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(L s, P p) {
  P a = vec(s);
  p -= s.first;
  double cr = cross(a, p);
  if (abs(cr) < EPS) {
    if (sig(dot(a, p)) < 0) return BACK;
    if (sig(abs(a) - abs(p)) < 0) return FRONT;
    return ON;
  }
  return (cr > 0) ? LEFT : RIGHT;
}
 
// 角度
double arg(P a, P b) {return acos(dot(a, b) / (abs(a) * abs(b)));}
P rot(P p, double theta) { return p * polar(1., theta);}
 
// 射影
P proj(P a, P b) {return a * dot(a, b) / norm(a);}
P perp(L l, P p) {return l.first + proj(vec(l), p - l.first);}
P refl(L l, P p) {return perp(l, p) * 2. - p;}
  
// 交差判定 端点を含む
bool iLL(L a, L b) {return !eq(cross(vec(a), vec(b)), 0);}
bool eqL(L a, L b) {return !iLL(a, b) && eq(cross(vec(a), b.first - a.first), 0);}
bool iLS(L a, L b) {return sig(cross(vec(a), b.first)) * sig(cross(vec(a), b.second)) <= 0;}
bool iSS(L a, L b) {
  int cwaf = ccw(a, b.first);
  int cwbf = ccw(b, a.first);
  int cwas = ccw(a, b.second);
  int cwbs = ccw(b, a.second);
  if ((cwaf | cwas | cwbf | cwbs) & ON) return true;
  return ((cwaf | cwas) & (cwbf | cwbs)) == (LEFT | RIGHT);
}
 
// 交点
P pLL(L a, L b) {
  P va = vec(a);
  P vb = vec(b);
  return a.first + va * (cross(vb, b.first - a.first) / cross(vb, va));
}
 
// 距離
double dLP(L l, P x) {return abs(cross(vec(l), x - l.first)) / abs(vec(l));}
double dSP(L s, P x) {
  if (dot(vec(s), x - s.first) <= 0) return abs(x - s.first);
  if (dot(-vec(s), x - s.second) <= 0) return abs(x - s.second);
  return dLP(s, x);
}
double dLL(L a, L b) {return iLL(a, b) ? 0 : dLP(a, b.first);}
double dLS(L a, L b) {return iLS(a, b) ? 0 : min(dLP(a, b.first), dLP(a, b.second));}
double dSS(L a, L b) {return iSS(a, b) ? 0 : min(min(dSP(a, b.first), dSP(a, b.second)), min(dSP(b, a.first), dSP(b, a.second)));}
 
// 単位ベクトル
P uline(P a) {return a / abs(a);}
// 法線ベクトル
P nml(P a) {return a * P(0, 1);}
P nmr(P a) {return a * P(0, -1);}
// 単位法線ベクトル
P unml(P a) {return uline(nml(a));}
P unmr(P a) {return uline(nmr(a));}
 
// 直行
bool orth(P a, P b) {return eq(dot(a, b), 0);}
// 平行
bool prll(P a, P b) {return eq(cross(a, b), 0);}
 
// 円
struct C{
  P c;
  double r;
  C() {}
  C(P c, double r) : c(c), r(r) {}
};
 
// 偏角ソートに用いる比較関数
// TODO よくわからん
bool isRight(P base, P isv) {return eq(cross(base, isv), 0) ? abs(isv) < abs(base) : cross(base, isv) < 0;}
bool isLeft(P base, P isv) {return eq(cross(base,isv), 0) ? abs(isv) < abs(base) : cross(base,isv) > 0;}
// 角度が等しい場合は順序が一定ではない
bool cmpArg(P a, P b) {return ccw(L(P(0, 0), a), b) == RIGHT;}
 
// 2円の位置関係
enum RELATION{SAME = 1, CONTAIN = 2, OVER = 4, NO_CROSS = 8, ONE_CROSS = 16, ONE_INSIDE_CROSS = 32, TWO_CROSS = 64};
int cRel(C c1, C c2) {
  double d = abs(c1.c - c2.c);
  if (near(c1.c, c2.c) && eq(d, 0)) return SAME;
  if (sig(d - (c1.r - c2.r)) < 0) return OVER;
  if (sig(d - (c2.r - c1.r)) < 0) return CONTAIN;
  if (eq(d, c1.r - c2.r)) return ONE_INSIDE_CROSS;
  if (eq(d, c1.r + c2.r)) return ONE_CROSS;
  if (sig(d - (c1.r + c2.r)) > 0) return NO_CROSS;
  return TWO_CROSS;
}
 
bool iCC(C a, C b) {return cRel(a, b) & (ONE_INSIDE_CROSS | ONE_CROSS | TWO_CROSS);}
// 点が円に含まれるか
bool iCP(C c, P p) {return sig(abs(p - c.c) - c.r) <= 0;}
// 交差判定
bool iCL(C c, L l) {return sig(c.r - dLP(l, c.c)) >= 0;}
// 円と交差せず完全に含まれても良い場合は&&以降を削除
bool iCS(C c, L s) {return sig(c.r - dSP(s, c.c)) >= 0 && sig(c.r - max(abs(s.first - c.c), abs(s.second - c.c))) <= 0;}
 
// 交点
pair<P, P> pCC(C a, C b) {
  double d = abs(b.c - a.c);
  double x = (sq(d) + sq(a.r) - sq(b.r)) / (2 * d);
  P e = uline(b.c - a.c), w = nml(e) * sqrt(max(sq(a.r) - sq(x), 0.));
  return make_pair(a.c + e * x - w, a.c + e * x + w);
}
pair<P, P> pCL(C c, L l) {
  P h = perp(l, c.c);
  double d2 = norm(h - c.c);
  double y = sqrt(max(sq(c.r) - d2, 0.0));
  P e = uline(vec(l));
  return make_pair(h - e * y, h + e * y);
}
 
// a:bに内分
P iDiv(P p, P q, double a, double b) {return P((q * a + p * b) / (a + b));}
// a:bに外分
P oDiv(P p, P q, double a, double b) {return P((q * a - p * b) / (a - b));}
 
// 線分を直径とする円
C cDS(L s) {return C((s.first + s.second) / 2., abs(vec(s)) / 2);}
// アポロニウスの円
// s!=tに注意
C apC(P a, P b, double s, double t) {return cDS(L(iDiv(a, b, s, t), oDiv(a, b, s, t)));}
 
vector<P> dogs;
vector<double> v;
vector<P> dv;
P fp, fv;
vector<int> res;
 
int main() {
  int n, m;
  for (;;) {
    cin >> n >> m;
    if (n == 0 && m == 0) break;
    dogs.clear();
    v.clear();
    res.clear();
    rep (i, n) {
      double xx, yy ,vv;
      cin >> xx >> yy >> vv;
      dogs.push_back(P(xx, yy));
      v.push_back(vv);
      res.push_back(0);
    }
    rep (iii, m) {
      cin >> fp.X >> fp.Y >> fv.X >> fv.Y;
      dv.clear();
      int winner = -1;
      double t = INF;
      rep (i, n) {
    if (near(fp, dogs[i])) {
      dv.push_back(P(0, 0));
      winner = i;
      t = 0;
      continue;
    }
    if (eq(v[i],abs(fv))) {
      L la = L(fp, fp + fv);
      L lb = L((dogs[i] + fp) / 2., (dogs[i] + fp) / 2. + nml(fp - dogs[i]));
      if (iLL(la, lb)) {
        P p = pLL(la, lb);
        if (ccw(la, p) & (ON | FRONT)) {
          dv.push_back(polar(v[i], arg(p - dogs[i])));
          if (t > abs(p - dogs[i]) / v[i]) {
        t = abs(p - dogs[i]) / v[i];
        winner = i;
          }
          continue;
        }
      }
      dv.push_back(P(0, 0));
      continue;
    }
    C ap = apC(dogs[i], fp, v[i], abs(fv));
    if (!iCL(ap, L(fp, fp + fv))) {
      dv.push_back(P(0, 0));
    } else {
      pair<P, P> pp = pCL(ap, L(fp, fp + fv));
      assert(ccw(L(fp, fp + fv), pp.first) & (BACK | FRONT | ON));
      assert(ccw(L(fp, fp + fv), pp.second) & (BACK | FRONT | ON));
      if (ccw(L(fp, fp + fv), pp.first) & (ON | FRONT) && (ccw(L(fp, fp + fv), pp.second) & (BACK) || abs(pp.first - fp) < abs(pp.second - fp))) {
        //cout << i << " " << pp.first << endl;
        dv.push_back(polar(v[i], arg(pp.first - dogs[i])));
        if (t > abs(pp.first - dogs[i]) / v[i]) {
          t = abs(pp.first - dogs[i]) / v[i];
          winner = i;
        }
      } else if (ccw(L(fp, fp + fv), pp.second) & (FRONT | ON)) {
        //cout << i << " " << pp.second << endl;
        dv.push_back(polar(v[i], arg(pp.second - dogs[i])));
        if (t > abs(pp.second - dogs[i]) / v[i]) {
          t = abs(pp.second - dogs[i]) / v[i];
          winner = i;
        }
      } else {
        dv.push_back(P(0, 0));
      }
    }
      }
      rep (i, n) dogs[i] += dv[i] * t;
      ++res[winner];
      //rep(i, n) cout << dogs[i] << " ";
      //cout << endl;
    }
    rep (i, n) {
      if (i < n - 1) cout << res[i] << " ";
      else cout << res[i] << endl;
    }
  }
  return 0;
}

Measured memory_bytes: 996