#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
//#define EPS 0.000000001
using namespace std;


#define EPS 0.000000001
#define NUM 105

struct Point{
	Point(){
		x = y = 0;
	}
	Point(int arg_x,int arg_y){
		x = arg_x;
		y = arg_y;
	}
	ll x,y;
};
typedef Point Vector;


struct Data{
	Data(ll arg_Time,ll arg_Vx,ll arg_Vy){
		Time = arg_Time;
		Vx = arg_Vx;
		Vy = arg_Vy;
	}
	ll Time,Vx,Vy;
};

struct Info{

	Point pos_First;
	string name;
	vector<Data> V;
};

struct State{
	State(int arg_robo_A,int arg_robo_B,double arg_Time){
		robo_A = arg_robo_A;
		robo_B = arg_robo_B;
		Time = arg_Time;
	}
	bool operator<(const struct State &arg) const{
		return Time > arg.Time; //時刻の昇順(PQ)
	}

	int robo_A,robo_B;
	double Time;
};

int N;
ll T,R;
bool is_adj[NUM][NUM],is_Same[NUM];
Info info[NUM];
priority_queue<State> Q;



int calc_dist(Point A,Point B){

	return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}

void calc_Cross_Time(int robo_A,int robo_B){

	Point pos_A = info[robo_A].pos_First;
	Point pos_B = info[robo_B].pos_First;

	Vector v_A = Vector(info[robo_A].V[0].Vx,info[robo_A].V[0].Vy);
	Vector v_B = Vector(info[robo_B].V[0].Vx,info[robo_B].V[0].Vy);
	Vector next_v_A,next_v_B;

	int index_A = 0,index_B = 0;

	ll current_Time = 0,next_Time;

	while(true){

		next_v_A = v_A;
		next_v_B = v_B;

		//次のイベントはどちらが早いか、または同時か

		if(	(index_A < info[robo_A].V.size()-1 && info[robo_A].V[index_A].Time < info[robo_B].V[index_B].Time)){ //Aが早い

			next_Time = info[robo_A].V[index_A].Time;

			next_v_A.x = info[robo_A].V[index_A+1].Vx;
			next_v_A.y = info[robo_A].V[index_A+1].Vy;

			index_A++;

		}else if((index_B < info[robo_B].V.size()-1 && info[robo_B].V[index_B].Time < info[robo_A].V[index_A].Time)){ //Bが早い

			next_Time = info[robo_B].V[index_B].Time;

			next_v_B.x = info[robo_B].V[index_B+1].Vx;
			next_v_B.y = info[robo_B].V[index_B+1].Vy;

			index_B++;

		}else{ //同時

			next_Time = info[robo_A].V[index_A].Time;

			if(index_A+1 <= info[robo_A].V.size()-1){

				next_v_A.x = info[robo_A].V[index_A+1].Vx;
				next_v_A.y = info[robo_A].V[index_A+1].Vy;
				index_A++;
			}

			if(index_B+1 <= info[robo_B].V.size()-1){

				next_v_B.x = info[robo_B].V[index_B+1].Vx;
				next_v_B.y = info[robo_B].V[index_B+1].Vy;
				index_B++;
			}
		}

		//判別式
		ll a = (v_A.x-v_B.x)*(v_A.x-v_B.x)+(v_A.y-v_B.y)*(v_A.y-v_B.y);
		ll b = 2*((pos_A.x-pos_B.x)*(v_A.x-v_B.x)+(pos_A.y-pos_B.y)*(v_A.y-v_B.y));
		ll c = (pos_A.x-pos_B.x)*(pos_A.x-pos_B.x)+(pos_A.y-pos_B.y)*(pos_A.y-pos_B.y)-R*R;

		ll D = b*b-4*a*c;

		if(a != 0  && D >= 0){ //解があるならそれを求める:current_Time-next_Timeの間にあれば、それをQにpush

			double A = a,B = b, C = c;
			double CURRENT = current_Time,NEXT = next_Time;

			double t_1 = CURRENT+(-B-sqrt(B*B-4*A*C))/(2*A);
			double t_2 = CURRENT+(-B+sqrt(B*B-4*A*C))/(2*A);


			if(t_1 > CURRENT+EPS && t_1+EPS < NEXT){

				Q.push(State(robo_A,robo_B,t_1));

			}
			if(fabs(t_1-t_2) > EPS && t_2 > CURRENT+EPS && t_2+EPS < NEXT){

				Q.push(State(robo_A,robo_B,t_2));
			}
		}

		if(index_A == info[robo_A].V.size()-1 && index_B == info[robo_B].V.size()-1){

			break;
		}

		pos_A.x += v_A.x*(next_Time-current_Time);
		pos_A.y += v_A.y*(next_Time-current_Time);

		pos_B.x += v_B.x*(next_Time-current_Time);
		pos_B.y += v_B.y*(next_Time-current_Time);

		current_Time = next_Time;

		v_A = next_v_A;
		v_B = next_v_B;
	}
}

void func(){

	for(int i = 0; i < NUM; i++){

		info[i].V.clear();
	}

	int base_robot = 0;

	ll Time,Vx,Vy;

	for(int i = 0; i < N; i++){

		cin >> info[i].name;

		scanf("%lld %lld %lld",&Time,&info[i].pos_First.x,&info[i].pos_First.y);

		while(true){

			scanf("%lld %lld %lld",&Time,&Vx,&Vy);
			info[i].V.push_back(Data(Time,Vx,Vy));

			if(Time == T)break;
		}
	}

	is_Same[base_robot] = true;
	for(int i = 1; i < N; i++){

		is_Same[i] = false;
	}

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++){

			is_adj[i][k] = (i==k);
		}
	}

	//最初の位置関係
	for(int a = 0; a < N-1; a++){
		for(int b = a+1; b < N; b++){
			//最初の距離
			ll first_dist = calc_dist(info[a].pos_First,info[b].pos_First);

			if(first_dist <= R*R){
				is_adj[a][b] = true;
				is_adj[b][a] = true;
			}
		}
	}

	for(int mid = 0; mid < N; mid++){
		for(int start = 0; start < N; start++){
			if(!is_adj[start][mid])continue;
			for(int goal = 0; goal < N; goal++){
				if(!is_adj[mid][goal])continue;

				is_Same[goal] = is_Same[start]|is_Same[mid];
			}
		}
	}


	for(int a = 0; a < N-1; a++){
		for(int b = a+1; b < N; b++){

			calc_Cross_Time(a,b);
		}
	}

	while(!Q.empty()){

		if(is_adj[Q.top().robo_A][Q.top().robo_B]){

			is_adj[Q.top().robo_A][Q.top().robo_B] = false;
			is_adj[Q.top().robo_B][Q.top().robo_A] = false;

		}else{

			is_adj[Q.top().robo_A][Q.top().robo_B] = true;
			is_adj[Q.top().robo_B][Q.top().robo_A] = true;

			if(is_Same[Q.top().robo_A] == is_Same[Q.top().robo_B]){
				Q.pop();
				continue;
			}

			int robo_id;

			if(is_Same[Q.top().robo_A]){

				robo_id = Q.top().robo_B;

			}else{

				robo_id = Q.top().robo_A;
			}

			is_Same[robo_id] = true;

			queue<int> calc_Q;
			calc_Q.push(robo_id);

			while(!calc_Q.empty()){

				for(int i = 0; i < N; i++){

					if(is_adj[calc_Q.front()][i] == true && is_Same[i] ==false){

						is_Same[i] = true;
						calc_Q.push(i);
					}
				}
				calc_Q.pop();
			}
		}

		Q.pop();
	}

	vector<string> ans;

	for(int i = 0; i < N; i++){

		if(is_Same[i]){

			ans.push_back(info[i].name);
		}
	}

	sort(ans.begin(),ans.end());

	for(int i = 0; i < ans.size(); i++){

		printf("%s\n",ans[i].c_str());
	}
}

int main(){

	while(true){

		scanf("%d %lld %lld",&N,&T,&R);
		if(N == 0 && T == 0 && R == 0)break;

		func();
	}

	return 0;
}



Measured memory_bytes: 3432