#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <complex>
#include <vector>
#include <assert.h>
#include <queue>
#include <string>

using namespace std;
typedef long long ll;
typedef complex<double> Point;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

struct Line : public vector<Point> {
  Line(Point a, Point b) { push_back(a), push_back(b); }
};
struct Circle {
  Point p;
  double r;
  Circle() {;}
  Circle(Point p, double r) : p(p), r(r) {;}
};

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define DEC(i, s) for (int i = (s); i >= 0; i--)

#define SIZE(v) (int)((v).size())
#define MEMSET(v, h) memset((v), h, sizeof(v))
#define FIND(m, w) ((m).find(w) != (m).end())

inline double cross(const Point &a, const Point &b) {
  return imag(conj(a) * b);
}
inline double dot(const Point &a, const Point &b) {
  return real(conj(a) * b);
}
int ccw(Point a, Point b, Point 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;
}
inline bool intersectLP(const Line &l, const Point &p) {
  return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
inline bool intersectSP(const Line &s, const Point &p) {
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[0] - s[1]) < EPS;
}
inline bool intersectCP(const Circle &c, const Point &p) {
  return abs(c.p - p) - c.r < EPS;
}
inline Point projection(const Line &l, const Point &p) {
  double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
  return l[0] + t * (l[0] - l[1]);
}
inline double distanceLP(const Line &l, const Point &p) {
  return abs(p - projection(l, p));
}
inline double distanceSP(const Line &s, const Point &p) {
  const Point r = projection(s, p);
  if (intersectSP(s, r)) { return abs(r - p); }
  return min(abs(s[0] - p), abs(s[1] - p));
}
//include inside
inline bool intersectSC(const Line &s, const Circle &c) {
  return distanceSP(s, c.p) <= c.r;
}
Point crosspointSC(const Line &s, const Circle &c) {
  assert(intersectSC(s, c));
  assert(!intersectCP(c, s[0]));
  double d = distanceLP(s, c.p);
  Point vect = (s[1] - s[0]);
  vect /= abs(vect);
  Point center1 = c.p + vect * Point(0, 1) * d;
  Point center2 = c.p - vect * Point(0, 1) * d;
  //cout << d << endl;
  //cout << vect << endl;
  //cout << center1 << " " << center2 << endl;
  if (intersectLP(s, center1)) {
    return center1 - vect * sqrt(c.r*c.r - d*d);
  }
  return center2 - vect * sqrt(c.r*c.r - d*d);
}

struct Node {
  double t;
  int robot;
  Node(double t, int robot) :t(t), robot(robot) {;}
  bool operator<(const Node &rhs) const { return t > rhs.t; }
};

int N, T, R;
char name[110][30];
Point inipos[110];
vector<Point> velocity[110];
vector<double> starttime[110];
bool havedata[110];
double gettime[110];

double senddata(int frobot, int trobot, double start) {
  Point pos = inipos[frobot] - inipos[trobot];
  Circle circle = Circle(Point(0, 0), R);
  Point v;
  int findex = 0;
  int tindex = 0;
  double ptime = 0;
  while (true) {
    double ntime = min(starttime[frobot][findex], starttime[trobot][tindex]);
    ntime = min(ntime, start);
    v = velocity[frobot][findex] - velocity[trobot][tindex];
    pos += v * (ntime - ptime);
    ptime = ntime;
    if (ntime == start) { break; }
    if (starttime[frobot][findex] < starttime[trobot][tindex]) {
      findex++;
    } else {
      tindex++;
    }
  }
  if (intersectCP(circle, pos)) { return start; }
  while (findex != (int)starttime[frobot].size() - 1 || tindex != (int)starttime[trobot].size() - 1) {
    if (ptime > gettime[trobot]) { break; }
    if (abs(pos) > R + (T - ptime) * 20 + 1) { break; }
    double ntime = min(starttime[frobot][findex], starttime[trobot][tindex]);
    v = velocity[frobot][findex] - velocity[trobot][tindex];
    Point npos = pos + v * (ntime - ptime);
    //cout << ntime << " " << ptime << " " << pos << " " << npos << endl;
    if (intersectSC(Line(pos, npos), circle)) {
      //cout << endl;
      Point intersect = crosspointSC(Line(pos, npos), circle);
      if (abs(v) == 0) { return ptime; }
      //cout << intersect << endl;
      //cout << ptime + abs(intersect - pos) / abs(v);
      double ret = ptime + abs(intersect - pos) / abs(v);
      assert(ptime - EPS < ret && ret < ntime + EPS);
      return ret;
    }
    pos = npos;
    ptime = ntime;
    if (starttime[frobot][findex] < starttime[trobot][tindex]) {
      findex++;
    } else {
      tindex++;
    }
  }
  //cout << endl;
  return T + 1;
}

int main() {
  while (scanf("%d %d %d", &N, &T, &R), N|T|R) {
    MEMSET(havedata, false);
    REP(i, N) {
      velocity[i].clear();
      starttime[i].clear();
      gettime[i] = T + EPS;
      scanf("%s", name[i]);
      double t, x, y;
      scanf("%lf %lf %lf", &t, &x, &y);
      inipos[i] = Point(x, y);
      velocity[i].push_back(Point(0, 0));
      starttime[i].push_back(0);
      while (true) {
        scanf("%lf %lf %lf", &t, &x, &y);
        velocity[i].push_back(Point(x, y));
        starttime[i].push_back(t);
        if (t == T) { break; }
      }
      velocity[i].push_back(Point(0, 0));
      starttime[i].push_back(T + 1);
    }
    priority_queue<Node> que;
    que.push(Node(0.0, 0));
    while (!que.empty()) {
      double t = que.top().t;
      int robot = que.top().robot;
      que.pop();
      if (havedata[robot]) { continue; }
      havedata[robot] = true;
      gettime[robot] = t;
      //cout << robot << " " << t << endl;
      REP(i, N) {
        if (havedata[i]) { continue; }
        double sendtime = senddata(robot, i, t);
        if (sendtime < gettime[i]) {
          gettime[i] = sendtime;
          que.push(Node(sendtime, i));
        }
      }
    }
    vector<string> ans;
    REP(i, N) {
      if (havedata[i]) { ans.push_back(name[i]); }
    }
    sort(ans.begin(), ans.end());
    REP(i, ans.size()) {
      printf("%s\n", ans[i].c_str());
    }
  }
}

Measured memory_bytes: 0