Problem:
Problem E: Frisbee Dogs

クレインは, 彼女の愛犬である Jack をフリスビードッグ大会に出場させようとしている. しかし, 彼女は Jack がよい成績を取れるか自信が無い. 彼女のために, 大会をシミュレートして Jack の成績を見積もるプログラムを作成してほしい.

この大会は, 2次元平面上にいる N 匹の犬によって行われる. 大会の開始時点において, i 番目の犬は (Dix, Diy) の位置にいる. i 番目の犬は Vi [m/s] で走ることができ, 全ての犬は十分小さいので点とみなせる. ある時刻に, 2 匹以上の犬が同じ位置にいても構わない.

1枚目のフリスビーの発射をもって大会は開始し, この瞬間から犬たちは動くことを許される. フリスビーもまた点とみなすことができ, i 枚目のフリスビーは (FPix, FPiy) の位置から (FVix, FViy) [m/s] の速度ベクトルで発射され, 等速直線運動を続ける. ある犬の位置とフリスビーの位置が等しくなったとき, その犬はフリスビーを取得することができる.

1枚目のフリスビーがいずれかの犬に取得された瞬間, 2枚目のフリスビーが発射される. 2枚目のフリスビーが取得された瞬間3枚目が発射され, 以下同様にフリスビーが取得された直後に次のフリスビーが発射される. M 枚目のフリスビーが取得されると大会は終了する.

言うまでもなく, 犬たちの目標はより多くのフリスビーを取得することである. 犬たちは, 以下のような戦略をとる.

フリスビーが発射されたとき, 犬は可能な限り早い時刻にそれを取得できるように移動し, フリスビーを取得する. ただし, フリスビーを取得できないときは現在いる場所に待機する.

ある犬がフリスビーを取得できるかどうかの判断は, 他の犬の行動に関係なく行われる. つまり, ある犬がフリスビーを取得するために移動したものの, 他の犬に先に取得されてしまうことも有りえる. いずれかの犬がフリスビーを取得し新たなフリスビーが発射された瞬間, 犬たちは新しいフリスビーに対して上記の戦略をとる.

あなたの作成するプログラムは、それぞれの犬が取得したフリスビーの数を出力しなければならない.

Input

入力ファイルは, 複数のデータセットから構成される.

データセットの1行目には, 犬の数 N (1 ≤ N ≤ 10) とフリスビーの数 M (1 ≤ M ≤ 1000)が与えられる.

続く N 行には, 犬の初期位置と速度 Dix, Diy, Vi が1つの空白区切りで与えられる.

続く M 行には, フリスビーの発射位置と速度 FPix, FPiy, FVix, FViy が1つの空白文字区切りで与えられる.

与えられる座標値は実数であり、その絶対値は 1000 を越えない. 与えられる速度は実数であり 1 ≤ DVi ≤ 100, -25 ≤ FVix, FViy ≤ 25 である. どの犬にも取得できないフリスビーはないと仮定してよい.

任意のフリスビーがある犬に時刻 t で取得されたとき、時刻 t + 1e-6 以前にそれを取得できる犬はいない.

シミュレーションの間, 犬の x 座標, y 座標の絶対値は 1e+8 を越えない.

N, M がともに 0 のとき入力の終わりを示す.

Output

それぞれの犬が取得したフリスビーの数を, 空白文字で区切って1行に出力せよ. 出力する順番は, 入力で与えられた順番と等しくなければならない.

Sample 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 for the Sample Input

1 0
2 1

Solution in C++ (judge verdict: Time Limit Exceeded)

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
using namespace std;

#define double long double

static const double EPS = 1e-9;
typedef long long ll;
#define rep(i,n) for(int i=0;i<n;i++)
#define rev(i,n) for(int i=n-1;i>=0;i--)
#define sz(a) a.size()
#define all(a) a.begin(),a.end()
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define SS stringstream
#define DBG1(a) rep(_X,sz(a)){printf("%d ",a[_X]);}puts("");
#define DBG2(a) rep(_X,sz(a)){rep(_Y,sz(a[_X]))printf("%d ",a[_X][_Y]);puts("");}
#define bitcount(b) __builtin_popcount(b)
#define REP(i, s, e) for ( int i = s; i <= e; i++ )  
 
const double INF = 1e12;
typedef complex<double> P,point;
typedef vector<P> G,polygon;
namespace std {bool operator < (const P& a, const P& b) {return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);} }
double cross(const P& a, const P& b) {return imag(conj(a)*b);}
double dot(const P& a, const P& b) {return real(conj(a)*b);}
struct L : public vector<P> {L(const P &a, const P &b) {push_back(a); push_back(b);} };
struct C {P p; double r;C(const P &p, double r) : p(p), r(r) { } C(){} };
int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if (cross(b, c) > 0)   return +1;
	if (cross(b, c) < 0)   return -1;
	if (dot(b, c) < 0) return +2;
	if (norm(b) < norm(c)) return -2;
	return 0;
}
 
// Check Funcs //
bool intersectLL(const L &l, const L &m) {return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;}
bool intersectLS(const L &l, const L &s) {return cross(l[1]-l[0], s[0]-l[0])*cross(l[1]-l[0], s[1]-l[0]) < EPS;}
bool intersectLP(const L &l, const P &p) {return abs(cross(l[1]-p, l[0]-p)) < EPS;}
bool intersectSS(const L &s, const L &t) {return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 && ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;}
bool intersectSP(const L &s, const P &p) {return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS;}

inline double test(P f,P v,P dg,double speed,double tm){
	P ff = f + tm * v;
	P dir = (ff-dg);
	if( abs(dir) > EPS ){
		dir /= (abs(dir));
		double dist = abs(ff-dg);
		dg += dir * min(dist/speed,tm);
	}
	//cout << ff << " " << dg << endl;
	return intersectSP(L(f,ff),dg);
}


inline P move(P f,P v,P dg,double speed,double tm){
	P ff = f + tm * v;
	P dir = (ff-dg);
	if( abs(dir) > EPS ){
		dir /= (abs(dir));
		double dist = abs(ff-dg);
		dg += dir * min(dist/speed,tm);
	}
	return dg;
}

int main(){
	int n,m;
	while(cin >> n >> m && n){
		vector<P> dog(n);
		double speed[10];
		double tmp[10];
		int res[10] = {};
		for(int i = 0 ; i < n ; i++){
			cin >> dog[i].real() >> dog[i].imag() >> speed[i];
		}
		for(int i = 0 ; i < m ; i++){
			P f,v;
			cin >> f.real() >> f.imag() >> v.real() >> v.imag();
			for(int j = 0 ; j < n ; j++){
				double le = 0 , ri = 1e10;
				for(int _ = 0 ; _ < 32 ; _++){
					double mi = (le+ri)*0.5;
					if( test(f,v,dog[j],speed[j],mi) ){
						ri = mi;
					}else{
						le = mi;
					}
				}
				tmp[j] = ri;
			}
			double mtime = *min_element(tmp,tmp+n);
			res[min_element(tmp,tmp+n)-tmp]++;
			for(int j = 0 ; j < n ; j++){
				//cout << "[" << i << "]" << j << " " << tmp[j] << endl;
				if( fabs(tmp[j]-1e10) > EPS ){
					dog[j] += move(f,v,dog[j],speed[j],mtime);
				}
			}
		}
		for(int i = 0 ; i < n ; i++)
			cout << res[i] << (i==n-1?"\n":" ");
		
	}
	
}