Problem:
Problem E:
Earth Observation with a Mobile Robot Team
A new type of mobile robot has been developed for environmental earth
observation.
It moves around on the ground, acquiring and recording various sorts of
observational data using high precision sensors.
Robots of this type have short range wireless communication devices and can
exchange observational data with ones nearby.
They also have large capacity memory units, on which they record data
observed by themselves and those received from others.
Figure 1 illustrates the current positions of three robots A, B, and C and
the geographic coverage of their wireless devices.
Each circle represents the wireless coverage of a robot, with its
center representing the position of the robot.
In this figure, two robots A and B are in the positions where A can
transmit data to B, and vice versa.
In contrast, C cannot communicate with A or B, since it is too remote
from them.
Still, however, once B moves towards C as in Figure 2, B and C can
start communicating with each other.
In this manner, B can relay observational data from A to C.
Figure 3 shows another example, in which data propagate among several robots 
instantaneously.
Figure 1: The initial configuration of three robots
Figure 2: Mobile relaying
Figure 3: Instantaneous relaying among multiple robots
As you may notice from these examples, if a team of robots move
properly, observational data quickly spread over a large number of them.
Your mission is to write a program that simulates how information
spreads among robots.
Suppose that, regardless of data size, the time necessary for
communication is negligible.
Input
The input consists of multiple datasets, each in the following format.
N
T
R
nickname and travel route of the first robot
nickname and travel route of the second robot
...
nickname and travel route of the N-th robot
The first line contains three integers
N
,
T
, and
R
that are the number of robots, the length of the simulation
period, and the maximum distance wireless signals can reach,
respectively, and satisfy that 1 <=
N
<= 100, 1 <=
T
<= 1000, and 1 <=
R
<= 10.
The
nickname and travel route
of each robot are given in the
following format.
nickname
t
0
x
0
y
0
t
1
vx
1
vy
1
t
2
vx
2
vy
2
...
t
k
vx
k
vy
k
Nickname
is a character string of length between one and eight that
only contains lowercase letters.
No two robots in a dataset may have the same nickname.
Each of the lines following
nickname
contains three integers,
satisfying the following conditions.
0 =
t
0
<
t
1
< ... <
t
k
=
T
-10 <=
vx
1
,
vy
1
,  ...,
vx
k
,
vy
k
<= 10
A robot moves around on a two dimensional plane.
(
x
0
,
y
0
) is the location of the
robot at time 0.
From time
t
i
-1
to
t
i
(0
<
i
<=
k
), the velocities in the
x
and
y
directions are
vx
i
and
vy
i
, respectively.
Therefore, the travel route of a robot is piecewise linear.
Note that it may self-overlap or self-intersect.
You may assume that each dataset satisfies the following conditions.
The distance bet
...(truncated)

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef long double ld;
typedef pair<ll,ll> pi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
#define F first
#define S second
template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return 1;}return 0;}
template<typename T>bool chmax(T&a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
int main(){
    while(1){
        ll N,T,R;cin>>N>>T>>R;
        if(!N)return 0;
        vector<vector<pi>>A(N,vector<pi>(T+1));
        vector<string>name(N);
        REP(i,N){
            cin>>name[i];
            ll t,x,y;cin>>t>>x>>y;
            A[i][0]=pi(x,y);
            while(t!=T){
                int _t,vx,vy;cin>>_t>>vx>>vy;
                FOR(j,t+1,_t+1)A[i][j]=pi(A[i][j-1].F+vx,A[i][j-1].S+vy);
                t=_t;
            }
        }
        vector<ld>DP(N,1e18);
        DP[0]=0;
        min_priority_queue<pair<ld,ll>>Q;
        Q.emplace(make_pair(0,0));
        while(!Q.empty()){
            auto[t,v]=Q.top();Q.pop();
            if(t!=DP[v])continue;
            REP(u,N)if(u!=v)REP(i,T)if(t<=i+1){
                ll x1=A[u][i].first-A[v][i].first;
                ll y1=A[u][i].second-A[v][i].second;
                ll x2=A[u][i+1].first-A[v][i+1].first;
                ll y2=A[u][i+1].second-A[v][i+1].second;
                ll a=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
                ll b=2*(x1*(x2-x1)+y1*(y2-y1));
                ll c=x1*x1+y1*y1-R*R;
                if(a==0){
                    assert(b==0);
                    if(c<=0){
                        if(chmin(DP[u],max((ld)i,t)))Q.emplace(make_pair(DP[u],u));
                    }
                }
                else if(b*b-4*a*c>=0){
                    ld s=sqrtl(b*b-4*a*c);
                    ld t1=(-b-s)/2/a+i;
                    ld t2=(-b+s)/2/a+i;
                    chmax(t1,(ld)i);
                    chmax(t1,t);
                    chmin(t2,(ld)(i+1));
                    if(t1<=t2&&chmin(DP[u],t1))Q.emplace(make_pair(DP[u],u));
                }
                //at^2+bt+c<=0
            }
        }
        //for(auto i:DP)cout<<i<<" ";cout<<endl;
        vector<string>ans;
        REP(i,N)if(DP[i]<1e17)ans.emplace_back(name[i]);
        sort(ALL(ans));
        for(auto s:ans)cout<<s<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4452
final_rank: 7

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 2 "cp-library/src/geometry/base.hpp"

template < class T > struct point {
    T x, y;
    point() : x(0), y(0) {}
    point(T x, T y) : x(x), y(y) {}
    point(std::pair< T, T > p) : x(p.first), y(p.second) {}
    point& operator+=(const point& p) { x += p.x, y += p.y; return *this; }
    point& operator-=(const point& p) { x -= p.x, y -= p.y; return *this; }
    point& operator*=(const T r) { x *= r, y *= r; return *this; }
    point& operator/=(const T r) { x /= r, y /= r; return *this; }
    point operator+(const point& p) const { return point(*this) += p; }
    point operator-(const point& p) const { return point(*this) -= p; }
    point operator*(const T r) const { return point(*this) *= r; }
    point operator/(const T r) const { return point(*this) /= r; }
    point operator-() const { return {-x, -y}; }
    bool operator==(const point& p) const { return x == p.x and y == p.y; }
    bool operator!=(const point& p) const { return x != p.x or  y != p.y; }
    bool operator<(const point& p) const { return x == p.x ? y < p.y : x < p.x; }
    point< T > rot(double theta) {
        static_assert(is_floating_point_v< T >);
        double cos_ = std::cos(theta), sin_ = std::sin(theta);
        return {cos_ * x - sin_ * y, sin_ * x + cos_ * y};
    }
};
template < class T > istream& operator>>(istream& is, point< T >& p) { return is >> p.x >> p.y; }
template < class T > ostream& operator<<(ostream& os, point< T >& p) { return os << p.x << " " << p.y; }
template < class T > T dot(const point< T >& a, const point< T >& b) { return a.x * b.x + a.y * b.y; }
template < class T > T det(const point< T >& a, const point< T >& b) { return a.x * b.y - a.y * b.x; }
template < class T > T norm(const point< T >& p) { return p.x * p.x + p.y * p.y; }
template < class T > double abs(const point< T >& p) { return std::sqrt(norm(p)); }
template < class T > double angle(const point< T >& p) { return std::atan2(p.y, p.x); }
template < class T > int sign(const T x) {
    T e = (is_integral_v< T > ? 1 : 1e-8);
    if(x <= -e) return -1;
    if(x >= +e) return +1;
    return 0;
}
template < class T > bool equals(const T& a, const T& b) { return sign(a - b) == 0; }
template < class T > int ccw(const point< T >& a, point< T > b, point< T > c) {
    b -= a, c -= a;
    if(sign(det(b, c)) == +1) return +1; // counter clockwise
    if(sign(det(b, c)) == -1) return -1; //         clockwise
    if(sign(dot(b, c)) == -1) return +2; // c-a-b
    if(norm(b) < norm(c)) return -2;     // a-b-c
    return 0;                            // a-c-b
}

template < class T > struct line {
    point< T > a, b;
    line() {}
    line(point< T > a, point< T > b) : a(a), b(b) {}
};
template < class T > point< T > projection(const line< T >& l, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    return l.a + (l.a - l.b) * dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
}
template < class T > point< T > reflection(const line< T >& l, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    return p + (projection(l, p) - p) * T(2);
}
template < class T > bool orthogonal(const line< T >& a, const line< T >& b) { return equals(dot(a.b - a.a, b.b - b.a), T(0)); }
template < class T > bool parallel  (const line< T >& a, const line< T >& b) { return equals(det(a.b - a.a, b.b - b.a), T(0)); }
template < class T > point< T > cross_point_ll(const line< T >& l, const line< T >& m) {
    static_assert(is_floating_point_v< T >);
    T A = det(l.b - l.a, m.b - m.a);
    T B = det(l.b - l.a, l.b - m.a);
    if(equals(abs(A), T(0)) and equals(abs(B), T(0))) return m.a;
    return m.a + (m.b - m.a) * B / A;
}

template < class T > using segment = line< T >;
template < class T > bool intersect_ss(const segment< T >& s, const segment< T >& t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 and ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
template < class T > double distance_sp(const segment< T >& s, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    point r = projection(s, p);
    if(ccw(s.a, s.b, r) == 0) return abs(r - p);
    return std::min(abs(s.a - p), abs(s.b - p));
}
template < class T > double distance_ss(const segment< T >& a, const segment< T >& b) {
    if(intersect_ss(a, b)) return 0;
    return std::min({ distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), distance_sp(b, a.b) });
}

template < class T > using polygon = std::vector< point< T > >;
template < class T > T area2(const polygon< T >& p) {
    T s = 0;
    int n = p.size();
    for(int i = 0; i < n; i++) s += det(p[i], p[(i + 1) % n]);
    return s;
}
template < class T > T area(const polygon< T >& p) { return area2(p) / T(2); }

template < class T > bool is_convex(const polygon< T >& p) {
    int n = p.size();
    for(int i = 0; i < n; i++) if(ccw(p[(i - 1 + n) % n], p[i], p[(i + 1) % n]) == -1) return false;
    return true;
}
template < class T > int contains(const polygon< T >& g, const point< T >& p) {
    int n = g.size();
    bool in = false;
    for(int i = 0; i < n; i++) {
        point a = g[i] - p, b = g[(i + 1) % n] - p;
        if(sign(a.y - b.y) == +1) std::swap(a, b);
        if(sign(a.y) <= 0 and sign(b.y) ==+1 and sign(det(a, b)) == -1) in = !in;
        if(sign(det(a, b)) == 0 and sign(dot(a, b)) <= 0) return 1; // ON
    }
    return in ? 2 : 0;
}
template < class T > polygon< T > convex_cut(const polygon< T >& p, const line< T >& l) {
    int n = p.size();
    polygon< T > res;
    for(int i = 0; i < n; i++) {
        point now = p[i], nxt = p[(i + 1) % n];
        if(ccw(l.a, l.b, now) != -1) res.push_back(now);
        if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) res.push_back(cross_point_ll(line(now, nxt), l));
    }
    return res;
}
template < class T > polygon< T > convex_hull(polygon< T >& p) {
    int n = p.size(), k = 0;
    if(n <= 2) return p;
    std::sort(p.begin(), p.end());
    polygon< T > ch(n + n);
    for(int i = 0; i < n; ch[k++] = p[i++])
        while(k >= 2 and sign(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) == -1) k--;
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--])
        while(k >= t and sign(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) == -1) k--;
    ch.resize(k - 1);
    return ch;
}
template < class T > T diameter2(const polygon< T >& p) {
    static_assert(is_floating_point_v< T >);
    int n = p.size(), is = 0, js = 0;
    for(int i = 1; i < n; i++) {
        if(sign(p[i].y - p[is].y) == +1) is = i;
        if(sign(p[i].y - p[js].y) == -1) js = i;
    }
    T dist_max = norm(p[is] - p[js]);
    int maxi = is, i = is, maxj = js, j = js;
    do {
        if(sign(det(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j])) >= 0) j = (j + 1) % n; else i = (i + 1) % n;
        if(norm(p[i] - p[j]) > dist_max) {
            dist_max = norm(p[i] - p[j]);
            maxi = i, maxj = j;
        }
    } while(i != is or j != js);
    return dist_max;
}
template < class T > double diameter(const polygon< T >& p) {
    static_assert(is_floating_point_v< T >);
    return std::sqrt(diameter2(p));
}

template < class T > struct circle {
    point< T > p;
    T r;
    circle() = default;
    circle(point< T > p, T r) : p(p), r(r) {}
};
template < class T > istream& operator>>(istream& is, circle< T >& c) { return is >> c.p >> c.r; }
template < class T > int intersect_cc(circle< T > c1, circle< T > c2) {
    if(c1.r < c2.r) std::swap(c1, c2);
    T d = abs(c1.p - c2.p);
    if(sign(c1.r + c2.r - d) == -1) return 4;
    if(equals(c1.r + c2.r, d)) return 3;
    if(sign(c1.r - c2.r - d) == -1) return 2;
    if(equals(c1.r - c2.r, d)) return 1;
    return 0;
}
template < class T > std::pair<point< T >, point< T >> cross_point_cc(const circle< T >& c1, const circle< T >& c2) {
    T d = abs(c1.p - c2.p);
    T a = std::acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    T t = angle(c2.p - c1.p);
    point< T > p1 = c1.p + point< T >(std::cos(t + a), std::sin(t + a)) * c1.r;
    point< T > p2 = c1.p + point< T >(std::cos(t - a), std::sin(t - a)) * c1.r;
    return {p1, p2};
}
#line 4 "A.cpp"

const f64 eps = 1e-8;

vector<f64> quad(f64 a, f64 b, f64 c) {
    if(abs(a) < eps) {
        if(abs(b) < eps) {
            return {};
        } else {
            return {- c / b};
        }
    } else {
        f64 D = b * b - 4.0 * a * c;
        if(D < 0) return {};
        return {
            (- b - sqrt(D)) / (2.0 * a), 
            (- b + sqrt(D)) / (2.0 * a)
        };
    }
}


void solve(int N, int T, int R) {
    vector<string> nickname(N);
    vector p(N, vector(T + 1, point<f64>(0, 0)));
    for(int i : rep(N)) {
        cin >> nickname[i];
        int t, x, y; cin >> t >> x >> y;
        p[i][t] = point<f64>(x, y);

        int pt = t;
        while(true) {
            cin >> t >> x >> y;
            point<f64> v(x, y);
            for(int now : rep(pt, t)) p[i][now + 1] = p[i][now] + v;
            pt = t;
            if(t == T) break;
        }
    }

    vector<tuple<f64,int,int,int>> event;
    for(int i : rep(N)) for(int j : rep(N)) if(i != j) {
        vector<f64> ts;
        if(abs(p[i][0] - p[j][0]) <= R + eps) ts.push_back(0);
        for(int t : rep(T)) {
            point<f64> dp = p[i][t] - p[j][t];
            point<f64> dv = (p[i][t + 1] - p[i][t]) - (p[j][t + 1] - p[j][t]);
            f64 a = norm(dv);
            f64 b = dot(dv, dp) * 2.0;
            f64 c = norm(dp) - R * R;
            for(f64 dt : quad(a, b, c)) if(- eps < dt and dt < 1 + eps) ts.push_back(t + dt);
        }
        unique(ts);
        int exist = 0;
        for(f64 t : ts) {
            exist ^= 1;
            event.push_back({t, exist, i, j});
        }
    }
    sort(event);

    vector graph(N, vector(N, 0));
    for(int i : rep(N)) for(int j : rep(N)) if(i != j) {
        if(abs(p[i][0] - p[j][0]) <= R + eps) graph[i][j] = true;
    }
    
    vector<int> ans(N, 0);
    ans[0] = true;
    for(auto [t, q, u, v] : event) {
        graph[u][v] = graph[v][u] = q;
        if(q) {
            if(ans[u] != ans[v]) {
                queue<int> que;
                que.push(u);
                que.push(v);
                while(not que.empty()) {
                    int x = que.front(); que.pop();
                    if(ans[x]) continue;
                    ans[x] = true;
                    for(int nx : rep(N)) if(graph[x][nx] and not ans[nx]) que.push(nx);
                }
            }
        }
    }

    vector<string> name;
    for(int i : rep(N)) if(ans[i]) name.push_back(nickname[i]);
    sort(name);
    print_n(name);
}

int main() {
    while(true) {
        int N, T, R; cin >> N >> T >> R;
        if(N == 0) return 0;
        solve(N, T, R);
    }
}
accuracy: 1
time_ms: 120
memory_kb: 6452
final_rank: 14

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 2 "cp-library/src/geometry/base.hpp"

template < class T > struct point {
    T x, y;
    point() : x(0), y(0) {}
    point(T x, T y) : x(x), y(y) {}
    point(std::pair< T, T > p) : x(p.first), y(p.second) {}
    point& operator+=(const point& p) { x += p.x, y += p.y; return *this; }
    point& operator-=(const point& p) { x -= p.x, y -= p.y; return *this; }
    point& operator*=(const T r) { x *= r, y *= r; return *this; }
    point& operator/=(const T r) { x /= r, y /= r; return *this; }
    point operator+(const point& p) const { return point(*this) += p; }
    point operator-(const point& p) const { return point(*this) -= p; }
    point operator*(const T r) const { return point(*this) *= r; }
    point operator/(const T r) const { return point(*this) /= r; }
    point operator-() const { return {-x, -y}; }
    bool operator==(const point& p) const { return x == p.x and y == p.y; }
    bool operator!=(const point& p) const { return x != p.x or  y != p.y; }
    bool operator<(const point& p) const { return x == p.x ? y < p.y : x < p.x; }
    point< T > rot(double theta) {
        static_assert(is_floating_point_v< T >);
        double cos_ = std::cos(theta), sin_ = std::sin(theta);
        return {cos_ * x - sin_ * y, sin_ * x + cos_ * y};
    }
};
template < class T > istream& operator>>(istream& is, point< T >& p) { return is >> p.x >> p.y; }
template < class T > ostream& operator<<(ostream& os, point< T >& p) { return os << p.x << " " << p.y; }
template < class T > T dot(const point< T >& a, const point< T >& b) { return a.x * b.x + a.y * b.y; }
template < class T > T det(const point< T >& a, const point< T >& b) { return a.x * b.y - a.y * b.x; }
template < class T > T norm(const point< T >& p) { return p.x * p.x + p.y * p.y; }
template < class T > double abs(const point< T >& p) { return std::sqrt(norm(p)); }
template < class T > double angle(const point< T >& p) { return std::atan2(p.y, p.x); }
template < class T > int sign(const T x) {
    T e = (is_integral_v< T > ? 1 : 1e-8);
    if(x <= -e) return -1;
    if(x >= +e) return +1;
    return 0;
}
template < class T > bool equals(const T& a, const T& b) { return sign(a - b) == 0; }
template < class T > int ccw(const point< T >& a, point< T > b, point< T > c) {
    b -= a, c -= a;
    if(sign(det(b, c)) == +1) return +1; // counter clockwise
    if(sign(det(b, c)) == -1) return -1; //         clockwise
    if(sign(dot(b, c)) == -1) return +2; // c-a-b
    if(norm(b) < norm(c)) return -2;     // a-b-c
    return 0;                            // a-c-b
}

template < class T > struct line {
    point< T > a, b;
    line() {}
    line(point< T > a, point< T > b) : a(a), b(b) {}
};
template < class T > point< T > projection(const line< T >& l, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    return l.a + (l.a - l.b) * dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
}
template < class T > point< T > reflection(const line< T >& l, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    return p + (projection(l, p) - p) * T(2);
}
template < class T > bool orthogonal(const line< T >& a, const line< T >& b) { return equals(dot(a.b - a.a, b.b - b.a), T(0)); }
template < class T > bool parallel  (const line< T >& a, const line< T >& b) { return equals(det(a.b - a.a, b.b - b.a), T(0)); }
template < class T > point< T > cross_point_ll(const line< T >& l, const line< T >& m) {
    static_assert(is_floating_point_v< T >);
    T A = det(l.b - l.a, m.b - m.a);
    T B = det(l.b - l.a, l.b - m.a);
    if(equals(abs(A), T(0)) and equals(abs(B), T(0))) return m.a;
    return m.a + (m.b - m.a) * B / A;
}

template < class T > using segment = line< T >;
template < class T > bool intersect_ss(const segment< T >& s, const segment< T >& t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 and ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
template < class T > double distance_sp(const segment< T >& s, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    point r = projection(s, p);
    if(ccw(s.a, s.b, r) == 0) return abs(r - p);
    return std::min(abs(s.a - p), abs(s.b - p));
}
template < class T > double distance_ss(const segment< T >& a, const segment< T >& b) {
    if(intersect_ss(a, b)) return 0;
    return std::min({ distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), distance_sp(b, a.b) });
}

template < class T > using polygon = std::vector< point< T > >;
template < class T > T area2(const polygon< T >& p) {
    T s = 0;
    int n = p.size();
    for(int i = 0; i < n; i++) s += det(p[i], p[(i + 1) % n]);
    return s;
}
template < class T > T area(const polygon< T >& p) { return area2(p) / T(2); }

template < class T > bool is_convex(const polygon< T >& p) {
    int n = p.size();
    for(int i = 0; i < n; i++) if(ccw(p[(i - 1 + n) % n], p[i], p[(i + 1) % n]) == -1) return false;
    return true;
}
template < class T > int contains(const polygon< T >& g, const point< T >& p) {
    int n = g.size();
    bool in = false;
    for(int i = 0; i < n; i++) {
        point a = g[i] - p, b = g[(i + 1) % n] - p;
        if(sign(a.y - b.y) == +1) std::swap(a, b);
        if(sign(a.y) <= 0 and sign(b.y) ==+1 and sign(det(a, b)) == -1) in = !in;
        if(sign(det(a, b)) == 0 and sign(dot(a, b)) <= 0) return 1; // ON
    }
    return in ? 2 : 0;
}
template < class T > polygon< T > convex_cut(const polygon< T >& p, const line< T >& l) {
    int n = p.size();
    polygon< T > res;
    for(int i = 0; i < n; i++) {
        point now = p[i], nxt = p[(i + 1) % n];
        if(ccw(l.a, l.b, now) != -1) res.push_back(now);
        if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) res.push_back(cross_point_ll(line(now, nxt), l));
    }
    return res;
}
template < class T > polygon< T > convex_hull(polygon< T >& p) {
    int n = p.size(), k = 0;
    if(n <= 2) return p;
    std::sort(p.begin(), p.end());
    polygon< T > ch(n + n);
    for(int i = 0; i < n; ch[k++] = p[i++])
        while(k >= 2 and sign(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) == -1) k--;
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--])
        while(k >= t and sign(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) == -1) k--;
    ch.resize(k - 1);
    return ch;
}
template < class T > T diameter2(const polygon< T >& p) {
    static_assert(is_floating_point_v< T >);
    int n = p.size(), is = 0, js = 0;
    for(int i = 1; i < n; i++) {
        if(sign(p[i].y - p[is].y) == +1) is = i;
        if(sign(p[i].y - p[js].y) == -1) js = i;
    }
    T dist_max = norm(p[is] - p[js]);
    int maxi = is, i = is, maxj = js, j = js;
    do {
        if(sign(det(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j])) >= 0) j = (j + 1) % n; else i = (i + 1) % n;
        if(norm(p[i] - p[j]) > dist_max) {
            dist_max = norm(p[i] - p[j]);
            maxi = i, maxj = j;
        }
    } while(i != is or j != js);
    return dist_max;
}
template < class T > double diameter(const polygon< T >& p) {
    static_assert(is_floating_point_v< T >);
    return std::sqrt(diameter2(p));
}

template < class T > struct circle {
    point< T > p;
    T r;
    circle() = default;
    circle(point< T > p, T r) : p(p), r(r) {}
};
template < class T > istream& operator>>(istream& is, circle< T >& c) { return is >> c.p >> c.r; }
template < class T > int intersect_cc(circle< T > c1, circle< T > c2) {
    if(c1.r < c2.r) std::swap(c1, c2);
    T d = abs(c1.p - c2.p);
    if(sign(c1.r + c2.r - d) == -1) return 4;
    if(equals(c1.r + c2.r, d)) return 3;
    if(sign(c1.r - c2.r - d) == -1) return 2;
    if(equals(c1.r - c2.r, d)) return 1;
    return 0;
}
template < class T > std::pair<point< T >, point< T >> cross_point_cc(const circle< T >& c1, const circle< T >& c2) {
    T d = abs(c1.p - c2.p);
    T a = std::acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    T t = angle(c2.p - c1.p);
    point< T > p1 = c1.p + point< T >(std::cos(t + a), std::sin(t + a)) * c1.r;
    point< T > p2 = c1.p + point< T >(std::cos(t - a), std::sin(t - a)) * c1.r;
    return {p1, p2};
}
#line 4 "A.cpp"

const f64 eps = 1e-8;

vector<f64> quad(f64 a, f64 b, f64 c) {
    if(abs(a) < eps) {
        if(abs(b) < eps) {
            return {};
        } else {
            return {- c / b};
        }
    } else {
        f64 D = b * b - 4.0 * a * c;
        if(D < 0) return {};
        return {
            (- b - sqrt(D)) / (2.0 * a), 
            (- b + sqrt(D)) / (2.0 * a)
        };
    }
}


void solve(int N, int T, int R) {
    vector<string> nickname(N);
    vector p(N, vector(T + 1, point<f64>(0, 0)));
    for(int i : rep(N)) {
        cin >> nickname[i];
        int t, x, y; cin >> t >> x >> y;
        p[i][t] = point<f64>(x, y);

        int prev = t;
        while(true) {
            cin >> t >> x >> y;
            point<f64> v(x, y);
            for(int now : rep(prev, t)) p[i][now + 1] = p[i][now] + v;
            prev = t;
            if(t == T) break;
        }
    }

    vector<tuple<f64,int,int,int>> event;
    for(int i : rep(N)) for(int j : rep(N)) if(i != j) {
        vector<f64> ts;
        if(abs(p[i][0] - p[j][0]) <= R + eps) ts.push_back(0);
        for(int t : rep(T)) {
            point<f64> dp = p[i][t] - p[j][t];
            point<f64> dv = (p[i][t + 1] - p[i][t]) - (p[j][t + 1] - p[j][t]);
            f64 a = norm(dv);
            f64 b = dot(dv, dp) * 2.0;
            f64 c = norm(dp) - R * R;
            for(f64 dt : quad(a, b, c)) if(- eps < dt and dt < 1 + eps) ts.push_back(t + dt);
        }
        unique(ts);
        int exist = 0;
        for(f64 t : ts) {
            exist ^= 1;
            event.push_back({t, exist, i, j});
        }
    }
    sort(event);

    vector graph(N, vector(N, 0));
    for(int i : rep(N)) for(int j : rep(N)) if(i != j) {
        if(abs(p[i][0] - p[j][0]) <= R + eps) {
            graph[i][j] = true;
        }
    }
    vector<int> ans(N, 0);
    ans[0] = true;
    for(auto [t, q, u, v] : event) {
        graph[u][v] = graph[v][u] = q;
        if(q) {
            if(ans[u] != ans[v]) {
                queue<int> que;
                que.push(u);
                que.push(v);
                while(not que.empty()) {
                    int x = que.front(); que.pop();
                    if(ans[x]) continue;
                    ans[x] = true;
                    for(int nx : rep(N)) if(graph[x][nx] and not ans[nx]) que.push(nx);
                }
            }
        }
    }

    vector<string> name;
    for(int i : rep(N)) if(ans[i]) name.push_back(nickname[i]);
    sort(name);
    print_n(name);
}

int main() {
    while(true) {
        int N, T, R; cin >> N >> T >> R;
        if(N == 0) return 0;
        solve(N, T, R);
    }
}
accuracy: 1
time_ms: 120
memory_kb: 6376
final_rank: 13

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cassert>
#include<sstream>
#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<utility>
#include<numeric>
#include<algorithm>
#include<bitset>
#include<complex>
#include<cstring>

using namespace std;

typedef pair<int,int> pint;
typedef pair<double,double> Point;

int INF=1001001001;

double dis2(Point p1, Point p2){
    return (p1.first-p2.first)*(p1.first-p2.first)+(p1.second-p2.second)*(p1.second-p2.second);
}
Point linedist00(double x, double y, double vx, double vy){
    double l=(x*vy-y*vx)/(vx*vx+vy*vy);
    return Point(l * vy, -l * vx);
}
pair<double,double > culc(double r,double x,double y,double vx,double vy){
    Point p2=linedist00(x, y, vx, vy);
    double vv= dis2(Point(0, 0), Point(vx, vy));
    double d2= dis2(Point(0, 0), p2);
    if(d2 <= r*r){
        double l=r*r-d2;
        double t;
        if(vx==0 && vy==0) return make_pair(INF, INF);
        else if(vx==0) t= (p2.second-y)/vy;
        else t= (p2.first-x)/vx;
        double dt=sqrt(l/vv);
        return make_pair(t-dt, t+dt);
    }else{
        return make_pair(INF, INF);
    }
}
struct str{
    double t;
    pint p;
    int f;
    str(double t0,pint p0,int f0){
        t=t0; p=p0; f=f0;
    }
};
bool operator < (str a,str b){
    return a.t>b.t;
}
void prints(str a){
    printf("t=%f  %d---%d  %d\n",a.t,a.p.first,a.p.second,a.f);
}
signed main(){

#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int i,j,k;
    int n,t,r;
    Point xy[100];
    pair<int,int> v[100][1000];
    string name[1000];
    int vis[100];
    while(true){
        cin >> n >> t >> r;
        if(n==0) break;
        for(i=0;i<100;i++){
            vis[i]=0;
            for(j=0;j<1000;j++){
                v[i][j]=pint(INF,INF);
            }
        }
        for(i=0;i<n;i++){
            cin >> name[i];
            cin >> k >> xy[i].first >> xy[i].second;
            while(true){
                int tk,vx,vy;
                scanf("%d%d%d",&tk,&vx,&vy);
                v[i][tk-1].first=vx;
                v[i][tk-1].second=vy;
                if(tk==t) break;
            }
        }
        for(k=0;k<n;k++){
            pint tmp=v[k][t-1];
            for(i=t-2;i>=0;i--){
                if(v[k][i].first==INF) v[k][i]=tmp;
                else tmp=v[k][i];
            }
        }
        int a[100][100];
        //未移动时的相交情况
        for(j=0;j<n;j++){
            for(k=0;k<n;k++){
                if(dis2(xy[j], xy[k]) <= r * r) a[j][k]=1;
                else a[j][k]=0;
            }
        }
        queue<int> q;
        q.push(0);
        while(!q.empty()){
            int f=q.front(); q.pop();
            if(vis[f] == 1) continue;
            else{
                vis[f]=1;
                for(i=0;i<n;i++){
                    if(a[f][i]==1) q.push(i);
                }
            }
        }
        for(i=0;i<t;i++){
            priority_queue<str> pq;
            for(j=0;j<n;j++){
                for(k=j+1;k<n;k++){
                    int x1=xy[k].first-xy[j].first,y1=xy[k].second-xy[j].second;
                    int vx=v[k][i].first-v[j][i].first,vy=v[k][i].second-v[j][i].second;
                    pair<double,double > time=culc(r,x1,y1,vx,vy);
                    if(time.first==INF) continue;
                    double t1=INF,t2=INF;
                    if(time.first >= 0.0){
                        if(time.second <= 1.0){
                            t1=time.first;
                            t2=time.second;
                        }else if(time.first <= 1.0){
                            t1=time.first;
                        }
                    }else{
                        if(time.second>=0 && time.second<=1.0){
                            t2=time.second;
                        }
                    }
                    if(t1!=INF) pq.push(str(t1,pint(j,k),1));
                    if(t2!=INF) pq.push(str(t2,pint(j,k),0));
                }
            }
            while(!pq.empty()){
                str tmp=pq.top(); pq.pop();
//                prints(tmp);
                a[tmp.p.first][tmp.p.second]=tmp.f;
                a[tmp.p.second][tmp.p.first]=tmp.f;
                if(tmp.f==1){
                    if(vis[tmp.p.first] == 0 && vis[tmp.p.second] == 1) swap(tmp.p.first, tmp.p.second);
                    if(vis[tmp.p.first] == 1 && vis[tmp.p.second] == 0){
                        queue<int> q2;
                        q2.push(tmp.p.second);
                        vis[tmp.p.second]=1;
                        while(!q2.empty()){
                            k=q2.front();
                            q2.pop();
                            for(j=0;j<n;j++){
                                if(a[j][k]==1 && vis[j] == 0){
                                    vis[j]=1;
                                    q2.push(j);
                                }
                            }
                        }
                    }
                }
            }
            for(j=0;j<n;j++){
                xy[j].first+=v[j][i].first;
                xy[j].second+=v[j][i].second;
            }
        }

        vector<string> ans;
        int cnt=0;
        for(i=0;i<n;i++){
            if(vis[i] == 1){
                ans.push_back(name[i]);
                cnt++;
            }
        }
        sort(ans.begin(),ans.end());
        for(i=0;i<cnt;i++){
            cout << ans[i] << endl;
        }

    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4436
final_rank: 8

code_snippet: #include<bits/stdc++.h> 
using namespace std;
using ll=long long int;
//using Int=__int128;
#define ALL(A) A.begin(),A.end()
template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}
template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>=b)return 0; a=b; return 1;}
template<typename T> constexpr int bitUP(T x,int a){return (x>>a)&1;}
//→　↓　←　↑ 
int dh[4]={0,1,0,-1}, dw[4]={1,0,-1,0};
//右上から時計回り
//int dh[8]={-1,0,1,1,1,0,-1,-1}, dw[8]={1,1,1,0,-1,-1,-1,0};
//long double EPS = 1e-6;
//long double PI = acos(-1);
//const ll INF=(1LL<<62);
const int MAX=(1<<30);
constexpr ll MOD=1000000000+7;
//constexpr ll MOD=998244353;


inline void bin101(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);
}

using pii=pair<int,int>;
using pil=pair<int,ll>;
using pli=pair<ll,int>;
using pll=pair<ll,ll>;
using psi=pair<string,int>;
using pis=pair<int,string>;
using psl=pair<string,ll>;
using pls=pair<ll,string>;
using pss=pair<string,string>;

using Graph=vector<vector<int>>;

template<typename T >
struct edge {
	int to;
	T cost;
	edge()=default;
	edge(int to, T cost) : to(to), cost(cost) {}

};
template<typename T>
using WeightGraph=vector<vector<edge<T>>>;

template<typename T>
void CinGraph(int M,WeightGraph<T> &g,bool directed=false,bool index1=true){
    while(M--){
        int s,t;
        T cost;
        cin>>s>>t>>cost;
        if(index1) s--,t--;
        g[s].emplace_back(t,cost);
        if(not directed) g[t].emplace_back(s,cost);
    }
}

void CinGraph(int M,Graph &g,bool directed=false,bool index1=true){
    while(M--){
        int s,t;
        cin>>s>>t;
        if(index1) s--,t--;
        g[s].push_back(t);
        if(not directed) g[t].push_back(s);
    }
}


//0-indexed vector cin
template<typename T>
inline istream &operator>>(istream &is,vector<T> &v) {
    for(size_t i=0;i<v.size();i++) is>>v[i];
	return is;
}
 
//0-indexed vector cin
template<typename T>
inline istream &operator>>(istream &is,vector<vector<T>> &v) {
    for(size_t i=0;i<v.size();i++){
        is>>v[i];
    }
    return is;
}
//vector cout
template<typename T>
inline ostream &operator<<(ostream &os,const vector<T> &v) {
    for(size_t i=0;i<v.size();i++){
        if(i) os<<" ";
        os<<v[i];
    }
    return os;
}
//vector<vector> cout
template<typename T>
inline ostream &operator<<(ostream &os,const vector<vector<T>> &v) {
    for(size_t i=0;i<v.size();i++){
        os<<v[i];
        if(i+1!=v.size()) os<<"\n";
    }
    return os;
}

//Graph out
template<typename T>
inline ostream &operator<<(ostream &os,const Graph &g) {
    for(size_t i=0;i<g.size();i++){
        for(int to:g[i]){
            os<<i<<"->"<<to<<" ";
        }
        os<<endl;
    }
    return os;
}

//WeightGraph out
template<typename T>
inline ostream &operator<<(ostream &os,const WeightGraph<T> &g) {
    for(size_t i=0;i<g.size();i++){
        for(auto e:g[i]){
            os<<i<<"->"<<e.to<<"("<<e.cost<<") ";
        }
        os<<endl;
    }
    return os;
}


//要素数n 初期値x
template<typename T>
inline vector<T> vmake(size_t n,T x){
	return vector<T>(n,x);
}

//a,b,c,x data[a][b][c] 初期値x
template<typename... Args>
auto vmake(size_t n,Args... args){
	auto v=vmake(args...);
	return vector<decltype(v)>(n,move(v));
}
template<typename V,typename T>
void fill(V &v,const T value){
    v=value;
}

template<typename V,typename T>
void fill(vector<V> &vec,const T value){
    for(auto &v:vec) fill(v,value);
}

//pair cout
template<typename T, typename U>
inline ostream &operator<<(ostream &os,const pair<T,U> &p) {
	os<<p.first<<" "<<p.second;
	return os;
}
 
//pair cin
template<typename T, typename U>
inline istream &operator>>(istream &is,pair<T,U> &p) {
	is>>p.first>>p.second;
	return is;
}
 
//ソート
template<typename T>
inline void vsort(vector<T> &v){
    sort(v.begin(),v.end());
}
 
//逆順ソート
template<typename T>
inline void rvsort(vector<T> &v){
	sort(v.rbegin(),v.rend());
}

//1ビットの数を返す
inline int popcount(int x){
	return __builtin_popcount(x);
}
//1ビットの数を返す
inline int popcount(ll x){
	return __builtin_popcountll(x);
}
template<typename T>
inline void Compress(vector<T> &C){
    sort(C.begin(),C.end());
    C.erase(unique(C.begin(),C.end()),C.end());
}
template<typename T>
inline int lower_idx(const vector<T> &C,T value){
    return lower_bound(C.begin(),C.end(),value)-C.begin();
}
template<typename T>
inline int upper_idx(const vector<T> &C,T value){
    return upper_bound(C.begin(),C.end(),value)-C.begin();
}
//時計回りに90度回転
template<typename T>
inline void rotate90(vector<vector<T>> &C){
    vector<vector<T>> D(C[0].size(),vector<T>(C.size()));
    for(int h=0;h<C.size();h++){
        for(int w=0;w<C[h].size();w++){
            D[w][C.size()-1-h]=C[h][w];
        }
    }
    C=D;
}
//補グラフを返す
//i→iのような辺は加えない
Graph ComplementGraph(const Graph &g){
    size_t sz=g.size();
    bool used[sz][sz];
    fill(used[0],used[sz],false);
    for(size_t i=0;i<sz;i++){
        for(int to:g[i]){
            used[i][to]=true;
        }
    }
    Graph ret(sz);
    for(size_t i=0;i<sz;i++){
        for(size_t j=0;j<sz;j++){
            if(used[i][j]) continue;
            if(i==j) continue;
            ret[i].push_back(j);
        }
    }
    return ret;
}
//グラフの分解 secondはある頂点がどこに対応するか id[i]={2,3}のとき,頂点iはret[2][3]に対応
//無効グラフのみに対応
pair<vector<Graph>,vector<pair<int,int>>> GraphDecomposition(const Graph &g){
    vector<pair<int,int>> id(g.size(),pair<int,int>(-1,-1));
    vector<Graph> ret;
    vector<int> now;
    for(size_t i=0;i<g.size();i++){
        if(id[i].first!=-1) continue;
        id[i].first=ret.size();
        id[i].second=0;
        now.push_back(i);
        for(size_t j=0;j<now.size();j++){
            for(int to:g[now[j]]){
                if(id[to].first==-1){
                    id[to].first=ret.size();
                    id[to].second=now.size();
                    now.push_back(to);
                }
            }
        }
        Graph r(now.size());
        for(size_t j=0;j<now.size();j++){
            r[j]=g[now[j]];
            for(int &to:r[j]){
                to=id[to].second;
            }
        }
        ret.push_back(r);
        now.clear();
    }
    return make_pair(ret,id);
}
//0indexを想定
bool OutGrid(ll h,ll w,ll H,ll W){
    return (h>=H or w>=W or h<0 or w<0);
}

void NO(){
    cout<<"NO"<<"\n";
}
void YES(){
    cout<<"YES"<<"\n";
}
void No(){
    cout<<"No"<<"\n";
}
void Yes(){
    cout<<"Yes"<<"\n";
}
namespace overflow{
    template<typename T>
    T max(){
        return numeric_limits<T>::max();
    }
    template<typename T>
    T ADD(T a,T b){
        T res;
        return __builtin_add_overflow(a,b,&res)?max<T>():res;
    }
    template<typename T>
    T MUL(T a,T b){
        T res;
        return __builtin_mul_overflow(a,b,&res)?max<T>():res;
    }
};
using namespace overflow;
struct ModInt{
    using u64=uint_fast64_t;
    u64 a;
    constexpr ModInt() :a(0){}
    constexpr ModInt(ll x) :a((x>=0)?(x%MOD):(x%MOD+MOD) ) {}

    inline constexpr ModInt operator+(const ModInt rhs)const noexcept{
        return ModInt(*this)+=rhs;
    }
    inline constexpr ModInt operator-(const ModInt rhs)const noexcept{
        return ModInt(*this)-=rhs;
    }
    inline constexpr ModInt operator*(const ModInt rhs)const noexcept{
        return ModInt(*this)*=rhs;
    }
    inline constexpr ModInt operator/(const ModInt rhs)const noexcept{
        return ModInt(*this)/=rhs;
    }
    inline constexpr ModInt operator+(const ll rhs) const noexcept{
        return ModInt(*this)+=ModInt(rhs);
    }
    inline constexpr ModInt operator-(const ll rhs)const noexcept{
        return ModInt(*this)-=ModInt(rhs);
    }
    inline constexpr ModInt operator*(const ll rhs)const noexcept{
        return ModInt(*this)*=ModInt(rhs);
    }
    inline constexpr ModInt operator/(const ll rhs)const noexcept{
        return ModInt(*this)/=ModInt(rhs);
    }

    inline constexpr ModInt &operator+=(const ModInt rhs)noexcept{
        a+=rhs.a;
        if(a>=MOD) a-=MOD;
        return *this;
    }
    inline constexpr ModInt &operator-=(const ModInt rhs)noexcept{
        if(rhs.a>a) a+=MOD;
        a-=rhs.a;
        return *this;
    }
    inline constexpr ModInt &operator*=(const ModInt rhs)noexcept{
        a=(a*rhs.a)%MOD;
        return *this;
    }
    inline constexpr ModInt &operator/=(ModInt rhs)noexcept{
        a=(a*rhs.inverse().a)%MOD;
        return *this;
    }
    inline constexpr ModInt &operator+=(const ll rhs)noexcept{
        return *this+=ModInt(rhs);
    }
    inline constexpr ModInt &operator-=(const ll rhs)noexcept{
        return *this-=ModInt(rhs);
    }
    inline constexpr ModInt &operator*=(const ll rhs)noexcept{
        return *this*=ModInt(rhs);
    }
    inline constexpr ModInt &operator/=(const ll rhs)noexcept{
        return *this/=ModInt(rhs);
    }

    inline constexpr ModInt operator=(const ll x)noexcept{
        a=(x>=0)?(x%MOD):(x%MOD+MOD);
        return *this;
    }

    inline constexpr bool operator==(const ModInt p)const noexcept{
        return a==p.a;
    }

    inline constexpr bool operator!=(const ModInt p)const noexcept{
        return a!=p.a;
    }

    inline constexpr ModInt pow(ll N) const noexcept{
        ModInt ans(1LL),p(a);
        while(N>0){
            if(bitUP(N,0)){
                ans*=p;
            }
            p*=p;
            N>>=1;
        }
        return ans;
    }
    inline constexpr ModInt inverse() const noexcept{
        return pow(MOD-2);
    }

};
inline constexpr ModInt operator+(const ll &a,const ModInt &b)noexcept{
    return ModInt(a)+=b;
}
inline constexpr ModInt operator-(const ll &a,const ModInt &b)noexcept{
    return ModInt(a)-=b;
}
inline constexpr ModInt operator*(const ll &a,const ModInt &b)noexcept{
    return ModInt(a)*=b;
}
inline constexpr ModInt operator/(const ll &a,const ModInt &b)noexcept{
    return ModInt(a)/=b;
}
//cout
inline ostream &operator<<(ostream &os,const ModInt &p) {
    return os<<p.a;
}

//cin
inline istream &operator>>(istream &is,ModInt &p) {
    ll t;
    is>>t;
    p=t;
    return is;
}

struct Binominal{
    vector<ModInt> fac,finv,inv; //fac[n]:n! finv:(n!)の逆元
    int sz;
    Binominal(int n=10) :sz(1){
        if(n<=0) n=10;
        init(n);
    }
    inline void init(int n){
        fac.resize(n+1,1);
        finv.resize(n+1,1);
        inv.resize(n+1,1);
        for(int i=sz+1;i<=n;i++){
            fac[i]=fac[i-1]*i;
            inv[i]=MOD-inv[MOD%i]*(MOD/i);
            finv[i]=finv[i-1]*inv[i];
        }
        sz=n;
    }
    //nCk(n,k<=N) をO(1)で求める
    inline ModInt com(int n,int k){
        if(n<k) return ModInt(0);
        if(n<0 || k<0) return ModInt(0);
        if(n>sz) init(n);
        return fac[n]*finv[k]*finv[n-k];
    }
    //nCk(k<=N) をO(k)　で求める 
    inline ModInt rcom(ll n,int k){
        if(n<0 || k<0 || n<k) return ModInt(0);
        if(k>sz) init(k);
        ModInt ret(1);
        for(int i=0;i<k;i++){
            ret*=n-i;
        }
        ret*=finv[k];
        return ret;
    }

    //重複組み合わせ n種類のものから重複を許してk個を選ぶ
    //〇がn個,|がk個
    inline ModInt h(int n,int k){
        return com(n+k-1,k);
    }
};
vector<int> Subset(int S,bool zero=false,bool full=false){
    vector<int> ret;
    int now=(S-1)&S;
    if(full and S){
        ret.push_back(S);
    }
    do{
        ret.push_back(now);
        now=(now-1)&S;
    }while(now!=0);
    if(zero){
        ret.push_back(0);
    }
    return ret;
}
template<typename T>
T SUM(const vector<T> &v,int s,int t){
    chmax(s,0);
    chmin(t,int(v.size())-1);
    if(s>t) return 0;
    if(s==0) return v[t];
    else return v[t]-v[s-1];
}
template<typename T>
void buildSUM(vector<T> &v){
    for(size_t i=1;i<v.size();i++){
        v[i]+=v[i-1];
    }
    return;
}
////////////////////////////
// マクロや型
////////////////////////////

using DD=long double;

const DD EPS=1e-14;
const DD INF=1e50;
const DD PI=acosl(-1.0);
#define EQ(a,b) (abs( (a) - (b) )<EPS) //a==b
#define LS(a,b) ( (a)+EPS<(b) ) //a<b
#define GR(a,b) ( (a)>(b)+EPS ) //a>b
#define LE(a,b) ( (a)<(b)+EPS ) //a<=b
#define GE(a,b) ( (a)>(b)-EPS ) //a>=b

#define X real()
#define Y imag()


//点
using Point=complex<DD>;
istream &operator>>(istream &is, Point &p) {
  DD x,y;
  is>>x>>y;
  p=Point(x,y);
  return is;
}
void debug(Point p,string name=""){
    cout<<p.X<<" "<<p.Y<<" "<<name<<endl;
}

//点a→点bの線分
//aとbが等しい時、色々バグるから注意!
struct Segment{
    Point a,b;
    Segment()=default;
    Segment(Point a,Point b) :a(a),b(b){}
    Segment(DD ax,DD ay,DD bx,DD by):a(ax,ay),b(bx,by){}
    Segment(DD r,Point a) :a(a),b(a+polar((DD)1.0,r)){}
    void debug(bool isLine=false,string name=""){
        string type="Segment ";
        if(isLine) type="Line ";
        cout<<type<<a.X<<" "<<a.Y<<" "<<b.X<<" "<<b.Y<<" "<<name<<endl;
    }
};
using Line=Segment;

//円
struct Circle{
    Point p;
    DD r;
    Circle()=default;
    Circle(Point p,DD r):p(p),r(r){}
    void debug(string name=""){
        cout<<"Circle "<<p.X<<" "<<p.Y<<" "<<r<<" "<<name<<endl;
    }
};

using Polygon=vector<Point>;
void debug(Polygon pol,string name=""){
    cout<<"Polygon"<<" "<<name<<endl;
    for(auto p:pol){
        cout<<p.X<<" "<<p.Y<<endl;
    }
    cout<<"..."<<endl;
}

////////////////////////////
// 基本計算
////////////////////////////

//度→ラジアン
inline DD torad(const DD deg){return deg*PI/180;}
//ラジアン→度
inline DD todeg(const DD rad){return rad*180/PI;}
//内積 |a||b|cosθ
inline DD dot(const Point &a,const Point &b){return (conj(a)*b).X;}
//外積 |a||b|sinθ
inline DD cross(const Point &a,const Point &b){return (conj(a)*b).Y;}
//ベクトルpを反時計回りにtheta(ラジアン)回転
Point rotate(const Point &p,const DD theta){return p*Point(cos(theta),sin(theta));}

//余弦定理 cos(角度abc(ラジアン))を返す
//長さの対応に注意 ab:辺abの長さ
//verify:https://codeforces.com/gym/102056/problem/F
DD cosine_formula(const DD ab,const DD bc,const DD ca){
    return (ab*ab+bc*bc-ca*ca)/(2*ab*bc);
}

inline bool xy_sort(const Point &a,const Point &b){
    if(a.X+EPS<b.X) return true;
    if(EQ(a.X,b.X) && a.Y+EPS<b.Y) return true;
    return false;
}
inline bool yx_sort(const Point &a,const Point &b){
    if(a.Y+EPS<b.Y) return true;
    if(EQ(a.Y,b.Y) && a.X+EPS<b.X) return true;
    return false;
}
namespace std{
    inline bool operator<(const Point &a,const Point &b)noexcept{
        return xy_sort(a,b);
    }
}
//DDの比較関数
//map<DD,vector<pii>,DDcom>
struct DDcom{
    bool operator()(const DD a, const DD b) const noexcept {
        return a+EPS<b;
    }
};


////////////////////////////
// 平行や直交
////////////////////////////

bool isOrthogonal(const Point &a,const Point &b){
    return EQ(dot(a,b),0.0);
}
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool isOrthogonal(const Segment &s,const Segment &t){
    return EQ(dot(s.a-s.b,t.a-t.b),0.0);
}
bool isParallel(const Point &a,const Point &b){
    return EQ(cross(a,b),0.0);
}
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool isParallel(const Segment &s,const Segment &t){
    return EQ(cross(s.a-s.b,t.a-t.b),0);
}
//線分a→bに対して点cがどの位置にあるか
//反時計回り:1　時計回り:-1 直線上(a,b,c:-2 a,c,b:0 c,a,b:2)
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
//線分a→bの端点にcがあるなら0と判定されるはず
int ccw(const Point &a,Point b,Point c){
    if(EQ(abs(b-c),0) or EQ(abs(a-c),0)) return 0;
    b-=a;c-=a;
    if(cross(b,c)>EPS) return 1;
    if(cross(b,c)<-EPS) return -1;
    if(dot(b,c)<-EPS) return 2;
    if(LS(norm(b),norm(c))) return -2;
    return 0;
}

////////////////////////////
// 射影と反射
////////////////////////////

//射影
//直線lに点pから垂線を引いたときの交点
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point project(const Point &p,const Line &l){
    Point base=l.b-l.a;
    DD r=dot(p-l.a,base)/norm(base);
    return l.a+base*r;
}
//反射
//直線lに対して点pと対称な点
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflect(const Point &p,const Line &l){
    return p+(project(p,l)-p)*(DD)2.0;
}
//反射
//直線lに対して線分sと対称な線分(直線でも使える)
//verify:https://onlinejudge.u-aizu.ac.jp/solutions/problem/1171/review/6009447/bin101/C++17
Segment reflect(const Segment &s,const Line &l){
    return Segment(reflect(s.a,l) , reflect(s.b,l));
}

////////////////////////////
// 点との距離
////////////////////////////

//点と直線の距離
DD DistPL(const Point &p,const Line &l){
    return abs(cross(l.b-l.a,p-l.a))/abs(l.b-l.a);
}
//点と線分の距離
DD DistPS(const Point &p,const Segment &s){
    if( dot(s.b-s.a,p-s.a)<0.0 ) return abs(p-s.a);
    if( dot(s.a-s.b,p-s.b)<0.0 ) return abs(p-s.b);
    return DistPL(p,s);
}

////////////////////////////
// 線分と直線
////////////////////////////

//線分a-b,c-dは交差するか?
//接する場合も交差すると判定
//接する場合は交差しないとするなら<=を<に変換
bool intersect(const Point &a,const Point &b,const Point &c,const Point &d){
    return(ccw(a,b,c)*ccw(a,b,d)<=0 && ccw(c,d,a)*ccw(c,d,b)<=0);
}
//線分s,tは交差するか？
//接する場合も交差すると判定
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B&lang=ja
//接する場合は交差しないとするならintersectの<=を<に変換
bool intersect(const Segment &s,const Segment &t){
    return intersect(s.a,s.b,t.a,t.b);
}
// 2直線の交点
// 線分の場合はintersectをしてから使う
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C&lang=ja
Point crossPoint(const Line &s,const Line &t){
    Point base=t.b-t.a;
    DD d1=cross(base,t.a-s.a);
    DD d2=cross(base,s.b-s.a);
    if(EQ(d1,0) and EQ(d2,0)) return s.a; //同じ直線
    if(EQ(d2,0)) assert(false); //交点がない
    return s.a+d1/d2*(s.b-s.a);
}
//線分と線分の距離
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D&lang=ja
DD Dist(const Segment &s,const Segment &t){
    if(intersect(s,t)) return 0.0;
    return min(min(DistPS(t.a,s),DistPS(t.b,s)),min(DistPS(s.a,t),DistPS(s.b,t)) );
}
bool issame(const Line &l,const Line &m){
    if (GR(abs(cross(m.a - l.a, l.b - l.a)),0) ) return false;
    if (GR(abs(cross(m.b - l.a, l.b - l.a)),0) ) return false;
    return true;
}

////////////////////////////
// 円
////////////////////////////
//直線lと円Cの交点
//l.aにより近い方がindexが小さい
//veirfy:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
vector<Point> crossPointLC(const Line &l,const Circle &c){
    vector<Point> ret;
    if(GR(DistPL(c.p,l),c.r)) return ret; //交点がないとき、空ベクトルを返す
    Point pr=project(c.p,l);
    Point e=(l.b-l.a)/(abs(l.b-l.a));
    DD base=sqrt(c.r*c.r-norm(pr-c.p));
    ret.push_back(pr-e*base);
    ret.push_back(pr+e*base);
    if(EQ(DistPL(c.p,l),c.r)) ret.pop_back(); //接するとき
    return ret;
}
//線分sと円cの交点
//交点がないときは空ベクトルを返す
//線分の端が交わる場合も交点とみなす
//s.aにより近い方がindexが小さい
vector<Point> crossPointSC(const Segment &s,const Circle &c){
    vector<Point> ret;
    if(DistPS(c.p,s)>c.r+EPS) return ret;
    auto koho=crossPointLC(s,c);
    for(auto p:koho){
        if(ccw(s.a,s.b,p)==0 or EQ(abs(p-s.a),0) or EQ(abs(p-s.b),0)) ret.push_back(p);
    }
    return ret;
}

//円aと円bの共通接線の数
//離れている:4 外接:3 交わる:2 内接:1 内包:0
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A
int intersect(const Circle &a,const Circle &b){
    DD d=abs(a.p-b.p);
    if(GR(d,a.r+b.r)) return 4;
    if(EQ(d,a.r+b.r)) return 3;
    if(EQ(d,abs(a.r-b.r))) return 1;
    if(LS(d,abs(a.r-b.r))) return 0;
    return 2;
}

//円aと円bの交点
//交点がないときは空ベクトルを返す
//事前にintersectをしたほうがいいかも
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E
vector<Point> crossPoint(const Circle &a,const Circle &b){
    vector<Point> ret;
    if(GR(abs(a.p-b.p),a.r+b.r)) return ret;
    DD d=abs(a.p-b.p);
    DD s=acosl((a.r*a.r+d*d-b.r*b.r)/(2*a.r*d)); //0~π
    DD t=arg(b.p-a.p);
    if(EQ(a.r+b.r,d)) ret.push_back(a.p+polar(a.r,t));
    else ret.push_back(a.p+polar(a.r,t+s)),ret.push_back(a.p+polar(a.r,t-s));
    return ret;
}

//点pから円cに接線を引いたときの接点
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F&lang=ja
vector<Point> TanLine(const Point &p,const Circle &c){
    vector<Point> ret;
    DD d=abs(p-c.p);
    if(LS(d,c.r)) return ret; //pがcの内部にある場合
    if(EQ(d,c.r)){
        ret.push_back(p);
        return ret; //円の線上にある場合
    } 
    return crossPoint(c,Circle(p,sqrt(d*d-c.r*c.r)));
}

//円a,bの共通接線
//https://www.slideshare.net/kujira16/ss-35861169
//Line.aは円aと接線の交点
//(接線と円bの交点)と(接線と円aの交点)が違う場合はLine.bは(接線と円bの交点)
//一致する場合は円aの中心からLine.aに向かうベクトルを反時計回りに90度回転したものを
//Line.aに足したもの
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2201
vector<Line> TanLine(const Circle &a,const Circle &b){
    DD d=abs(a.p-b.p);
    vector<Line> ret;
    //外接線
    if(intersect(a,b)>=2){
        if(EQ(a.r,b.r)){
            Point up=polar(a.r,arg(b.p-a.p)+PI/2);
            ret.emplace_back(a.p+up,b.p+up);
            ret.emplace_back(a.p-up,b.p-up);
        }else{
            Point q=(a.p*b.r-b.p*a.r)/(b.r-a.r);
            auto as=TanLine(q,a);
            auto bs=TanLine(q,b);
            assert(as.size()==2 and bs.size()==2);
            for(int i=0;i<2;i++){
                ret.emplace_back(as[i],bs[i]);
            }
        }
    }else if(intersect(a,b)==1){ //内接する場合
        Point dir;
        if(a.r>b.r) dir=polar(a.r,arg(b.p-a.p));
        else dir=polar(a.r,arg(a.p-b.p));
        ret.emplace_back(a.p+dir,a.p+dir+rotate(dir,PI/2));
    }
    //内接線
    if(GR(abs(a.p-b.p),a.r+b.r)){ //円が離れている場合
        Point q=a.p+(b.p-a.p)*a.r/(a.r+b.r);
        auto as=TanLine(q,a);
        auto bs=TanLine(q,b);
        assert(as.size()==2 and bs.size()==2);
        for(int i=0;i<2;i++){
            ret.emplace_back(as[i],bs[i]);
        }
    }else if(EQ(d,a.r+b.r)){ //円が接している場合
        Point dir=polar(a.r,arg(b.p-a.p));
        ret.emplace_back(a.p+dir,a.p+dir+rotate(dir,PI/2));
    }
    return ret;
}
//２つの円の共通部分の面積
//参考: https://tjkendev.github.io/procon-library/python/geometry/circles_intersection_area.html
//verify: https://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=6005736#1
DD Area(const Circle &c1,const Circle &c2){
    DD cd=abs(c1.p-c2.p);
    if(LE(c1.r+c2.r,cd)) return 0; //円が離れている

    if(LE(cd,abs(c1.r-c2.r))) //片方の円が他方を包んでいる
        return min(c1.r,c2.r)*min(c1.r,c2.r)*PI;

    DD theta1=acosl(cosine_formula(c1.r,cd,c2.r));
    DD theta2=acosl(cosine_formula(c2.r,cd,c1.r));

    return c1.r*c1.r*theta1+c2.r*c2.r*theta2-c1.r*cd*sin(theta1);
}


////////////////////////////
// 三角形
////////////////////////////

//ヘロンの公式　三角形の面積を返す
//三角形が成立するか(平行ではないか)を忘れずに
DD Heron(const DD ad,const DD bd,const DD cd){
    DD s=(ad+bd+cd)/2;
    return sqrt(s*(s-ad)*(s-bd)*(s-cd));
}
//三角形の外接円
//isParallel()を使って三角形が成立するか(平行ではないか)を忘れずに
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_C
Circle CircumscribedCircle(const Point &a,const Point &b,const Point &c){
    Point bc=(b+c)/(DD)2.0;
    Line aa(bc,bc+rotate(c-b,PI/2));
    Point ab=(a+b)/(DD)2.0;
    Line cc(ab,ab+rotate(b-a,PI/2));
    Point p=crossPoint(aa,cc);
    return Circle(p,abs(a-p));
}
//三角形の内接円
//isParallel()を使って三角形が成立するか(平行ではないか)を忘れずに
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_B
Circle InCircle(const Point &a,const Point &b,const Point &c){
    Line aa(a,a+polar((DD)1.0,(arg(b-a)+arg(c-a))/(DD)2.0));
    Line bb(b,b+polar((DD)1.0,(arg(a-b)+arg(c-b))/(DD)2.0));
    Point p=crossPoint(aa,bb);
    return Circle(p,DistPL(p,Line(a,b)));
}

////////////////////////////
// 多角形
////////////////////////////

//点pが多角形gに対してどの位置にあるか
//中:2 辺上:1 外:0
//凸多角形である必要ない
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
int contains(const Point &p,const vector<Point> &g){
    int n=(int)g.size();
    int x=false;
    for(int i=0;i<n;i++){
        Point a=g[i]-p,b=g[(i+1)%n]-p;
        if(EQ(cross(a,b),0) && dot(a,b)<EPS) return 1;
        if(a.Y>b.Y) swap(a,b);
        if(a.Y<EPS && EPS<b.Y && cross(a,b)>EPS) x=!x;
    }
    return (x?2:0);
}
//凸性判定
//多角形gは凸か？
//gは反時計回りでも時計回りでもいい
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
bool isConvex(const vector<Point> &g){
    int n=(int)g.size();
    if(n<=3) return true;
    int flag=0;
    int t;
    for(int i=0;i<n;i++){
        Point a(g[(i+1)%n]-g[i]),b(g[(i+2)%n]-g[i]);
        if(cross(a,b)>EPS) t=1;
        else if(cross(a,b)<-EPS) t=-1;
        else continue;
        if(flag==-t) return false;
        flag=t;
    }
    return true;
}

//凸包　アンドリューのアルゴリズム
//O(NlogN)
//反時計回りの多角形を返す
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
vector<Point> ConvexHull(vector<Point> s,const bool on_edge){
    int j;
    if(on_edge) j=-1;
    else j=1;
    int sz=(int)s.size();
    if(sz<3) return s;
    sort(s.begin(),s.end(),yx_sort);

    int n=0;
    vector<Point> res(2*sz);
    for(int i=0;i<sz;i++){
        while(n>=2 && cross(res[n-1]-res[n-2],s[i]-res[n-2])<EPS*j){
            n--;
        }
        res[n]=s[i];
        n++;
    }
    int t=n+1;
    for(int i=sz-2;i>=0;i--){
        while(n>=t && cross(res[n-1]-res[n-2],s[i]-res[n-2])<EPS*j){
            n--;
        }
        res[n]=s[i];
        n++;
    }
    res.resize(n-1);
    return res;
}



int N,T,R;
vector<string> Name(110);
vector<vector<int>> VT(110),VX(110),VY(110);
using pdi=pair<DD,int>;
priority_queue<pdi,vector<pdi>,greater<pdi>> que;

Point Place(int id,DD t){
    Point now(VX[id][0],VY[id][0]);
    for(int i=1;i<VX[id].size();i++){
        Point p(VX[id][i],VY[id][i]);
        if(t<=VT[id][i]){
            now+=p*(t-VT[id][i-1]);
            return now;
        }else{
            now+=p*DD(VT[id][i]-VT[id][i-1]);
        }
    }
    return now;
}

void FFF(int ID,DD now){
    Circle C(Point(0,0),R);
    //C.debug();
    Point p1(VX[ID][0],VY[ID][0]);

    for(int ti1=0;ti1+1<VT[ID].size();ti1++){
        int t1=VT[ID][ti1];
        int nt1=VT[ID][ti1+1];
        for(int id=0;id<N;id++){
            if(id==ID) continue;
            for(int ti2=0;ti2+1<VT[id].size();ti2++){
                int t2=VT[id][ti2];
                int nt2=VT[id][ti2+1];
                int start=max(t1,t2);
                int end=min(nt1,nt2);
                if(start>end) continue;

                Segment S(Place(ID,start)-Place(id,start),Place(ID,end)-Place(id,end));
                auto sc=crossPointSC(S,C);
                for(auto p:sc){
                    auto sp=Place(ID,start)-Place(id,start);
                    Point d(VX[ID][ti1+1]-VX[id][ti2+1] , VY[ID][ti1+1]-VY[id][ti2+1]);
                    DD t=abs(p-sp)/abs(d);
                    if(GE(start+t,now)) que.emplace(start+t,id);
                }
                if(LE(abs(Place(ID,start)-Place(id,start)),R) and LE(abs(Place(ID,end)-Place(id,end)),R) and LE(now,end)){
                    if(Name[id]=="baz"){
                        cerr<<abs(Place(ID,start)-Place(id,start))<<endl;
                        cout<<-1<<endl;
                    }
                    que.emplace(max<DD>(now,start),id);
                }
            }
        }
    }
}


void solve(){
while(true){
    cin>>N>>T>>R;
    if(N==0) return;

    for(int i=0;i<N;i++){
        cin>>Name[i];
        VT[i].clear();
        VX[i].clear();
        VY[i].clear();
        for(int j=0;;j++){
            int t,x,y;
            cin>>t>>x>>y;
            VT[i].push_back(t);
            VX[i].push_back(x);
            VY[i].push_back(y);
            if(t==T) break;
        }
    }
    /*for(int i=0;i<N;i++){
        for(int t=0;t+1<VT[i].size();t++){
            string s;s+=char('a'+i);
            debug(Place(i,VT[i][t]),s);
            Segment seg(Place(i,VT[i][t]),Place(i,VT[i][t+1]));
            debug(Place(i,VT[i][t+1]),s);
            seg.debug();
        }
        cout<<endl;
    }*/
    vector<bool> used(N,false);
    vector<string> ans;
    que.emplace(0,0);
    
    while(que.size()){
        auto x=que.top(); que.pop();
        if(used[x.second]) continue;
        used[x.second]=true;
        ans.push_back(Name[x.second]);
        FFF(x.second,x.first);
    }

    vsort(ans);
    for(auto s:ans) cout<<s<<endl;
}
}

int main(){
    bin101();
    int T=1;
    //cin>>T;
    while(T--) solve();
}
accuracy: 1
time_ms: 310
memory_kb: 3556
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=105,INF=1<<30;

//幾何ライブラリ
// define double ll をするときは Point の < と == も書き換えよう！

const double eps=1e-8;
const double pi=acos((double)-1.0L);
#define equals(a,b) (fabs((a)-(b))<eps)

double torad(double deg) {return (double)(deg)*pi/180.0;}
double todeg(double ang) {return ang*180.0/pi;}

class Point{
public:
    double x,y;
    
    Point(double x=0,double y=0):x(x),y(y){}
    
    Point operator + (Point p){return Point(x+p.x,y+p.y);}
    Point operator - (Point p){return Point(x-p.x,y-p.y);}
    Point operator * (double a){return Point(a*x,a*y);}
    Point operator / (double a){return Point(x/a,y/a);}
    
    double abs(){return sqrt(norm());}
    double norm(){return x*x+y*y;}
    
    bool operator < (const Point &p)const{
        return x+eps<p.x||(equals(x,p.x)&&y+eps<p.y);
    }
    
    bool operator == (const Point &p)const{
        return fabs(x-p.x)<eps/100000&&fabs(y-p.y)<eps/100000;
    }
};

typedef Point Vector;

double norm(Vector a){
    return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
    return sqrt(norm(a));
}

double dot(Vector a,Vector b){
    return a.x*b.x+a.y*b.y;
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

struct Segment{
    Point p1,p2;
};

bool isOrthogonal(Vector a,Vector b){
    return equals(dot(a,b),0.0);
}

bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
    return isOrthogonal(a1-a2,b1-b2);
}

bool isOrthogonal(Segment s1,Segment s2){
    return equals(dot(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

bool isParallel(Vector a,Vector b){
    return equals(cross(a,b),0.0);
}

bool isParallel(Point a1,Point a2,Point b1,Point b2){
    return isParallel(a1-a2,b1-b2);
}

bool isParallel(Segment s1,Segment s2){
    return equals(cross(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

Point project(Segment s,Point p){
    Vector base=s.p2-s.p1;
    double r=dot(p-s.p1,base)/norm(base);
    return s.p1+base*r;
}

Point reflect(Segment s,Point p){
    return p+(project(s,p)-p)*2.0;
}

Point turn(Point p,Point c,double pi){
    double q=atan2(p.y-c.y,p.x-c.x);
    q+=pi;
    p=c+Point{cos(q)*abs(p-c),sin(q)*abs(p-c)};
    
    return p;
}
//pをcを中心としてpi回転させる(1周で2π)
//p=cのときnan

//p0,p1,p2の順に見たときどうなるか？

static const int counter_clockwise=1;
static const int clockwise=-1;
static const int online_back=2;
static const int online_front=-2;
static const int on_segment=0;

int ccw(Point p0,Point p1,Point p2){
    Vector a=p1-p0;
    Vector b=p2-p0;
    
    if(cross(a,b)>eps) return counter_clockwise;
    if(cross(a,b)<-eps) return clockwise;
    if(dot(a,b)<-eps) return online_back;
    if(a.norm()<b.norm()) return online_front;
    
    return on_segment;
}

bool intersect(Point p1,Point p2,Point p3,Point p4){
    return(ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0&&ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}

bool intersect(Segment s1,Segment s2){
    return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

bool overlap(Segment s1,Segment s2){
    int a=ccw(s1.p1,s1.p2,s2.p1),b=ccw(s1.p1,s1.p2,s2.p2);
    if(a&1||b&1) return 0;
    if(a==2){
        if(b==-2||(b==0&&!(s2.p2==s1.p1))) return 1;
        else return 0;
    }
    if(a==-2){
        if(b==2||(b==0&&!(s2.p2==s1.p2))) return 1;
        else return 0;
    }
    if(a==0){
        if(s1.p1==s2.p1){
            if(b!=2) return 1;
            else return 0;
        }
        else if(s1.p2==s2.p1){
            if(b!=-2) return 1;
            else return 0;
        }
        else return 1;
    }
    return 0;
}
//s1とs2の共通の線分(長さ0より大きい)があるかどうか

typedef Segment Line;

double getDistance(Point a,Point b){
    return abs(a-b);
}

double getDistanceLP(Line l,Point p){
    return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s,Point p){
    if(dot(s.p2-s.p1,p-s.p1)<0.0) return abs(p-s.p1);
    if(dot(s.p1-s.p2,p-s.p2)<0.0) return abs(p-s.p2);
    return getDistanceLP(s,p);
}

double getDistance(Segment s1,Segment s2){
    if(intersect(s1,s2)) return 0.0;
    return min({getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2),getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)});
}

Point getCrossPointS(Segment s1,Segment s2){
    //if(ccw(s1.p1,s1.p2,s2.p1)==0&&ccw(s1.p1,s1.p2,s2.p2)==0) return s1.p1;
    Vector base=s2.p2-s2.p1;
    double d1=abs(cross(base,s1.p1-s2.p1));
    double d2=abs(cross(base,s1.p2-s2.p1));
    double t=d1/(d1+d2);
    return s1.p1+(s1.p2-s1.p1)*t;
}//同じ時壊れます

Point getCrossPointL(Line l1,Line l2){
    //if(ccw(s1.p1,s1.p2,s2.p1)==0&&ccw(s1.p1,s1.p2,s2.p2)==0) return s1.p1;
    
    Vector v1=l1.p2-l1.p1,v2=l2.p2-l2.p1;
    
    return l1.p1+v1*cross(v2,l2.p1-l1.p1)/cross(v2,v1);
}

Segment ParallelSegment(Segment s,double d){
    Vector v={-(s.p2-s.p1).y,(s.p2-s.p1).x};
    v=v/abs(v);
    
    s.p1=s.p1+v*d;
    s.p2=s.p2+v*d;
    
    return s;
}

Point naisin(Point p1,Point p2,Point p3){
    if(p1==p2&&p2==p3&&p3==p1) return p1;
    
    return (p1*abs(p2-p3)+p2*abs(p1-p3)+p3*abs(p1-p2))/(abs(p2-p3)+abs(p1-p3)+abs(p1-p2));
}

Point naisin(Line l1,Line l2,Line l3){
    //平行でない前提
    
    Point p1=getCrossPointL(l1,l2),p2=getCrossPointL(l1,l3),p3=getCrossPointL(l2,l3);
    return naisin(p1,p2,p3);
}

//ネットの適当を書いたのであってるか全く知りません→あってそう

class Circle{
public:
    Point c;
    double r;
    Circle(Point c=Point(),double r=0.0):c(c),r(r){}
};

Point CircleCenter(Point a,Point b,Point c){
    Point u=a-b,v=a-c;
    double m1=(norm(a)-norm(b))/2.0,m2=(norm(a)-norm(c))/2.0;
    
    Point res;
    if(cross(u,v)==0.0){
        res.x=1e9;
        res.y=1e9;
        
        return res;
    }
    res.x=(m1*v.y-m2*u.y)/cross(u,v);
    res.y=(m1*v.x-m2*u.x)/cross(v,u);
    
    return res;
}
//3点を通る円の中心を返す

//交わる 0
// c1がc2のinside 1
// c1がc2のoutside 2
// 交わらない 3

int not_intersect(Circle c1,Circle c2){
    double d=getDistance(c1.c,c2.c);
    double r1=c1.r,r2=c2.r;
    if(r1<r2){
        if(d<(r2-r1)) return 1;
    }
    if(r1>r2){
        if(d<(r1-r2)) return 2;
    }
    if(d<=r1+r2) return 0;
    else return 3;
}

pair<Point,Point> segCrossPpoints(Circle c,Line l){
    //assert(intersect(c,l));
    Vector pr=project(l,c.c);
    Vector e=(l.p2-l.p1)/abs(l.p2-l.p1);
    double base=sqrt(c.r*c.r-norm(pr-c.c));
    return make_pair(pr+e*base,pr-e*base);
}

double arg(Vector p){return atan2(p.y,p.x);}
Vector polar(double a,double r){return Point(cos(r)*a,sin(r)*a);}

//inside(outside)

pair<Point,Point> getCrossPoints(Circle c1,Circle c2){
    //assert(intersect(c1,c2));
    double d=abs(c1.c-c2.c);
    double a=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    double t=arg(c2.c-c1.c);
    return make_pair(c1.c+polar(c1.r,t+a),c1.c+polar(c1.r,t-a));
}

vector<Line> Commontangent(Circle c1,Circle c2){
    vector<Line> res;
    Point p=c2.c-c1.c;
    
    if(abs(p)>=(c1.r+c2.r)){
        Point a,b;
        a.x=c1.r*(p.x*(c1.r+c2.r)+p.y*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        a.y=c1.r*(p.y*(c1.r+c2.r)-p.x*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        
        b.x=c1.r*(p.x*(c1.r+c2.r)-p.y*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        b.y=c1.r*(p.y*(c1.r+c2.r)+p.x*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        
        res.push_back(Line{a+c1.c,a+c1.c+Point{-a.y,a.x}});
        if(!(a==b)){
            res.push_back(Line{b+c1.c,b+c1.c+Point{-b.y,b.x}});
        }
    }
    
    if(abs(p)>=abs(c1.r-c2.r)){
        Point a,b;
        a.x=c1.r*(p.x*(c1.r-c2.r)+p.y*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        a.y=c1.r*(p.y*(c1.r-c2.r)-p.x*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        
        b.x=c1.r*(p.x*(c1.r-c2.r)-p.y*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        b.y=c1.r*(p.y*(c1.r-c2.r)+p.x*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        
        res.push_back(Line{a+c1.c,a+c1.c+Point{-a.y,a.x}});
        if(!(a==b)){
            res.push_back(Line{b+c1.c,b+c1.c+Point{-b.y,b.x}});
        }
    }
    
    return res;
}

typedef vector<Point> Polygon;

/*
 IN 2
 ON 1
 OUT 0
 */

int contains(Polygon g,Point p){
    int n=int(g.size());
    bool x=false;
    for(int i=0;i<n;i++){
        Point a=g[i]-p,b=g[(i+1)%n]-p;
        if(a.y>b.y) swap(a,b);
        if(a.y<eps&&0<b.y&&cross(a,b)<0) x=!x;
        if(abs(cross(a,b))<eps&&dot(a,b)<eps) return 1;
    }
    return (x?2:0);
}

Polygon andrewScan(Polygon s,bool ok){
    Polygon u,l;
    sort(all(s));
    
    if(int(s.size())<3) return s;
    int n=int(s.size());
    
    u.push_back(s[0]);
    u.push_back(s[1]);
    
    l.push_back(s[n-1]);
    l.push_back(s[n-2]);
    
    if(ok){
        for(int i=2;i<n;i++){
            for(int j=int(u.size());j>=2&&ccw(u[j-2],u[j-1],s[i])==counter_clockwise;j--){
                u.pop_back();
            }
            u.push_back(s[i]);
        }
        
        for(int i=int(s.size())-3;i>=0;i--){
            for(int j=int(l.size());j>=2&&ccw(l[j-2],l[j-1],s[i])==counter_clockwise;j--){
                l.pop_back();
            }
            l.push_back(s[i]);
        }
    }
    
    if(!ok){
        for(int i=2;i<n;i++){
            for(int j=int(u.size());j>=2&&ccw(u[j-2],u[j-1],s[i])!=clockwise;j--){
                u.pop_back();
            }
            u.push_back(s[i]);
        }
        
        for(int i=int(s.size())-3;i>=0;i--){
            for(int j=int(l.size());j>=2&&ccw(l[j-2],l[j-1],s[i])!=clockwise;j--){
                l.pop_back();
            }
            l.push_back(s[i]);
        }
    }
    
    reverse(all(l));
    
    for(int i=int(u.size())-2;i>=1;i--) l.push_back(u[i]);
    
    return l;
}//ok==1なら辺の上も含める

Polygon convex_cut(const Polygon& P, const Line& l) {
    Polygon Q;
    for(int i=0;i<si(P);i++){
        Point A=P[i],B=P[(i+1)%si(P)];
        if(ccw(l.p1,l.p2,A)!=-1)Q.push_back(A);
        if(ccw(l.p1,l.p2,A)*ccw(l.p1,l.p2,B)<0) Q.push_back(getCrossPointL(Line{A,B},l));
    }
    return Q;
}

double area(Point a,Point b,Point c){
    b=b-a;
    c=c-a;
    return abs(b.x*c.y-b.y*c.x)/2.0;
}

double area(Polygon &P){
    if(si(P)==0) return 0.0;
    double res=0;
    Point c={0.0,0.0};
    for(int i=0;i<si(P);i++){
        c=c+P[i];
    }
    c=c/si(P);
    
    for(int i=0;i<si(P);i++){
        res+=area(c,P[i],P[(i+1)%si(P)]);
    }
    
    return res;
}

ll gcd(ll a,ll b){
    if(b==0) return a;
    return gcd(b,a%b);
}

pair<Point,Vector> perpendicular_bisector(Point a,Point b){
    Point c=(a+b)/2;
    Vector v=b-c;
    swap(v.x,v.y);
    v.x*=-1;
    
    Point p=c;
    if(v.x==0){
        v.y=1;
        p.y=0;
    }
    else if(v.y==0){
        v.x=1;
        p.x=0;
    }
    else{
        if(v.x<0){
            v.x*=-1;
            v.y*=-1;
        }
        ll g=gcd(abs(ll(v.x)),abs(ll(v.y)));
        v.x/=g;
        v.y/=g;
        if(p.x>=0){
            ll d=p.x/v.x;
            p=p-v*d;
        }else{
            ll d=abs(p.x)/v.x;
            p=p+v*d;
            
            if(p.x<0){
                p=p+v;
            }
        }
    }
    
    return mp(p,v);
}
//2倍するなりして整数にしておくこと

bool kousa[MAX][MAX];

int main() {
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    while(1){
        int N,T,RR;cin>>N>>T>>RR;
        if(N==0) break;
        memset(kousa,0,sizeof(kousa));
        vector<string> S(N);
        vector<vector<Vector>> V(N,vector<Vector>(T));
        vector<Point> P(N);
        for(int i=0;i<N;i++){
            cin>>S[i];
            double lt=0;
            while(1){
                double t,x,y;cin>>t>>x>>y;
                for(int j=lt;j<t;j++){
                    V[i][j]={x,y};
                }
                if(t==0) P[i]={x,y};
                lt=t;
                if(lt==T) break;
            }
        }
        vector<int> on(N);
        on[0]=true;
        
        vector<pair<double,pair<int,int>>> Q;
        for(int i=0;i<N;i++){
            for(int j=i+1;j<N;j++){
                Point a=P[i],b=P[j];
                for(int k=0;k<T;k++){
                    double l=k,r=k+1,mi=INF;
                    for(int q=0;q<30;q++){
                        double m1=(l+l+r)/3,m2=(l+r+r)/3;
                        Point a1=a+V[i][k]*(m1-k),b1=b+V[j][k]*(m1-k);
                        Point a2=a+V[i][k]*(m2-k),b2=b+V[j][k]*(m2-k);
                        double d1=getDistance(a1,b1),d2=getDistance(a2,b2);
                        if(d1<d2){
                            r=m2;
                            chmin(mi,d1);
                        }else{
                            l=m1;
                            chmin(mi,d2);
                        }
                    }
                    
                    //cout<<i<<" "<<j<<" "<<k<<" "<<mi<<" "<<l<<" "<<r<<endl;
                    
                    if(mi<=RR+eps){
                        double L=k,M=(l+r)/2,R=k+1;
                        for(int q=0;q<30;q++){
                            double m=(L+M)/2;
                            Point aa=a+V[i][k]*(m-k),bb=b+V[j][k]*(m-k);
                            if(getDistance(aa,bb)<=RR+eps) M=m;
                            else L=m;
                        }
                        double saveM=M;
                        M=(l+r)/2;
                        for(int q=0;q<30;q++){
                            double m=(M+R)/2;
                            Point aa=a+V[i][k]*(m-k),bb=b+V[j][k]*(m-k);
                            //cout<<i<<" "<<j<<" "<<m<<" "<<getDistance(aa,bb)<<endl;
                            if(getDistance(aa,bb)<=RR+eps) M=m;
                            else R=m;
                        }
                        if(L==k){
                            Q.push_back(mp(L+eps,mp(i,j)));
                        }else{
                            Q.push_back(mp(saveM,mp(i,j)));
                        }
                        
                        if(R==k+1){
                            Q.push_back(mp(R-eps,mp(i,j)));
                        }else{
                            Q.push_back(mp(M,mp(i,j)));
                        }
                        
                        //cout<<i<<" "<<j<<" "<<saveM<<" "<<M<<endl;
                    }
                    
                    
                    a=a+V[i][k];
                    b=b+V[j][k];
                }
            }
        }
        
        sort(all(Q));
        
        for(auto q:Q){
            int a=q.se.fi,b=q.se.se;
            
            kousa[a][b]^=1;
            kousa[b][a]^=1;
            
            if(on[a]+on[b]==1){
                for(int t=0;t<N;t++){
                    for(int i=0;i<N;i++){
                        for(int j=0;j<N;j++){
                            if(on[i]&&kousa[i][j]) on[j]=true;
                        }
                    }
                }
            }
        }
        
        vector<string> ans;
        for(int i=0;i<N;i++){
            if(on[i]) ans.push_back(S[i]);
        }
        sort(all(ans));
        for(auto s:ans) cout<<s<<"\n";
    }
}
accuracy: 1
time_ms: 1280
memory_kb: 4868
final_rank: 18

code_snippet: /*	author:  Kite_kuma
	created: 2021.08.19 15:21:48 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

#pragma region geometry

using Real = long double;
using R = Real;
using Point = std::complex<Real>;
using Vec = Point;
const Real EPS = 1e-10, PI = acos(-1);

inline bool eq(const Real &a, const Real &b) { return fabs(b - a) < EPS; }
inline bool eq(const Point &a, const Point &b) { return fabs(b - a) < EPS; }
/*
	-1: a < b
	0 : a == b
	1 : a > b
*/
inline int compare(const Real &a, const Real &b) { return eq(a, b) ? 0 : a < b ? -1 : 1; }
inline int sign(const Real &a) { return fabs(a) < EPS ? 0 : a < 0 ? -1 : 1; }

namespace std {
const Point operator*(const Point &p, const Real &d) { return Point(real(p) * d, imag(p) * d); }
}  // namespace std

std::istream &operator>>(std::istream &is, Point &p) {
	Real a, b;
	is >> a >> b;
	p = Point(a, b);
	return is;
}
std::ostream &operator<<(std::ostream &os, Point &p) { return os << std::fixed << std::setprecision(10) << p.real() << " " << p.imag(); }

// rotate point 'p' for counter clockwise direction
const Point rotate(const Real &theta, const Point &p) {
	return Point(cos(theta) * p.real() - sin(theta) * p.imag(), sin(theta) * p.real() + cos(theta) * p.imag());
}

const Real radian_to_degree(const Real &r) { return (r * 180.0 / PI); }

const Real degree_to_radian(const Real &d) { return (d * PI / 180.0); }

// get angle a-b-c (<pi)
const Real get_angle(const Point &a, const Point &b, const Point &c) {
	const Point v(a - b), w(c - b);
	Real theta = fabs(atan2(w.imag(), w.real()) - atan2(v.imag(), v.real()));
	return std::min(theta, 2 * PI - theta);
}

namespace std {
bool operator<(const Point &a, const Point &b) { return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag(); }
}  // namespace std

struct Line {
	Point a, b;

	Line() = default;

	Line(Point a, Point b) : a(a), b(b) {}

	Line(Real A, Real B, Real C)  // Ax + By = C
	{
		if(eq(A, 0))
			a = Point(0, C / B), b = Point(1, C / B);
		else if(eq(B, 0))
			b = Point(C / A, 0), b = Point(C / A, 1);
		else
			a = Point(0, C / B), b = Point(C / A, 0);
	}

	friend std::ostream &operator<<(std::ostream &os, Line &p) { return os << p.a << " -- " << p.b; }

	friend std::istream &operator>>(std::istream &is, Line &a) { return is >> a.a >> a.b; }
};

struct Segment : Line {
	Segment() = default;

	Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
	Point p;
	Real r;

	Circle() = default;

	Circle(Point p, Real r) : p(p), r(r) {}
};

using Points = std::vector<Point>;
using Polygon = std::vector<Point>;
using Segments = std::vector<Segment>;
using Lines = std::vector<Line>;
using Circles = std::vector<Circle>;

const Real cross(const Point &a, const Point &b) { return real(a) * imag(b) - imag(a) * real(b); }
const Real dot(const Point &a, const Point &b) { return real(a) * real(b) + imag(a) * imag(b); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
const int ccw(const Point &a, Point b, Point c) {
	b = b - a, c = c - a;
	if(cross(b, c) > EPS) return +1;		// "COUNTER_CLOCKWISE"
	if(cross(b, c) < -EPS) return -1;		// "CLOCKWISE"
	if(dot(b, c) < -EPS) return +2;			// "ONLINE_BACK"
	if(norm(b) + EPS < norm(c)) return -2;	// "ONLINE_FRONT"
	return 0;								// "ON_SEGMENT"
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool parallel(const Line &a, const Line &b) { return eq(cross(a.b - a.a, b.b - b.a), 0.0); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool orthogonal(const Line &a, const Line &b) { return eq(dot(a.a - a.b, b.a - b.b), 0.0); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line &l, const Point &p) {
	double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p) {
	double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + (l.a - l.b) * t;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line &l, const Point &p) { return projection(l, p) * 2.0 - p; }

int intersect(const Line &l, const Point &p) { return int(abs(ccw(l.a, l.b, p)) != 1); }

int intersect(const Line &l, const Line &m) {
	if(intersect(l, m.a) && intersect(l, m.b)) return -1;
	return int(abs(cross(l.b - l.a, m.b - m.a)) > EPS);
}

int intersect(const Segment &s, const Point &p) { return int(ccw(s.a, s.b, p) == 0); }

int intersect(const Line &l, const Segment &s) {
	if(intersect(l, s.a) && intersect(l, s.b)) return -1;
	return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

Real distance(const Line &l, const Point &p);

int intersect(const Circle &c, const Line &l) {
	Real d = c.r - distance(l, c.p);
	return fabs(d) < EPS ? 1 : d > 0. ? 2 : 0;
}

int intersect(const Circle &c, const Point &p) { return int(abs(abs(p - c.p) - c.r) < EPS); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
int intersect(const Segment &s, const Segment &t) {
	if(eq(s.a, s.b)) return intersect(t, s.a);
	if(intersect(Line(s), t.a) && intersect(Line(s), t.b) &&
	   std::max(std::min(s.a, s.b), std::min(t.a, t.b)) < std::min(std::max(s.a, s.b), std::max(t.a, t.b)))
		return -1;
	return int(ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0);
}

int intersect(const Circle &c, const Segment &l) {
	const Point h = projection(l, c.p);
	if(norm(h - c.p) - c.r * c.r > EPS) return 0;
	auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b);
	if(compare(d1, c.r) == -1 && compare(d2, c.r) == -1) return 0;
	if(d1 < c.r - EPS && d2 > c.r - EPS || d1 > c.r - EPS && d2 < c.r - EPS) return 1;
	return dot(l.a - h, l.b - h) < 0 ? 2 : 0;
}

Real distance(const Point &a, const Point &b);

int number_of_common_tangents(const Circle &c1, const Circle &c2) {
	Real r1 = std::min(c1.r, c2.r), r2 = std::max(c1.r, c2.r), d = distance(c1.p, c2.p);
	int com = compare(r1 + r2, d);
	return com == 1 ? compare(d + r1, r2) + 1 : 3 - com;
	// if(c1.r < c2.r) swap(c1, c2);
	// Real d = abs(c1.p - c2.p);
	// if(compare(c1.r + c2.r, d) == -1) return 4;
	// if(eq(c1.r + c2.r, d)) return 3;
	// if(compare(c1.r - c2.r, d) == -1) return 2;
	// return int(eq(c1.r - c2.r, d));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=jp
int intersect(const Circle &c1, const Circle &c2) { return 2 - abs(2 - number_of_common_tangents(c1, c2)); }

Real distance(const Point &a, const Point &b) { return abs(a - b); }

Real distance(const Line &l, const Point &p) { return abs(p - projection(l, p)); }

Real distance(const Line &l, const Line &m) { return intersect(l, m) ? 0 : distance(l, m.a); }

Real distance(const Segment &s, const Point &p) {
	Point r = projection(s, p);
	return intersect(s, r) ? distance(r, p) : std::min(abs(s.a - p), abs(s.b - p));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance(const Segment &a, const Segment &b) {
	if(intersect(a, b)) return 0;
	return std::min({distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

Real distance(const Line &l, const Segment &s) {
	if(intersect(l, s)) return 0;
	return std::min(distance(l, s.a), distance(l, s.b));
}

Point crosspoint(const Line &l, const Line &m) {
	Real A = cross(l.b - l.a, m.b - m.a);
	Real B = cross(l.b - l.a, l.b - m.a);
	if(eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
	return m.a + (m.b - m.a) * B / A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C
Point crosspoint(const Segment &l, const Segment &m) { return crosspoint(Line(l), Line(m)); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
std::pair<Point, Point> crosspoint(const Circle &c, const Line l) {
	Point pr = projection(l, c.p);
	if(eq(distance(l, c.p), c.r)) return {pr, pr};
	Vec v = (l.b - l.a) / abs(l.b - l.a) * sqrt(c.r * c.r - norm(pr - c.p));
	return make_pair(pr - v, pr + v);
	// Vec e = (l.b - l.a) / abs(l.b - l.a);
	// double base = sqrt(c.r * c.r - norm(pr - c.p));
	// return {pr - e * base, pr + e * base};
}

std::pair<Point, Point> crosspoint(const Circle &c, const Segment &l) {
	if(intersect(c, l) == 2) return crosspoint(c, Line(l.a, l.b));
	auto ret = crosspoint(c, Line(l.a, l.b));
	if(dot(l.a - ret.first, l.b - ret.first) < EPS)
		ret.second = ret.first;
	else
		ret.first = ret.second;
	return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E
std::pair<Point, Point> crosspoint(const Circle &c1, const Circle &c2) {
	Real d = abs(c1.p - c2.p);
	Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));  // cosine theorem
	Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
	Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
	Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
	return make_pair(p1, p2);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F
// "点 p を通る円 c の接線"の接点2つ
std::pair<Point, Point> tangent(const Circle &c1, const Point &p2) {
	return crosspoint(c1, Circle(p2, sqrt(norm(c1.p - p2) - c1.r * c1.r)));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
// 円 c1, c2 の共通接線
Lines tangent(Circle c1, Circle c2) {
	Lines ret;
	if(c1.r < c2.r) std::swap(c1, c2);
	Real g = norm(c1.p - c2.p);
	if(eq(g, 0)) return ret;
	Vec u = (c2.p - c1.p) / Real(sqrt(g));
	Vec v = rotate(PI * 0.5, u);
	for(int s : {-1, 1}) {
		Real h = (c1.r + s * c2.r) / sqrt(g);
		if(eq(1 - h * h, 0)) {
			ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
		} else if(1 - h * h > 0) {
			Point uu = u * h, vv = v * sqrt(1 - h * h);
			ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
			ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
		}
	}
	return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
bool is_convex(const Polygon &p, bool pi_is_ok = false) {
	int n = p.size();
	if(pi_is_ok) {
		for(int i = 0; i < n; i++)
			if(ccw(p[i], p[(i + 1) % n], p[(i + 2) % n]) == -1) return false;
	} else {
		for(int i = 0; i < n; i++)
			if(ccw(p[i], p[(i + 1) % n], p[(i + 2) % n]) != 1) return false;
	}
	return true;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
Polygon convex_hull(Polygon &p, bool pi_is_ok = false) {
	int n = (int)p.size(), k = 0;
	if(n <= 2) return p;
	sort(p.begin(), p.end());
	Points ch(2 * n);
	if(pi_is_ok) {
		for(int i = 0; i < n; ch[k++] = p[i++])
			while(k >= 2 && ccw(ch[k - 2], ch[k - 1], p[i]) == -1) --k;
		for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--])
			while(k >= t && ccw(ch[k - 2], ch[k - 1], p[i]) == -1) --k;
	} else {
		for(int i = 0; i < n; ch[k++] = p[i++])
			while(k >= 2 && ccw(ch[k - 2], ch[k - 1], p[i]) != 1) --k;
		for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--])
			while(k >= t && ccw(ch[k - 2], ch[k - 1], p[i]) != 1) --k;
	}
	ch.resize(k - 1);
	return ch;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
enum { OUT, ON, IN };
int contains(const Polygon &Q, const Point &p) {
	bool in = false;
	const Real p_y = p.imag();
	for(int i = 0; i < Q.size(); i++) {
		Point a = Q[i], b = Q[(i + 1) % Q.size()];
		if(ccw(a, b, p) == 0) return ON;
		if(a.imag() > b.imag()) swap(a, b);
		if(a.imag() <= p_y && p_y < b.imag() && cross(a - p, b - p) < 0) in = !in;
	}
	return in ? IN : OUT;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033
// 線分の重複除去
void merge_segments(std::vector<Segment> &segs) {
	auto merge_if_able = [](Segment &s1, const Segment &s2) {
		if(abs(cross(s1.b - s1.a, s2.b - s2.a)) > EPS) return false;
		if(ccw(s1.a, s2.a, s1.b) == 1 || ccw(s1.a, s2.a, s1.b) == -1) return false;
		if(ccw(s1.a, s1.b, s2.a) == -2 || ccw(s2.a, s2.b, s1.a) == -2) return false;
		s1 = Segment(min(s1.a, s2.a), max(s1.b, s2.b));
		return true;
	};

	for(int i = 0; i < segs.size(); i++) {
		if(segs[i].b < segs[i].a) swap(segs[i].a, segs[i].b);
	}
	for(int i = 0; i < segs.size(); i++) {
		for(int j = i + 1; j < segs.size(); j++) {
			if(merge_if_able(segs[i], segs[j])) {
				segs[j--] = segs.back(), segs.pop_back();
			}
		}
	}
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033
// 線分アレンジメント
// 任意の2線分の交点を頂点としたグラフを構築する
std::vector<std::vector<int>> segment_arrangement(std::vector<Segment> &segs, std::vector<Point> &ps) {
	std::vector<std::vector<int>> g;
	int N = (int)segs.size();
	for(int i = 0; i < N; i++) {
		ps.emplace_back(segs[i].a);
		ps.emplace_back(segs[i].b);
		for(int j = i + 1; j < N; j++) {
			const Point p1 = segs[i].b - segs[i].a;
			const Point p2 = segs[j].b - segs[j].a;
			if(eq(cross(p1, p2), 0)) continue;	// " == 0" となっていたのを訂正
			if(intersect(segs[i], segs[j])) {
				ps.emplace_back(crosspoint(segs[i], segs[j]));
			}
		}
	}
	sort(begin(ps), end(ps));
	ps.erase(unique(begin(ps), end(ps)), end(ps));	// 誤差?

	int M = (int)ps.size();
	g.resize(M);
	for(int i = 0; i < N; i++) {
		std::vector<int> vec;
		for(int j = 0; j < M; j++) {
			if(intersect(segs[i], ps[j])) {
				vec.emplace_back(j);
			}
		}
		for(int j = 1; j < vec.size(); j++) {
			g[vec[j - 1]].push_back(vec[j]);
			g[vec[j]].push_back(vec[j - 1]);
		}
	}
	return (g);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C
// 凸多角形の切断
// 直線 l.a-l.b で切断しその左側にできる凸多角形を返す
Polygon convex_cut(const Polygon &U, Line l) {
	Polygon ret;
	for(int i = 0; i < U.size(); i++) {
		Point now = U[i], nxt = U[(i + 1) % U.size()];
		if(ccw(l.a, l.b, now) != -1) ret.push_back(now);
		if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) == -1) ret.push_back(crosspoint(Line(now, nxt), l));
	}
	return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A
// 多角形の面積
Real area(const Polygon &p) {
	Real A = 0;
	for(int i = 0; i < p.size(); ++i) {
		A += cross(p[i], p[(i + 1) % p.size()]);
	}
	return A * 0.5;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_H
// 円と多角形の共通部分の面積
Real area(const Polygon &p, const Circle &c) {
	if(p.size() < 3) return 0.0;
	auto cross_area = [&c](auto cross_area, const Point &a, const Point &b) -> Real {
		Point va = c.p - a, vb = c.p - b;
		Real f = cross(va, vb), ret = 0.0;
		if(eq(f, 0.0)) return ret;
		if(std::max(abs(va), abs(vb)) < c.r + EPS) return f;
		if(distance(Segment(a, b), c.p) > c.r - EPS) return c.r * c.r * arg(vb * conj(va));
		auto u = crosspoint(c, Segment(a, b));
		std::vector<Point> tot{a, u.first, u.second, b};
		for(int i = 0; i + 1 < tot.size(); i++) ret += cross_area(cross_area, tot[i], tot[i + 1]);
		return ret;
	};
	Real A = 0;
	for(int i = 0; i < p.size(); i++) {
		A += cross_area(cross_area, p[i], p[(i + 1) % p.size()]);
	}
	return A * 0.5;
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/all/CGL_7_I
Real area(const Circle &c1, const Circle &c2) {
	Real d = abs(c1.p - c2.p);
	if(c1.r + c2.r <= d + EPS) return 0.;
	if(abs(c1.r - c2.r) + EPS >= d) return pow(std::min(c1.r, c2.r), 2.) * PI;
	Real radius_diff = c1.r * c1.r - c2.r * c2.r;
	Real cosine_alpha = (d * d + radius_diff) / (2 * d * c1.r);
	Real cosine_beta = (d * d - radius_diff) / (2 * d * c2.r);
	return c1.r * c1.r * (acos(cosine_alpha) - cosine_alpha * sqrt(1 - cosine_alpha * cosine_alpha)) +
		   c2.r * c2.r * (acos(cosine_beta) - cosine_beta * sqrt(1 - cosine_beta * cosine_beta));
}


#pragma endregion

void solve() {
	int n, time_end, radius;
	cin >> n >> time_end >> radius;

	if(n == 0) exit(0);

	V<string> nicknames;

	V<Points> place(n, Points(time_end + 1));

	rep(id_robot, n) {
		string nk;
		cin >> nk;
		nicknames.push_back(nk);

		int now = 0;
		int x, y;

		while(now < time_end) {
			int t, vx, vy;
			cin >> t >> vx >> vy;

			if(t == 0) {
				x = vx;
				y = vy;
				place[id_robot][0] = Point(x, y);
			} else {
				while(now < t) {
					x += vx;
					y += vy;
					place[id_robot][now + 1] = Point(x, y);
					now++;
				}
			}
		}
	}

	auto reachable = [&](const Point &p) { return compare(distance(p, Point(0, 0)), radius) <= 0; };

	V<tuple<R, int, int>> events;

	rep(i, n) rep(j, i + 1, n) {
		rep(t, time_end) {
			Point a, b;
			a = place[j][t] - place[i][t];
			b = place[j][t + 1] - place[i][t + 1];

			R beg, end;
			Segment seg(a, b);
			Circle c(Point(0, 0), radius);

			if(reachable(a)) {
				beg = t;
				if(reachable(b)) {
					end = t + 1;
				} else {
					if(intersect(c, seg)) {
						auto crs = crosspoint(c, seg).first;
						if(ccw(a, b, crs) == 0) {
							end = beg + distance(a, crs) / distance(a, b);
						} else {
							continue;
						}
					} else {
						continue;
					}
				}
			} else {
				if(reachable(b)) {
					end = t + 1;
					if(intersect(c, seg)) {
						auto crs = crosspoint(c, seg).first;
						if(ccw(a, b, crs) == 0) {
							beg = t + distance(a, crs) / distance(a, b);
						} else {
							continue;
						}
					} else
						continue;
				} else {
					if(intersect(c, seg)) {
						auto crs = crosspoint(c, seg);
						beg = t + distance(a, crs.first) / distance(a, b);
						end = t + distance(a, crs.second) / distance(a, b);
						if(beg > end) swap(beg, end);
					} else {
						continue;
					}
				}
			}

			if(isnan(beg) || isnan(end)) continue;
			if(beg > end) swap(beg, end);

			events.emplace_back(beg, i, j);
			events.emplace_back(end, i, j);
		}
	}

	sort(all(events));

	vvi conn(n, vi(n));

	vi know_info(n);
	know_info[0] = 1;

	auto update = [&](int newcomer) {
		know_info[newcomer] = 1;
		queue<int> q;
		q.push(newcomer);
		while(!q.empty()) {
			int now = q.front();
			q.pop();
			rep(i, 1, n) {
				if(!conn[newcomer][i] || know_info[i]) continue;
				know_info[i] = 1;
				q.push(i);
			}
		}
		return;
	};

	for(auto [time, i, j] : events) {
		debug(time, i, j);
		if(know_info[i] == know_info[j]) continue;
		if(know_info[j]) swap(i, j);

		update(j);

		conn[i][j] ^= 1;
	}

	vector<string> ans;
	rep(i, n) {
		if(know_info[i]) {
			ans.push_back(nicknames[i]);
		}
	}

	sort(all(ans));

	vout(ans, 1);
	return;
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	while(1) solve();

	return 0;
}
accuracy: 1
time_ms: 950
memory_kb: 6532
final_rank: 16

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}
typedef complex<ld> Point;
ld dot(Point a, Point b) { return real(conj(a) * b); }
ld cross(Point a, Point b) { return imag(conj(a) * b); }
namespace std {
	bool operator<(const Point& lhs, const Point& rhs) {
		return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag() : lhs.real() < rhs.real();
	}
}
struct Line {
	Point a, b;
};
struct Circle {
	Point p; ld r;
};
int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//counter clockwise
	if (cross(b, c) < -eps)return -1;//clock wise
	if (dot(b, c) < 0)return 2;//c--a--b on line
	if (norm(b) < norm(c))return -2;//a--b--c on line
	return 0; //a--c--b on line
}

//点が線分上に存在するか
bool isis_sp(Line s, Point p) {
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}
//点から直線への垂線の足
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
//線分と点の距離
ld dist_sp(Line s, Point p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(p - r) : min(abs(p - s.a), abs(p - s.b));
}
const int bb = 40;
struct ste {
	ld tim; int a, b; int x;
};
bool operator<(ste a, ste b) {
	if (a.tim != b.tim)return a.tim < b.tim;
	if (a.a != b.a)return a.a < b.a;
	if (a.b != b.b)return a.b < b.b;
	return a.x > b.x;
}

vector<string> als;

int n, T, r;
void solve() {
	vector<string> s(n);
	vector<vector<int>> t(n);
	vector<vector<Point>> loc(n);
	vector<vector<int>> vx(n);
	vector<vector<int>> vy(n);
	rep(i, n) {
		cin >> s[i];
		while (true) {
			int _t, _vx, _vy;
			cin >> _t >> _vx >> _vy;
			t[i].push_back(_t);
			vx[i].push_back(_vx);
			vy[i].push_back(_vy);
			if (_t == T)break;
		}
		loc[i].resize(T + 1);
		loc[i][0]={ (ld)vx[i][0],(ld)vy[i][0] };
		int cur = 1;
		int cx = vx[i][0], cy = vy[i][0];
		for (int j = 1; j <= T; j++) {
			if (j > t[i][cur])cur++;
			cx += vx[i][cur];
			cy += vy[i][cur];
			loc[i][j] = { (ld)cx,(ld)cy };
		}
	}
	Point ori = { (ld)0,(ld)0 };
	vector<ste> vs;
	rep(i, n)Rep(j, i + 1, n) {
		int z = 0;
		if (abs(loc[i][0] - loc[j][0]) <= r) {
			z = 1;
			vs.push_back({ 0,i,j,1 });
		}
		for (int k = 0; k < T; k++) {
			ld lx = real(loc[j][k]) - real(loc[i][k]);
			ld ly = imag(loc[j][k]) - imag(loc[i][k]);
			ld rx = real(loc[j][k + 1]) - real(loc[i][k + 1]);
			ld ry = imag(loc[j][k + 1]) - imag(loc[i][k + 1]);
			ld dx = rx - lx;
			ld dy = ry - ly;
			Point pl = { lx,ly };
			Point pr = { lx + dx,ly + dy };
			Line s = { pl,pr };
			if (z == 0) {
				//cout << "?? " << i << " " << j << " " << k << "\n";
				if (dist_sp(s, ori) <= r) {
					//cout << "?? " << i << " " << j << " " << k << "\n";
					if (abs(pr - ori) <= r) {
						ld le = 0, ri = 1;
						rep(aa, bb) {
							ld m = (le + ri) / 2.0;
							Point pm = { lx + dx * m,ly + dy * m };
							if (abs(pm - ori) <= r) {
								ri = m;
							}
							else {
								le = m;
							}
						}
						vs.push_back({ le+k,i,j,1 });
						z = 1;
					}
					else {
						Point ph = proj(s, ori);
						ld tmid = abs(ph - pl) / abs(pr - pl);
						//assert(0 - eps <= tmid && tmid <= 1 + eps);
						ld le = 0, ri = tmid;
						rep(aa, bb) {
							ld m = (le + ri) / 2.0;
							Point pm = { lx + dx * m,ly + dy * m };
							if (abs(pm - ori) <= r) {
								ri = m;
							}
							else {
								le = m;
							}
						}
						vs.push_back({ le+k,i,j,1 });
						le = tmid, ri = 1;
						rep(aa, bb) {
							ld m = (le + ri) / 2.0;
							Point pm = { lx + dx * m,ly + dy * m };
							if (abs(pm - ori) <= r) {
								le = m;
							}
							else {
								ri = m;
							}
						}
						vs.push_back({ le+k,i,j,0 });
					}
				}
				else {
					//
				}
			}
			else {
				if (abs(pr - ori) <= r) {
					//
				}
				else {
					ld le = 0, ri = 1;
					rep(aa, bb) {
						ld m = (le + ri) / 2.0;
						Point pm = { lx + dx * m,ly + dy * m };
						if (abs(pm - ori) <= r) {
							le = m;
						}
						else {
							ri = m;
						}
					}
					vs.push_back({ le+k,i,j,0 });
					z = 0;
				}
			}
		}
	}
	sort(all(vs));
	vector<set<int>> st(n);
	vector<bool> used(n);
	used[0] = true;
	auto add = [&](int a, int b) {
		st[a].insert(b);
		st[b].insert(a);
		if (used[a] == used[b])return;
		if (used[b])swap(a, b);
		queue<int> q;
		q.push(b);
		used[b] = true;
		while (!q.empty()) {
			int id = q.front(); q.pop();
			for (int to : st[id]) {
				if (!used[to]) {
					used[to] = true;
					q.push(to);
				}
			}
		}
	};
	auto del = [&](int a, int b) {
		st[a].erase(b);
		st[b].erase(a);
	};
	rep(i, vs.size()) {
		int a = vs[i].a, b = vs[i].b, x = vs[i].x;
		//cout << vs[i].tim << " " << a << " " << b << " " << x << "\n";
		if (x)add(a, b);
		else del(a, b);
	}
	vector<string> ss;
	rep(i, n)if (used[i])ss.push_back(s[i]);
	sort(all(ss));
	//cout << "ans is\n";
	//cout << "----------------\n";
	for (string s : ss)als.push_back(s);
	//cout << "----------------\n";
	//cout << ".\n";
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(12);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t;rep(i, t)
	while(cin>>n>>T>>r,n)
	solve();
	for (string s : als)cout << s << "\n";
	return 0;
}
accuracy: 1
time_ms: 1350
memory_kb: 23100
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double EPS = 0.00000001;
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator +(point P){
    return point(x + P.x, y + P.y);
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
  point operator *(double k){
    return point(x * k, y * k);
  }
  point operator /(double k){
    return point(x / k, y / k);
  }
  bool operator < (point P) const{
    return x < P.x || x == P.x && y < P.y;
  }
};
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
double dot(point P, point Q){
  return P.x * Q.x + P.y * Q.y;
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
point projection(point P, line L){
  return L.A + vec(L) * dot(P - L.A, vec(L)) / abs(vec(L)) / abs(vec(L));
}
double point_line_distance(point P, line L){
  return abs(cross(L.A - P, vec(L))) / abs(vec(L));
}
struct circle{
  point C;
  double r;
  circle(point C, double r): C(C), r(r){
  }
};
vector<point> line_circle_intersection(line L, circle C){
  double d = point_line_distance(C.C, L);
  if (d > C.r){
    return vector<point>();
  }
  point P = projection(C.C, L);
  point D = vec(L) / abs(vec(L));
  double m = sqrt(C.r * C.r - d * d);
  vector<point> ans = {P - D * m, P + D * m};
  return ans;
}
int main(){
  while (true){
    int N, T;
    double R;
    cin >> N >> T >> R;
    if (N == 0 && T == 0 && R == 0){
      break;
    }
    vector<string> s(N);
    vector<point> P(N);
    vector<vector<double>> t(N, vector<double>(1));
    vector<vector<point>> v(N);
    for (int i = 0; i < N; i++){
      cin >> s[i];
      cin >> t[i][0] >> P[i].x >> P[i].y;
      while (t[i].back() != T){
        t[i].push_back(0);
        v[i].push_back(point());
        cin >> t[i].back() >> v[i].back().x >> v[i].back().y;
      }
    }
    vector<tuple<double, int, int, bool>> upd;
    for (int i = 0; i < N; i++){
      for (int j = i + 1; j < N; j++){
        if (dist(P[i], P[j]) < R){
          upd.push_back(make_tuple(0, i, j, true));
        }
        int cnt1 = v[i].size(), cnt2 = v[j].size();
        vector<tuple<double, point, int>> c;
        for (int k = 0; k < cnt1; k++){
          c.push_back(make_tuple(t[i][k], v[i][k], 0));
        }
        for (int k = 0; k < cnt2; k++){
          c.push_back(make_tuple(t[j][k], v[j][k], 1));
        }
        sort(c.begin(), c.end());
        int cnt = c.size();
        point v1(0, 0), v2(0, 0);
        vector<double> t2(cnt + 1);
        vector<point> dv(cnt);
        for (int k = 0; k < cnt; k++){
          t2[k] = get<0>(c[k]);
          if (get<2>(c[k]) == 0){
            v1 = get<1>(c[k]);
          }
          if (get<2>(c[k]) == 1){
            v2 = get<1>(c[k]);
          }
          dv[k] = v2 - v1;
        }
        t2[cnt] = T;
        point D = P[j] - P[i];
        for (int k = 0; k < cnt; k++){
          if (abs(dv[k]) > EPS){
            point D2 = D + dv[k] * (t2[k + 1] - t2[k]);
            line L(D, D2);
            if (point_line_distance(point(0, 0), L) < R){
              circle C(point(0, 0), R);
              vector<point> I = line_circle_intersection(L, C);
              for (int l = 0; l < 2; l++){
                double d = dot(I[l] - D, D2 - D) / dist(D, D2);
                if (- EPS < d && d < dist(D, D2) + EPS){
                  upd.push_back(make_tuple(t2[k] + d / abs(dv[k]), i, j, l == 0));
                }
              }
            }
            D = D2;
          }
        }
      }
    }
    sort(upd.begin(), upd.end());
    int M = upd.size();
    vector<vector<bool>> E(N, vector<bool>(N, false));
    vector<bool> used(N, false);
    used[0] = true;
    for (int i = 0; i < M; i++){
      int a = get<1>(upd[i]);
      int b = get<2>(upd[i]);
      bool e = get<3>(upd[i]);
      E[a][b] = e;
      E[b][a] = e;
      if (e && (used[a] ^ used[b])){
        queue<int> Q;
        if (!used[a]){
          used[a] = true;
          Q.push(a);
        }
        if (!used[b]){
          used[b] = true;
          Q.push(b);
        }
        while (!Q.empty()){
          int v = Q.front();
          Q.pop();
          for (int j = 0; j < N; j++){
            if (E[v][j] && !used[j]){
              used[j] = true;
              Q.push(j);
            }
          }
        }
      }
    }
    vector<string> ans;
    for (int i = 0; i < N; i++){
      if (used[i]){
        ans.push_back(s[i]);
      }
    }
    sort(ans.begin(), ans.end());
    int cnt = ans.size();
    for (int i = 0; i < cnt; i++){
      cout << ans[i] << endl;
    }
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3320
final_rank: 5

code_snippet: //WA
#include <bits/stdc++.h>
using namespace std;
const double EPS = 0.00000001;
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator +(point P){
    return point(x + P.x, y + P.y);
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
  point operator *(double k){
    return point(x * k, y * k);
  }
  point operator /(double k){
    return point(x / k, y / k);
  }
  bool operator < (point P) const{
    return x < P.x || x == P.x && y < P.y;
  }
};
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
double dot(point P, point Q){
  return P.x * Q.x + P.y * Q.y;
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
point projection(point P, line L){
  return L.A + vec(L) * dot(P - L.A, vec(L)) / abs(vec(L)) / abs(vec(L));
}
double point_line_distance(point P, line L){
  return abs(cross(L.A - P, vec(L))) / abs(vec(L));
}
struct circle{
  point C;
  double r;
  circle(point C, double r): C(C), r(r){
  }
};
vector<point> line_circle_intersection(line L, circle C){
  double d = point_line_distance(C.C, L);
  if (d > C.r){
  	return vector<point>();
  }
  point P = projection(C.C, L);
  point D = vec(L) / abs(vec(L));
  double m = sqrt(C.r * C.r - d * d);
  vector<point> ans = {P - D * m, P + D * m};
  return ans;
}
int main(){
  while (true){
    int N, T;
    double R;
    cin >> N >> T >> R;
    if (N == 0 && T == 0 && R == 0){
      break;
    }
    vector<string> s(N);
    vector<point> P(N);
    vector<vector<double>> t(N, vector<double>(1));
    vector<vector<point>> v(N);
    for (int i = 0; i < N; i++){
      cin >> s[i];
      cin >> t[i][0] >> P[i].x >> P[i].y;
      while (t[i].back() != T){
        t[i].push_back(0);
        v[i].push_back(point());
        cin >> t[i].back() >> v[i].back().x >> v[i].back().y;
      }
    }
    vector<tuple<double, int, int, bool>> upd;
    for (int i = 0; i < N; i++){
      for (int j = i + 1; j < N; j++){
        if (dist(P[i], P[j]) < R){
          upd.push_back(make_tuple(0, i, j, true));
        }
        int cnt1 = v[i].size(), cnt2 = v[j].size();
        vector<tuple<double, point, int>> c;
        for (int k = 0; k < cnt1; k++){
          c.push_back(make_tuple(t[i][k], v[i][k], 0));
        }
        for (int k = 0; k < cnt2; k++){
          c.push_back(make_tuple(t[j][k], v[j][k], 1));
        }
        sort(c.begin(), c.end());
        int cnt = c.size();
        point v1(0, 0), v2(0, 0);
        vector<double> t2(cnt + 1);
        vector<point> dv(cnt);
        for (int k = 0; k < cnt; k++){
          t2[k] = get<0>(c[k]);
          if (get<2>(c[k]) == 0){
            v1 = get<1>(c[k]);
          }
          if (get<2>(c[k]) == 1){
            v2 = get<1>(c[k]);
          }
          dv[k] = v2 - v1;
        }
        t2[cnt] = T;
        point D = P[j] - P[i];
        for (int k = 0; k < cnt; k++){
        	if (abs(dv[k]) > EPS){
            point D2 = D + dv[k] * (t2[k + 1] - t2[k]);
            line L(D, D2);
            if (point_line_distance(point(0, 0), L) < R){
              circle C(point(0, 0), R);
              vector<point> I = line_circle_intersection(L, C);
              for (int l = 0; l < 2; l++){
                double d = dot(I[l] - D, D2 - D) / dist(D, D2);
                if (0 < d && d < dist(D, D2)){
                  upd.push_back(make_tuple(t2[k] + d / abs(dv[k]), i, j, l == 0));
                }
              }
            }
            D = D2;
          }
        }
      }
    }
    sort(upd.begin(), upd.end());
    int M = upd.size();
    vector<vector<bool>> E(N, vector<bool>(N, false));
    vector<bool> used(N, false);
    used[0] = true;
    for (int i = 0; i < M; i++){
      int a = get<1>(upd[i]);
      int b = get<2>(upd[i]);
      bool e = get<3>(upd[i]);
      E[a][b] = e;
      E[b][a] = e;
      if (e && (used[a] ^ used[b])){
        queue<int> Q;
        if (!used[a]){
          used[a] = true;
          Q.push(a);
        }
        if (!used[b]){
          used[b] = true;
          Q.push(b);
        }
        while (!Q.empty()){
          int v = Q.front();
          Q.pop();
          for (int j = 0; j < N; j++){
            if (E[v][j] && !used[j]){
              used[j] = true;
              Q.push(j);
            }
          }
        }
      }
    }
    vector<string> ans;
    for (int i = 0; i < N; i++){
      if (used[i]){
        ans.push_back(s[i]);
      }
    }
    sort(ans.begin(), ans.end());
    int cnt = ans.size();
    for (int i = 0; i < cnt; i++){
      cout << ans[i] << endl;
    }
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3212
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double EPS = 0.00000001;
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator +(point P){
    return point(x + P.x, y + P.y);
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
  point operator *(double k){
    return point(x * k, y * k);
  }
  point operator /(double k){
    return point(x / k, y / k);
  }
  bool operator < (point P) const{
    return x < P.x || x == P.x && y < P.y;
  }
};
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
double dot(point P, point Q){
  return P.x * Q.x + P.y * Q.y;
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
point projection(point P, line L){
  return L.A + vec(L) * dot(P - L.A, vec(L)) / abs(vec(L)) / abs(vec(L));
}
double point_line_distance(point P, line L){
  return abs(cross(L.A - P, vec(L))) / abs(vec(L));
}
struct circle{
  point C;
  double r;
  circle(point C, double r): C(C), r(r){
  }
};
vector<point> line_circle_intersection(line L, circle C){
  double d = point_line_distance(C.C, L);
  if (d > C.r){
  	return vector<point>();
  }
  point P = projection(C.C, L);
  point D = vec(L) / abs(vec(L));
  double m = sqrt(C.r * C.r - d * d);
  vector<point> ans = {P - D * m, P + D * m};
  return ans;
}
int main(){
  while (true){
    int N, T;
    double R;
    cin >> N >> T >> R;
    if (N == 0 && T == 0 && R == 0){
      break;
    }
    vector<string> s(N);
    vector<point> P(N);
    vector<vector<double>> t(N, vector<double>(1));
    vector<vector<point>> v(N);
    for (int i = 0; i < N; i++){
      cin >> s[i];
      cin >> t[i][0] >> P[i].x >> P[i].y;
      while (t[i].back() != T){
        t[i].push_back(0);
        v[i].push_back(point());
        cin >> t[i].back() >> v[i].back().x >> v[i].back().y;
      }
    }
    vector<tuple<double, int, int, bool>> upd;
    for (int i = 0; i < N; i++){
      for (int j = i + 1; j < N; j++){
        if (dist(P[i], P[j]) < R){
          upd.push_back(make_tuple(0, i, j, true));
        }
        int cnt1 = v[i].size(), cnt2 = v[j].size();
        vector<tuple<double, point, int>> c;
        for (int k = 0; k < cnt1; k++){
          c.push_back(make_tuple(t[i][k], v[i][k], 0));
        }
        for (int k = 0; k < cnt2; k++){
          c.push_back(make_tuple(t[j][k], v[j][k], 1));
        }
        sort(c.begin(), c.end());
        int cnt = c.size();
        point v1(0, 0), v2(0, 0);
        vector<double> t2(cnt + 1);
        vector<point> dv(cnt);
        for (int k = 0; k < cnt; k++){
          t2[k] = get<0>(c[k]);
          if (get<2>(c[k]) == 0){
            v1 = get<1>(c[k]);
          }
          if (get<2>(c[k]) == 1){
            v2 = get<1>(c[k]);
          }
          dv[k] = v2 - v1;
        }
        t2[cnt] = T;
        point D = P[j] - P[i];
        for (int k = 0; k < cnt; k++){
        	if (abs(dv[k]) > EPS){
            point D2 = D + dv[k] * (t2[k + 1] - t2[k]);
            line L(D, D2);
            if (point_line_distance(point(0, 0), L) < R){
              circle C(point(0, 0), R);
              vector<point> I = line_circle_intersection(L, C);
              for (int l = 0; l < 2; l++){
                double d = dot(I[l] - D, D2 - D) / dist(D, D2);
                if (-	EPS < d && d < dist(D, D2) + EPS){
                  upd.push_back(make_tuple(t2[k] + d / abs(dv[k]), i, j, l == 0));
                }
              }
            }
            D = D2;
          }
        }
      }
    }
    sort(upd.begin(), upd.end());
    int M = upd.size();
    vector<vector<bool>> E(N, vector<bool>(N, false));
    vector<bool> used(N, false);
    used[0] = true;
    for (int i = 0; i < M; i++){
      int a = get<1>(upd[i]);
      int b = get<2>(upd[i]);
      bool e = get<3>(upd[i]);
      E[a][b] = e;
      E[b][a] = e;
      if (e && (used[a] ^ used[b])){
        queue<int> Q;
        if (!used[a]){
          used[a] = true;
          Q.push(a);
        }
        if (!used[b]){
          used[b] = true;
          Q.push(b);
        }
        while (!Q.empty()){
          int v = Q.front();
          Q.pop();
          for (int j = 0; j < N; j++){
            if (E[v][j] && !used[j]){
              used[j] = true;
              Q.push(j);
            }
          }
        }
      }
    }
    vector<string> ans;
    for (int i = 0; i < N; i++){
      if (used[i]){
        ans.push_back(s[i]);
      }
    }
    sort(ans.begin(), ans.end());
    int cnt = ans.size();
    for (int i = 0; i < cnt; i++){
      cout << ans[i] << endl;
    }
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3348
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
using Int = long long;
const char newl = '\n';


#define EPS (1e-7)
#define equals(a,b) (fabs((a)-(b)) < EPS)
const double PI = asinl(1) * 2;

// COUNTER CLOCKWISE
static const int CCW_COUNTER_CLOCKWISE = 1;
static const int CCW_CLOCKWISE = -1;
static const int CCW_ONLINE_BACK = 2;
static const int CCW_ONLINE_FRONT = -2;
static const int CCW_ON_SEGMENT = 0;

// intercsect of circles
static const int ICC_SEPERATE = 4;
static const int ICC_CIRCUMSCRIBE = 3;
static const int ICC_INTERSECT = 2;
static const int ICC_INSCRIBE = 1;
static const int ICC_CONTAIN = 0;

struct Point{
  double x,y;
  Point(){}
  Point(double x,double y) :x(x),y(y){}
  Point operator+(Point p) {return Point(x+p.x,y+p.y);}
  Point operator-(Point p) {return Point(x-p.x,y-p.y);}
  Point operator*(double k){return Point(x*k,y*k);}
  Point operator/(double k){return Point(x/k,y/k);}
  double norm(){return x*x+y*y;}
  double abs(){return sqrt(norm());}

  bool operator < (const Point &p) const{
    return x!=p.x?x<p.x:y<p.y;
    //grid-point only
    //return !equals(x,p.x)?x<p.x:!equals(y,p.y)?y<p.y:0;
  }

  bool operator == (const Point &p) const{
    return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
  }
};

struct EndPoint{
  Point p;
  int seg,st;
  EndPoint(){}
  EndPoint(Point p,int seg,int st):p(p),seg(seg),st(st){}
  bool operator<(const EndPoint &ep)const{
    if(p.y==ep.p.y) return st<ep.st;
    return p.y<ep.p.y;
  }
};

istream &operator >> (istream &is,Point &p){
  is>>p.x>>p.y;
  return is;
}

ostream &operator << (ostream &os,Point p){
  os<<fixed<<setprecision(12)<<p.x<<" "<<p.y;
  return os;
}

bool sort_x(Point a,Point b){
  return a.x!=b.x?a.x<b.x:a.y<b.y;
}

bool sort_y(Point a,Point b){
  return a.y!=b.y?a.y<b.y:a.x<b.x;
}

typedef Point Vector;
typedef vector<Point> Polygon;

istream &operator >> (istream &is,Polygon &p){
  for(int i=0;i<(int)p.size();i++) is>>p[i];
  return is;
}

struct Segment{
  Point p1,p2;
  Segment(){}
  Segment(Point p1, Point p2):p1(p1),p2(p2){}
};
typedef Segment Line;

istream &operator >> (istream &is,Segment &s){
  is>>s.p1>>s.p2;
  return is;
}

struct Circle{
  Point c;
  double r;
  Circle(){}
  Circle(Point c,double r):c(c),r(r){}
};

istream &operator >> (istream &is,Circle &c){
  is>>c.c>>c.r;
  return is;
}

double norm(Vector a){
  return a.x*a.x+a.y*a.y;
}
double abs(Vector a){
  return sqrt(norm(a));
}
double dot(Vector a,Vector b){
  return a.x*b.x+a.y*b.y;
}
double cross(Vector a,Vector b){
  return a.x*b.y-a.y*b.x;
}

Point orth(Point p){return Point(-p.y,p.x);}

bool isOrthogonal(Vector a,Vector b){
  return equals(dot(a,b),0.0);
}

bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
  return isOrthogonal(a1-a2,b1-b2);
}

bool isOrthogonal(Segment s1,Segment s2){
  return equals(dot(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

bool isParallel(Vector a,Vector b){
  return equals(cross(a,b),0.0);
}

bool isParallel(Point a1,Point a2,Point b1,Point b2){
  return isParallel(a1-a2,b1-b2);
}

bool isParallel(Segment s1,Segment s2){
  return equals(cross(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

Point project(Segment s,Point p){
  Vector base=s.p2-s.p1;
  double r=dot(p-s.p1,base)/norm(base);
  return s.p1+base*r;
}

Point reflect(Segment s,Point p){
  return p+(project(s,p)-p)*2.0;
}

double arg(Vector p){
  return atan2(p.y,p.x);
}

Vector polar(double a,double r){
  return Point(cos(r)*a,sin(r)*a);
}

int ccw(Point p0,Point p1,Point p2);
bool intersectSS(Point p1,Point p2,Point p3,Point p4);
bool intersectSS(Segment s1,Segment s2);
bool intersectPS(Polygon p,Segment l);
int intersectCC(Circle c1,Circle c2);
bool intersectSC(Segment s,Circle c);
double getDistanceLP(Line l,Point p);
double getDistanceSP(Segment s,Point p);
double getDistanceSS(Segment s1,Segment s2);
Point getCrossPointSS(Segment s1,Segment s2);
Point getCrossPointLL(Line l1,Line l2);
Polygon getCrossPointCL(Circle c,Line l);
Polygon getCrossPointCC(Circle c1,Circle c2);
int contains(Polygon g,Point p);
Polygon andrewScan(Polygon s);
Polygon convex_hull(Polygon ps);
double diameter(Polygon s);
bool isConvex(Polygon p);
double area(Polygon s);
Polygon convexCut(Polygon p,Line l);
Line bisector(Point p1,Point p2);
Vector translate(Vector v,double theta);
vector<Line> corner(Line l1,Line l2);
vector< vector<int> >
segmentArrangement(vector<Segment> &ss, Polygon &ps);

int ccw(Point p0,Point p1,Point p2){
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(cross(a,b) > EPS) return CCW_COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS) return CCW_CLOCKWISE;
  if(dot(a,b) < -EPS) return CCW_ONLINE_BACK;
  if(a.norm()<b.norm()) return CCW_ONLINE_FRONT;
  return CCW_ON_SEGMENT;
}

bool intersectSS(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 &&
          ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0 );
}

bool intersectSS(Segment s1,Segment s2){
  return intersectSS(s1.p1,s1.p2,s2.p1,s2.p2);
}

bool intersectPS(Polygon p,Segment l){
  int n=p.size();
  for(int i=0;i<n;i++)
    if(intersectSS(Segment(p[i],p[(i+1)%n]),l)) return 1;
  return 0;
}

int intersectCC(Circle c1,Circle c2){
  if(c1.r<c2.r) swap(c1,c2);
  double d=abs(c1.c-c2.c);
  double r=c1.r+c2.r;
  if(equals(d,r)) return ICC_CIRCUMSCRIBE;
  if(d>r) return ICC_SEPERATE;
  if(equals(d+c2.r,c1.r)) return ICC_INSCRIBE;
  if(d+c2.r<c1.r) return ICC_CONTAIN;
  return ICC_INTERSECT;
}

bool intersectSC(Segment s,Circle c){
  return getDistanceSP(s,c.c)<=c.r;
}

int intersectCS(Circle c,Segment s){
  if(norm(project(s,c.c)-c.c)-c.r*c.r>EPS) return 0;
  double d1=abs(c.c-s.p1),d2=abs(c.c-s.p2);
  if(d1<c.r+EPS&&d2<c.r+EPS) return 0;
  if((d1<c.r-EPS&&d2>c.r+EPS)||(d1>c.r+EPS&&d2<c.r-EPS)) return 1;
  Point h=project(s,c.c);
  if(dot(s.p1-h,s.p2-h)<0) return 2;
  return 0;
}

double getDistanceLP(Line l,Point p){
  return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s,Point p){
  if(dot(s.p2-s.p1,p-s.p1) < 0.0 ) return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0 ) return abs(p-s.p2);
  return getDistanceLP(s,p);
}

double getDistanceSS(Segment s1,Segment s2){
  if(intersectSS(s1,s2)) return 0.0;
  return min(min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
             min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)));
}

Point getCrossPointSS(Segment s1,Segment s2){
  for(int k=0;k<2;k++){
    if(getDistanceSP(s1,s2.p1)<EPS) return s2.p1;
    if(getDistanceSP(s1,s2.p2)<EPS) return s2.p2;
    swap(s1,s2);
  }
  Vector base=s2.p2-s2.p1;
  double d1=abs(cross(base,s1.p1-s2.p1));
  double d2=abs(cross(base,s1.p2-s2.p1));
  double t=d1/(d1+d2);
  return s1.p1+(s1.p2-s1.p1)*t;
}

Point getCrossPointLL(Line l1,Line l2){
  double a=cross(l1.p2-l1.p1,l2.p2-l2.p1);
  double b=cross(l1.p2-l1.p1,l1.p2-l2.p1);
  if(abs(a)<EPS&&abs(b)<EPS) return l2.p1;
  return l2.p1+(l2.p2-l2.p1)*(b/a);
}

Polygon getCrossPointCL(Circle c,Line l){
  Polygon ps;
  Point pr=project(l,c.c);
  Vector e=(l.p2-l.p1)/abs(l.p2-l.p1);
  if(equals(getDistanceLP(l,c.c),c.r)){
    ps.emplace_back(pr);
    return ps;
  }
  double base=sqrt(c.r*c.r-norm(pr-c.c));
  ps.emplace_back(pr+e*base);
  ps.emplace_back(pr-e*base);
  return ps;
}

Polygon getCrossPointCS(Circle c,Segment s){
  Line l(s);
  Polygon res=getCrossPointCL(c,l);
  if(intersectCS(c,s)==2) return res;
  if(res.size()>1u){
    if(dot(l.p1-res[0],l.p2-res[0])>0) swap(res[0],res[1]);
    res.pop_back();
  }
  return res;
}


Polygon getCrossPointCC(Circle c1,Circle c2){
  Polygon p(2);
  double d=abs(c1.c-c2.c);
  double a=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
  double t=arg(c2.c-c1.c);
  p[0]=c1.c+polar(c1.r,t+a);
  p[1]=c1.c+polar(c1.r,t-a);
  return p;
}

// IN:2 ON:1 OUT:0
int contains(Polygon g,Point p){
  int n=g.size();
  bool x=false;
  for(int i=0;i<n;i++){
    Point a=g[i]-p,b=g[(i+1)%n]-p;
    if(fabs(cross(a,b)) < EPS && dot(a,b) < EPS) return 1;
    if(a.y>b.y) swap(a,b);
    if(a.y < EPS && EPS < b.y && cross(a,b) > EPS ) x = !x;
  }
  return (x?2:0);
}

Polygon andrewScan(Polygon s){
  Polygon u,l;
  if(s.size()<3) return s;
  sort(s.begin(),s.end());
  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);
  for(int i=2;i<(int)s.size();i++){
    for(int n=u.size();
        n>=2&&ccw(u[n-2],u[n-1],s[i])!=CCW_CLOCKWISE;
        n--){
      u.pop_back();
    }
    u.push_back(s[i]);
  }
  for(int i=s.size()-3;i>=0;i--){
    for(int n=l.size();
        n>=2&&ccw(l[n-2],l[n-1],s[i])!=CCW_CLOCKWISE;
        n--){
      l.pop_back();
    }
    l.push_back(s[i]);
  }
  reverse(l.begin(),l.end());
  for(int i=u.size()-2;i>=1;i--) l.push_back(u[i]);
  return l;
}

Polygon convex_hull(Polygon ps){
  int n=ps.size();
  sort(ps.begin(),ps.end(),sort_y);
  int k=0;
  Polygon qs(n*2);
  for(int i=0;i<n;i++){
    while(k>1&&cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<0) k--;
    qs[k++]=ps[i];
  }
  for(int i=n-2,t=k;i>=0;i--){
    while(k>t&&cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<0) k--;
    qs[k++]=ps[i];
  }
  qs.resize(k-1);
  return qs;
}

double diameter(Polygon s){
  Polygon p=s;
  int n=p.size();
  if(n==2) return abs(p[0]-p[1]);
  int i=0,j=0;
  for(int k=0;k<n;k++){
    if(p[i]<p[k]) i=k;
    if(!(p[j]<p[k])) j=k;
  }
  double res=0;
  int si=i,sj=j;
  while(i!=sj||j!=si){
    res=max(res,abs(p[i]-p[j]));
    if(cross(p[(i+1)%n]-p[i],p[(j+1)%n]-p[j])<0.0){
      i=(i+1)%n;
    }else{
      j=(j+1)%n;
    }
  }
  return res;
}

bool isConvex(Polygon p){
  bool f=1;
  int n=p.size();
  for(int i=0;i<n;i++){
    int t=ccw(p[(i+n-1)%n],p[i],p[(i+1)%n]);
    f&=t!=CCW_CLOCKWISE;
  }
  return f;
}

double area(Polygon s){
  double res=0;
  for(int i=0;i<(int)s.size();i++){
    res+=cross(s[i],s[(i+1)%s.size()])/2.0;
  }
  return res;
}

double area(Circle c1,Circle c2){
  double d=abs(c1.c-c2.c);
  if(c1.r+c2.r<=d+EPS) return 0;
  if(d<=abs(c1.r-c2.r)){
    double r=min(c1.r,c2.r);
    return PI*r*r;
  }
  double res=0;
  for(int k=0;k<2;k++){
    double rc=(d*d+c1.r*c1.r-c2.r*c2.r)/(2*d*c1.r);
    double th=acosl(rc)*2;
    res+=(th-sinl(th))*c1.r*c1.r/2;
    swap(c1,c2);
  }
  return res;
}

Polygon convexCut(Polygon p,Line l){
  Polygon q;
  for(int i=0;i<(int)p.size();i++){
    Point a=p[i],b=p[(i+1)%p.size()];
    if(ccw(l.p1,l.p2,a)!=-1) q.push_back(a);
    if(ccw(l.p1,l.p2,a)*ccw(l.p1,l.p2,b)<0)
      q.push_back(getCrossPointLL(Line(a,b),l));
  }
  return q;
}

Line bisector(Point p1,Point p2){
  Circle c1=Circle(p1,abs(p1-p2)),c2=Circle(p2,abs(p1-p2));
  Polygon p=getCrossPointCC(c1,c2);
  if(cross(p2-p1,p[0]-p1)>0) swap(p[0],p[1]);
  return Line(p[0],p[1]);
}

Vector translate(Vector v,double theta){
  Vector res;
  res.x=cos(theta)*v.x-sin(theta)*v.y;
  res.y=sin(theta)*v.x+cos(theta)*v.y;
  return res;
}

vector<Line> corner(Line l1,Line l2){
  vector<Line> res;
  if(isParallel(l1,l2)){
    double d=getDistanceLP(l1,l2.p1)/2.0;
    Vector v1=l1.p2-l1.p1;
    v1=v1/v1.abs()*d;
    Point p=l2.p1+translate(v1,90.0*(PI/180.0));
    double d1=getDistanceLP(l1,p);
    double d2=getDistanceLP(l2,p);
    if(abs(d1-d2)>d){
      p=l2.p1+translate(v1,-90.0*(PI/180.0));
    }
    res.push_back(Line(p,p+v1));
  }else{
    Point p=getCrossPointLL(l1,l2);
    Vector v1=l1.p2-l1.p1,v2=l2.p2-l2.p1;
    v1=v1/v1.abs();
    v2=v2/v2.abs();
    res.push_back(Line(p,p+(v1+v2)));
    res.push_back(Line(p,p+translate(v1+v2,90.0*(PI/180.0))));
  }
  return res;
}

Polygon tangent(Circle c1,Point p2){
  Circle c2=Circle(p2,sqrt(norm(c1.c-p2)-c1.r*c1.r));
  Polygon p=getCrossPointCC(c1,c2);
  sort(p.begin(),p.end());
  return p;
}

vector<Line> tangent(Circle c1,Circle c2){
  vector<Line> ls;
  if(c1.r<c2.r) swap(c1,c2);
  double g=norm(c1.c-c2.c);
  if(equals(g,0)) return ls;
  Point u=(c2.c-c1.c)/sqrt(g);
  Point v=orth(u);
  for(int s=1;s>=-1;s-=2){
    double h=(c1.r+s*c2.r)/sqrt(g);
    if(equals(1-h*h,0)){
      ls.emplace_back(c1.c+u*c1.r,c1.c+(u+v)*c1.r);
    }else if(1-h*h>0){
      Point uu=u*h,vv=v*sqrt(1-h*h);
      ls.emplace_back(c1.c+(uu+vv)*c1.r,c2.c-(uu+vv)*c2.r*s);
      ls.emplace_back(c1.c+(uu-vv)*c1.r,c2.c-(uu-vv)*c2.r*s);
    }
  }

  return ls;
}

double closest_pair(Polygon &a,int l=0,int r=-1){
  if(r<0){
    r=a.size();
    sort(a.begin(),a.end(),sort_x);
  }
  if(r-l<=1) return abs(a[0]-a[1]);
  int m=(l+r)>>1;
  double x=a[m].x;
  double d=min(closest_pair(a,l,m),closest_pair(a,m,r));
  inplace_merge(a.begin()+l,a.begin()+m,a.begin()+r,sort_y);

  Polygon b;
  for(int i=l;i<r;i++){
    if(fabs(a[i].x-x)>=d) continue;
    for(int j=0;j<(int)b.size();j++){
      double dy=a[i].y-next(b.rbegin(),j)->y;
      if(dy>=d) break;
      d=min(d,abs(a[i]-*next(b.rbegin(),j)));
    }
    b.emplace_back(a[i]);
  }
  return d;
}

vector<vector<int> >
segmentArrangement(vector<Segment> &ss, Polygon &ps){
  int n=ss.size();
  for(int i=0;i<n;i++){
    ps.emplace_back(ss[i].p1);
    ps.emplace_back(ss[i].p2);
    for(int j=i+1;j<n;j++)
      if(intersectSS(ss[i],ss[j]))
        ps.emplace_back(getCrossPointSS(ss[i],ss[j]));
  }
  sort(ps.begin(),ps.end());
  ps.erase(unique(ps.begin(),ps.end()),ps.end());

  vector<vector<int> > G(ps.size());
  for(int i=0;i<n;i++){
    vector<pair<double,int> > ls;
    for(int j=0;j<(int)ps.size();j++)
      if(getDistanceSP(ss[i],ps[j])<EPS)
        ls.emplace_back(make_pair(norm(ss[i].p1-ps[j]),j));

    sort(ls.begin(),ls.end());
    for(int j=0;j+1<(int)ls.size();j++){
      int a=ls[j].second,b=ls[j+1].second;
      G[a].emplace_back(b);
      G[b].emplace_back(a);
    }
  }
  for(auto &v:G){
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
  }
  return G;
}

int manhattan_intersection(vector<Segment> ss,const int INF){
  const int BTM = 0;
  const int LFT = 1;
  const int RGH = 2;
  const int TOP = 3;

  int n=ss.size();
  vector<EndPoint> ep;
  for(int i=0;i<n;i++){
    if(ss[i].p1.y==ss[i].p2.y){
      if(ss[i].p1.x>ss[i].p2.x) swap(ss[i].p1,ss[i].p2);
      ep.emplace_back(ss[i].p1,i,LFT);
      ep.emplace_back(ss[i].p2,i,RGH);
    }else{
      if(ss[i].p1.y>ss[i].p2.y) swap(ss[i].p1,ss[i].p2);
      ep.emplace_back(ss[i].p1,i,BTM);
      ep.emplace_back(ss[i].p2,i,TOP);
    }
  }
  sort(ep.begin(),ep.end());

  set<int> bt;
  bt.insert(INF);

  int cnt=0;
  for(int i=0;i<n*2;i++){
    if(ep[i].st==TOP){
      bt.erase(ep[i].p.x);
    }else if(ep[i].st==BTM){
      bt.emplace(ep[i].p.x);
    }else if(ep[i].st==LFT){
      auto b=bt.lower_bound(ss[ep[i].seg].p1.x);
      auto e=bt.upper_bound(ss[ep[i].seg].p2.x);
      cnt+=distance(b,e);
    }
  }

  return cnt;
}

double area(Polygon ps,Circle c){
  if(ps.size()<3u) return 0;
  function<double(Circle, Point, Point)> dfs=
    [&](Circle c,Point a,Point b){
      Vector va=c.c-a,vb=c.c-b;
      double f=cross(va,vb),res=0;
      if(equals(f,0.0)) return res;
      if(max(abs(va),abs(vb))<c.r+EPS) return f;
      Vector d(dot(va,vb),cross(va,vb));
      if(getDistanceSP(Segment(a,b),c.c)>c.r-EPS)
        return c.r*c.r*atan2(d.y,d.x);
      auto u=getCrossPointCS(c,Segment(a,b));
      if(u.empty()) return res;
      if(u.size()>1u&&dot(u[1]-u[0],a-u[0])>0) swap(u[0],u[1]);
      u.emplace(u.begin(),a);
      u.emplace_back(b);
      for(int i=1;i<(int)u.size();i++)
        res+=dfs(c,u[i-1],u[i]);
      return res;
    };
  double res=0;
  for(int i=0;i<(int)ps.size();i++)
    res+=dfs(c,ps[i],ps[(i+1)%ps.size()]);
  return res/2;
}


template<typename T, typename ...Ts>
vector<T> fusion(vector<T> bs,Ts... ts){
  auto append=[&](auto vs){for(auto v:vs) bs.emplace_back(v);};
  initializer_list<int>{(void(append(ts)),0)...};
  return bs;
}


template<typename V>
V compress(V v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}
template<typename T>
map<T, int> dict(const vector<T> &v){
  map<T, int> res;
  for(int i=0;i<(int)v.size();i++)
    res[v[i]]=i;
  return res;
}
map<char, int> dict(const string &v){
  return dict(vector<char>(v.begin(),v.end()));
}

//INSERT ABOVE HERE
using D = double;
int n,T;
D RADIUS;
struct Robot{
  string name;
  Point pos;
  vector<int> ts;
  vector<Vector> vs;
  void input(){
    cin>>name;
    int t0;
    cin>>t0>>pos;
    //cout<<pos<<endl;
    assert(t0==0);
    ts.emplace_back(t0);
    while(cin>>t0){
      vs.emplace_back();
      cin>>vs.back();
      ts.emplace_back(t0);
      if(t0==T) break;
    }
  }
};

Robot create(Robot r,vector<int> ss){
  Robot x;
  x.name=r.name;
  x.pos=r.pos;
  x.ts=ss;
  x.vs.resize(ss.size()-1);
  for(int i=0;i<(int)x.vs.size();i++){
    int cnt=0;
    for(int j=0;j<(int)r.vs.size();j++)
      if(r.ts[j]<=x.ts[i]&&x.ts[i+1]<=r.ts[j+1])
        x.vs[i]=r.vs[j],cnt++;
    assert(cnt==1);
  }
  return x;
}

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  while(cin>>n>>T>>RADIUS,n){
    vector<Robot> rs(n);
    for(int i=0;i<n;i++) rs[i].input();

    vector<D> vt;

    const int LOOP = 100;
    for(int i=0;i<n;i++){
      for(int j=0;j<i;j++){
        vector<int> ss=compress(fusion(rs[i].ts,rs[j].ts));
        Robot p=create(rs[i],ss);
        Robot q=create(rs[j],ss);

        Point pp=p.pos;
        Point qq=q.pos;

        for(int k=0;k+1<(int)ss.size();k++){
          if(abs(pp-qq)<=RADIUS+EPS)
            vt.emplace_back(ss[k]);

          D L=0,R=ss[k+1]-ss[k];
          for(int a=0;a<LOOP;a++){
            D M1=L+(R-L)/3;
            D M2=L+(R-L)/3*2;

            Point p1=pp+p.vs[k]*M1;
            Point p2=pp+p.vs[k]*M2;
            Point q1=qq+q.vs[k]*M1;
            Point q2=qq+q.vs[k]*M2;

            if(abs(p1-q1)<abs(p2-q2)) R=M2;
            else L=M1;
          }

          Point mp=pp+p.vs[k]*L;
          Point mq=qq+q.vs[k]*L;

          // cout<<i<<" "<<j<<":"<<abs(mp-mq)<<endl;
          if(abs(mp-mq)<=RADIUS+EPS){
            vt.emplace_back(ss[k]+L);
            {
              D X=0,Y=L;
              for(int a=0;a<LOOP;a++){
                D Z=(X+Y)/2;
                Point pz=pp+p.vs[k]*Z;
                Point qz=qq+q.vs[k]*Z;
                if(abs(pz-qz)<=RADIUS+EPS) Y=Z;
                else X=Z;
              }
              vt.emplace_back(ss[k]+Y);
            }
            {
              D X=L,Y=ss[k+1]-ss[k];
              for(int a=0;a<LOOP;a++){
                D Z=(X+Y)/2;
                Point pz=pp+p.vs[k]*Z;
                Point qz=qq+q.vs[k]*Z;
                if(abs(pz-qz)<=RADIUS+EPS) X=Z;
                else Y=Z;
              }
              vt.emplace_back(ss[k]+X);
            }
          }

          pp=pp+p.vs[k]*D(ss[k+1]-ss[k]);
          qq=qq+q.vs[k]*D(ss[k+1]-ss[k]);

          if(abs(pp-qq)<=RADIUS+EPS)
            vt.emplace_back(ss[k+1]);
        }
      }
    }

    vt=compress(vt);

    vector<int> ts;
    for(int i=0;i<n;i++)
      ts=fusion(ts,rs[i].ts);
    ts=compress(ts);

    for(int i=0;i<n;i++)
      rs[i]=create(rs[i],ts);

    vector<int> used(n);
    used[0]=1;
    for(int k=0;k<(int)ts.size();k++){
      for(D t:vt){
        if(t<ts[k]||t>ts[k+1]) continue;

        queue<int> que;
        for(int i=0;i<n;i++)
          if(used[i]) que.emplace(i);

        while(!que.empty()){
          int i=que.front();que.pop();
          for(int j=0;j<n;j++){
            if(used[j]) continue;
            Point pp=rs[i].pos+rs[i].vs[k]*(t-ts[k]);
            Point qq=rs[j].pos+rs[j].vs[k]*(t-ts[k]);
            if(abs(pp-qq)<=RADIUS+EPS){
              used[j]=1;
              que.emplace(j);
            }
          }
        }
      }

      for(int i=0;i<n;i++)
        rs[i].pos=rs[i].pos+rs[i].vs[k]*(ts[k+1]-ts[k]);
    }

    vector<string> ans;
    for(int i=0;i<n;i++)
      if(used[i]) ans.emplace_back(rs[i].name);
    sort(ans.begin(),ans.end());
    for(string s:ans) cout<<s<<newl;

  }
  return 0;
}
accuracy: 1
time_ms: 1140
memory_kb: 5144
final_rank: 17

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
const double PI = acos(-1);
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}

vector<double> solve_quadeq(double a, double b, double c){
    vector<double> ret;
    if(abs(a) < EPS){
        if(abs(b) > EPS) ret.push_back(-c/b);
        return ret;
    }
    double d = b*b -4*a*c;
    if(abs(d) < EPS) d = 0;
    if(d < 0) return ret;
    ret.push_back((-b -sqrt(d))/(2*a));
    ret.push_back((-b +sqrt(d))/(2*a));
    return ret;
}

bool epseq(const double &a, const double &b){
	return abs(a-b) < EPS;
}

struct event{
	int a,b,on;
	double time;
	event(int a, int b, int on, double t):a(a),b(b),on(on),time(t){}
	event(){}
	bool operator<(const event &a){
		return time < a.time;
	}
};

vector<event> calc_event(vector<VP> &c, int t, double r){
	int n = c.size();
	vector<event> ret;
	for(int i=0; i<n; i++){
		for(int j=i+1; j<n; j++){
			vector<double> times;
			if(abs(c[i][0]-c[j][0]) < r +EPS){
				times.push_back(0);	
			}
			for(int ct=0; ct<t; ct++){
				P diff = c[j][ct] -c[i][ct];
				P vdiff = (c[j][ct+1] -c[j][ct]) -(c[i][ct+1] -c[i][ct]);
				double a = norm(vdiff);
				double b = 2*dot(diff, vdiff);
				double c = norm(diff) -r*r;
				vector<double> ret = solve_quadeq(a,b,c);
				for(double t : ret){
					if(0 < t +EPS && t < 1 +EPS){
						times.push_back(ct+t);
					}
				}
			}
			sort(times.begin(), times.end());
			times.erase(unique(times.begin(), times.end(), epseq), times.end());
			int on = 0;
			for(double t : times){
				on = 1-on;
				ret.emplace_back(i, j, on, t);
			}
		}		
	}
	sort(ret.begin(), ret.end());
	return ret;
}

void dfs(int v, vector<bool> &used, vector<vector<bool> > &adj){
	if(used[v]) return;
	used[v] = true;
	for(int i=0; i<(int)adj.size(); i++){
		if(adj[v][i]) dfs(i, used, adj);
	}
}

int main(){
	while(1){
		int n,t,r;
		cin >> n >> t >> r;
		if(n == 0) break;

		vector<VP> c(n, VP(t+1));
		vector<string> name(n);
		for(int i=0; i<n; i++){
			cin >> name[i];
			int prev = 0;
			int ct,x,y;
			cin >> ct >> x >> y;
			c[i][0] = P(x, y);
			while(1){
				cin >> ct >> x >> y;
				P vec(x, y);
				for(int s=prev; s<ct; s++){
					c[i][s+1] = c[i][s] +vec;
				}
				prev = ct;
				if(ct == t) break;
			}
		}

		vector<event> info = calc_event(c, t, r);
		vector<vector<bool> > adj(n, vector<bool>(n, false));
		for(int i=0; i<n; i++){
			for(int j=i+1; j<n; j++){
				if(abs(c[i][0] -c[j][0]) < r +EPS){
					adj[i][j] = adj[j][i] = true;
				}
			}
		}
		vector<bool> reach(n, false);
		reach[0] = true;
		for(event e: info){
			if(e.on == 0){
				adj[e.a][e.b] = adj[e.b][e.a] = false;
			}else{
				adj[e.a][e.b] = adj[e.b][e.a] = true;
				if(reach[e.a] != reach[e.b]){
					dfs(e.a, reach, adj);
					dfs(e.b, reach, adj);
				}
			}
		}
		vector<string> ans;
		for(int i=0; i<n; i++){
			if(reach[i]) ans.push_back(name[i]);
		}
		sort(ans.begin(), ans.end());
		for(string s: ans){
			cout << s << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 4440
final_rank: 11

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <utility>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
namespace std{
    bool operator < (const P& a, const P& b){
        return (a.X!=b.X) ? a.X<b.X : a.Y<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}
double dot(P a, P b){
    return (conj(a)*b).X;
}

struct Event{
    double time;
    int a,b;
    bool close;
    Event(double t, int a, int b, bool r):time(t),a(a),b(b),close(r){}
    Event(){}
    bool operator < (const Event &a){
        return time < a.time;
    }
};

void dfs(int v, vector<bool> &used, vector<vector<bool> > &adj){
    if(used[v]) return;
    used[v] = true;
    for(int i=0; i<(int)adj.size(); i++){
        if(adj[v][i]){
            dfs(i, used, adj);
        }
    }
}

int main(){
    while(1){
        int n,t,r;
        cin >> n >> t >> r;
        if(n==0) break;

        vector<string> name(n);
        VP pos(n);
        //その時間に動くべき方向がupper_boundで検索できる
        vector<vector<pair<int, P> > > dir(n);
        for(int i=0; i<n; i++){
            cin >> name[i];
            while(1){
                int time,x,y;
                cin >> time >> x >> y;
                if(time == 0){
                    pos[i] = P(x, y);
                }else{
                    dir[i].push_back(make_pair(time, P(x, y)));
                }
                if(time == t) break;
            }
        }

        vector<Event> event;
        //初期接触
        for(int i=0; i<n; i++){
            for(int j=i+1; j<n; j++){
                if(abs(pos[i] -pos[j]) < r){
                    event.emplace_back(0, i, j, true);
                }
            }
        }
        //時間time ~ time+1について、交差するかシミュレーション
        for(int time=0; time<t; time++){
            VP tdir(n);
            for(int i=0; i<n; i++){
                auto itr = upper_bound(dir[i].begin(), dir[i].end(), make_pair(time, P(INF, INF)));
                tdir[i] = itr->second;
            }
            for(int i=0; i<n; i++){
                for(int j=i+1; j<n; j++){
                    //二次方程式
                    double a,b,c;
                    a = norm(tdir[i] -tdir[j]);
                    b = 2 *dot(pos[i] -pos[j], tdir[i] -tdir[j]);
                    c = norm(pos[i] -pos[j]) -r*r;
                    double d = b*b -4*a*c;
                    if(abs(a) < EPS || d < -EPS) continue;
                    if(d < 0) d = 0;
                    double sol[2] = {(-b +sqrt(d))/(2*a), (-b -sqrt(d))/(2*a)};
                    for(int k=0; k<2; k++){
                        if(0 < sol[k] +EPS && sol[k] < 1 +EPS){
                            P dpos = pos[i]-pos[j];
                            P ddir = tdir[i] -tdir[j];
                            bool close = norm(dpos +sol[k]*ddir) > norm(dpos +(sol[k]+EPS)*ddir);
                            event.emplace_back(time +sol[k], i, j, close);
                        }
                    }
                }
            }
            for(int i=0; i<n; i++){
                pos[i] += tdir[i];
            }
        }
        sort(event.begin(), event.end());
        
        vector<bool> used(n, false);
        used[0] = true;
        vector<vector<bool> > adj(n, vector<bool>(n, false));
        for(int i=0; i<(int)event.size(); i++){
            Event &e = event[i];
            adj[e.a][e.b] = adj[e.b][e.a] = e.close;
            if(e.close && used[e.a] != used[e.b]){
                dfs(e.a, used, adj);
                dfs(e.b, used, adj);
            }
        }

        vector<string> ans;
        for(int i=0; i<n; i++){
            if(used[i]) ans.push_back(name[i]);
        }
        sort(ans.begin(), ans.end());
        for(int i=0; i<(int)ans.size(); i++){
            cout << ans[i] << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 3292
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;

using F = double;

struct Robot {
  string nickname;
  vector<F> t, x, y, vx, vy;
};

int N, T, R;
vector<Robot> robot;

const F EPS = 1e-6;

vector<F> solve(F a, F b, F c) {
  if(a == 0) {
    if(b == 0) return {};
    else       return {-c / b};
  }
  F D = b * b - 4 * a * c;
  if(D < 0) return {};
  else      return {(-b - sqrt(D)) / (2 * a), (-b + sqrt(D)) / (2 * a)};
}

set<F> schedule() {
  set<F> res;

  for(auto r: robot) for(auto t: r.t) res.emplace(t);

  for(auto i = 0; i < N; ++i) for(auto j = 0; j < i; ++j) {
    auto& lhs = robot[i];
    auto& rhs = robot[j];

    for(auto a = 0; a + 1 < lhs.t.size(); ++a) for(auto b = 0; b + 1 < rhs.t.size(); ++b) {
      auto lx = lhs.x[a] - lhs.t[a] * lhs.vx[a];
      auto rx = rhs.x[b] - rhs.t[b] * rhs.vx[b];
      auto dx = lx - rx;

      auto ly = lhs.y[a] - lhs.t[a] * lhs.vy[a];
      auto ry = rhs.y[b] - rhs.t[b] * rhs.vy[b];
      auto dy = ly - ry;

      auto dvx = lhs.vx[a] - rhs.vx[b];
      auto dvy = lhs.vy[a] - rhs.vy[b];

      auto A = dvx * dvx + dvy * dvy;
      auto B = 2 * dx * dvx + 2 * dy * dvy;
      auto C = dx * dx + dy * dy - R * R;

      auto low  = max(lhs.t[a], rhs.t[b]);
      auto high = min(lhs.t[a + 1], rhs.t[b + 1]);

      for(auto t: solve(A, B, C)) if(low <= t + EPS && t <= high + EPS) res.emplace(t);
    }
  }

  return res;
}

multiset<string> solve() {
  vector<bool> ok(N);
  ok[0] = true;
  for(auto t: schedule()) {
    for(auto i = 0; i < N; ++i) for(auto j = 0; j < i; ++j) {
      if(!ok[i] && !ok[j]) continue;

      auto& lhs = robot[i];
      auto& rhs = robot[j];

      auto a = 0, b = 0;
      for(a = 0; a + 1 < lhs.t.size(); ++a) if(lhs.t[a] <= t + EPS && t <= lhs.t[a + 1] + EPS) break;
      for(b = 0; b + 1 < rhs.t.size(); ++b) if(rhs.t[b] <= t + EPS && t <= rhs.t[b + 1] + EPS) break;

      auto lx = lhs.x[a] + (t - lhs.t[a]) * lhs.vx[a];
      auto rx = rhs.x[b] + (t - rhs.t[b]) * rhs.vx[b];
      auto dx = lx - rx;

      auto ly = lhs.y[a] + (t - lhs.t[a]) * lhs.vy[a];
      auto ry = rhs.y[b] + (t - rhs.t[b]) * rhs.vy[b];
      auto dy = ly - ry;

      if(dx * dx + dy * dy <= R * R + EPS) ok[i] = ok[j] = true;
    }
  }

  multiset<string> res;
  for(auto i = 0; i < N; ++i) if(ok[i]) res.emplace(robot[i].nickname);
  return res;
}

int main() {
  while(cin >> N >> T >> R, N | T | R) {
    robot = vector<Robot>(N);

    for(auto& r: robot) {
      cin >> r.nickname;

      while(true) {
        int t, vx, vy;
        cin >> t >> vx >> vy;
        if(r.t.empty()) {
          r.x.emplace_back(vx);
          r.y.emplace_back(vy);
        } else {
          r.vx.emplace_back(vx);
          r.vy.emplace_back(vy);
          auto d = t - r.t.back();
          r.x.emplace_back(r.x.back() + d * vx);
          r.y.emplace_back(r.y.back() + d * vy);
        }
        r.t.emplace_back(t);
        if(t == T) break;
      }
    }

    for(auto s: solve()) cout << s << endl;
  }
}
accuracy: 1
time_ms: 240
memory_kb: 3300
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
typedef double D;
typedef complex<D> P;
D inf=1e50;
D dot(P x,P y){return real(x*conj(y));}
int N,T,R,n[100];
string st[100];
D t[100][1001];
P v[100][1001],p[100][1001];
D fi(D x){
	if(abs(x)<1e-9) return 0;
	return x;
}
typedef pair<D,D> Pdd;
vector<Pdd> segs[100][100];
void fix(vector<Pdd> vc){
	if(vc.empty()) return;
	sort(all(vc));
	vector<Pdd> ret;
	D l=vc[0].fs,r=vc[0].sc;
	for(Pdd p:vc){
		if(r<p.fs){
			ret.pb(Pdd(l,r));
			l=p.fs,r=p.sc;
		}else{
			chmax(r,p.sc);
		}
	}
	ret.pb(Pdd(l,r));
	vc=ret;
}
D fst(vector<Pdd> vc,D t){
	int N=vc.size();
	int id=lower_bound(all(vc),Pdd(t,0))-vc.begin()-1;
	if(id>=0&&vc[id].fs<t&&t<vc[id].sc) return t;
	id++;
	if(id==N) return inf;
	return vc[id].fs;
}
int main(){
	while(true){
		cin>>N>>T>>R;
		if(N==0) break;
		rep(i,N) rep(j,N) segs[i][j].clear();
		rep(i,N){
			cin>>st[i];
			int j=0;
			while(true){
				int vx,vy;
				cin>>t[i][j]>>vx>>vy;
				if(j==0) p[i][0]=P(vx,vy);
				else{
					v[i][j-1]=P(vx,vy);
					p[i][j]=p[i][j-1]+v[i][j-1]*(t[i][j]-t[i][j-1]);
				}
				if(t[i][j]==T) break;
				j++;
			}
			n[i]=j;
		}
		rep(a,N) rep(b,a){
			rep(i,n[a]) rep(j,n[b]){
				D tl=max(t[a][i],t[b][j]);
				D tr=min(t[a][i+1],t[b][j+1]);
				if(tl>tr) continue;
				P s=(p[a][i]-t[a][i]*v[a][i])-(p[b][j]-t[b][j]*v[b][j]),dv=v[a][i]-v[b][j];
				D A=fi(norm(dv));
				D B=2.0*dot(s,dv);
				D C=fi(norm(s)-R*R);
				if(A==0){
					// if(a==1&&b==0){
					// 	show(i);
					// 	show(j);
					// 	show(C);
					// 	show(p[a][i]);
					// 	show(p[b][j]);
					// 	show(v[a][i]);
					// 	show(v[b][j]);
					// }
					if(C<=0) segs[a][b].pb(Pdd(tl,tr));
					continue;
				}
				D det=B*B-4*A*C;
				if(det<0) continue;
				D x=(-B-sqrt(det))/2.0/A,y=(-B+sqrt(det))/2.0/A;
				chmax(tl,x);chmin(tr,y);
				if(tl<tr) segs[a][b].pb(Pdd(tl,tr));
			}
			fix(segs[a][b]);
			// if(a==1&&b==0){
			// 	for(Pdd p:segs[a][b]) printf("(%.1f,%.1f) ",p.fs,p.sc);
			// 	puts("");
			// }
			segs[b][a]=segs[a][b];
//			cout<<a<<","<<b<<"  ";
//			show(d[a][b]);
		}
		bool done[100]={};
		D d[100];
		rep(i,N) d[i]=inf;
		d[0]=0;
		rep(i,N){
			int mn=-1;
			rep(j,N) if(!done[j]&&(mn<0||d[j]<d[mn])) mn=j;
			if(mn<0||d[mn]==inf) break;
			done[mn]=1;
//			show(mn);
			rep(j,N) if(!done[j]){
				D x=fst(segs[mn][j],d[mn]);
				chmin(d[j],x);
			}
//			if(i==0) rep(j,N) show(d[j]);
		}
		vector<string> ans;
		rep(i,N) if(d[i]<T) ans.pb(st[i]);
		sort(all(ans));
		for(string s:ans) cout<<s<<endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 4812
final_rank: 9

code_snippet: #include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<string>
#include<queue>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e+10;
const double PI = acos(-1);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
inline double ABS(double a){return max(a,-a);}
struct Pt {
	double x, y;
	Pt() {}
	Pt(double x, double y) : x(x), y(y) {}
	Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
	Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
	Pt operator*(const Pt &a) const { return Pt(x * a.x - y * a.y, x * a.y + y * a.x); }
	Pt operator-() const { return Pt(-x, -y); }
	Pt operator*(const double &k) const { return Pt(x * k, y * k); }
	Pt operator/(const double &k) const { return Pt(x / k, y / k); }
	double ABS() const { return sqrt(x * x + y * y); }
	double abs2() const { return x * x + y * y; }
	double arg() const { return atan2(y, x); }
	double dot(const Pt &a) const { return x * a.x + y * a.y; }
	double det(const Pt &a) const { return x * a.y - y * a.x; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }
int iSP(Pt a, Pt b, Pt c) {
	int s = sig((b - a).det(c - a));
	if (s) return s;
	if (sig((b - a).dot(c - a)) < 0) return -2; // c-a-b
	if (sig((a - b).dot(c - b)) < 0) return +2; // a-b-c
	return 0;
}
double dSP(Pt a, Pt b, Pt c) {
	if (sig((b - a).dot(c - a)) <= 0) return (c - a).ABS();
	if (sig((a - b).dot(c - b)) <= 0) return (c - b).ABS();
	return ABS(tri(a, b, c)) / (b - a).ABS();
}
bool iCS(Pt a, double r, Pt b, Pt c) {
	return (sig(r - dSP(b, c, a)) >= 0 && sig(r - max((b - a).ABS(), (c - a).ABS())) <= 0);
}
pair<Pt,Pt> pCL(Pt a, double r, Pt b, Pt c) {
	Pt h = b + (c - b) * (c - b).dot(a - b) / (c - b).abs2(); // perp(b, c, a)
	double d = (h - a).ABS();
	double y = sqrt(max(r * r - d * d, 0.0));
	Pt e = (c - b) / (c - b).ABS();
	return make_pair(h - e * y, h + e * y);
}
char in[100];
string name[110];
vector<Pt>v[110];
vector<double>t[110];
vector<pair<double,pair<int,int> > >ev;
vector<string>ans;
int ret[110];
int g[110][110];
int bfs[110];
int main(){
	int a,b,c;
	scanf("%d%d%d",&a,&b,&c);
	scanf("%s",in);
	int na,nb,nc;
	while(a){
		double r=(double)c;
		for(int i=0;i<110;i++){
			v[i].clear();
			t[i].clear();
		}
		for(int i=0;i<a;i++){
			name[i]=in;
			while(1){
				int chk=scanf("%s",in);
				if(chk==-1)break;
				if('a'<=in[0]&&in[0]<='z')break;
				int tmp,x,y;
				sscanf(in,"%d",&tmp);
				na=tmp;
				t[i].push_back((double)tmp);
				scanf("%d%d",&x,&y);
				nb=x;nc=y;
				v[i].push_back(Pt((double)x,(double)y));
			}
			if(i==a-1){
				t[i].pop_back();
				v[i].pop_back();
			}
		}
		ev.clear();
		for(int i=0;i<a;i++)for(int j=i+1;j<a;j++){
			if((v[i][0]-v[j][0]).ABS()<r)ev.push_back(make_pair(0,make_pair(i,j)));
			int L=1;
			int R=1;
			Pt at=v[i][0]-v[j][0];
			while(1){
				double left=max(t[i][L-1],t[j][R-1]);
				double right=min(t[i][L],t[j][R]);
				Pt tv=v[i][L]-v[j][R];
				if(iCS(Pt(0,0),r,at,at+tv*(right-left))){
					pair<Pt,Pt> it=pCL(Pt(0,0),r,at,at+tv*(right-left));
					if(iSP(at,it.first,at+tv*(right-left))==2||(at+tv*(right-left)-it.first).ABS()<EPS){
						ev.push_back(make_pair(left+(it.first-at).ABS()/(tv.ABS()),make_pair(i,j)));
					}
					if(iSP(at,it.second,at+tv*(right-left))==2||(at+tv*(right-left)-it.second).ABS()<EPS){
						ev.push_back(make_pair(left+(it.second-at).ABS()/(tv.ABS()),make_pair(i,j)));
					}
				}
				at=at+tv*(right-left);
				if(L==t[i].size()-1&&R==t[j].size()-1)break;
				else if(L==t[i].size()-1)R++;
				else if(R==t[j].size()-1)L++;
				else if(t[i][L]>t[j][R]+EPS)R++;
				else if(t[i][L]+EPS<t[j][R])L++;
				else {L++;R++;}
			}
		}
		std::sort(ev.begin(),ev.end());
		for(int i=0;i<a;i++)ret[i]=0;
		ret[0]=1;
		for(int i=0;i<a;i++)for(int j=0;j<a;j++)g[i][j]=0;
		for(int i=0;i<ev.size();i++){
			g[ev[i].second.first][ev[i].second.second]^=1;
			if(g[ev[i].second.first][ev[i].second.second]&&ret[ev[i].second.first]+ret[ev[i].second.second]){
				queue<int>Q;
				for(int j=0;j<a;j++)bfs[j]=0;
				Q.push(ev[i].second.first);
				bfs[ev[i].second.first]=1;
				while(Q.size()){
					int at=Q.front();
					Q.pop();
					for(int j=0;j<a;j++){
						if(!bfs[j]&&(g[at][j]||g[j][at])){
							bfs[j]=1;Q.push(j);
						}
					}
				}
				for(int j=0;j<a;j++)if(bfs[j])ret[j]=1;
			}
		}
		ans.clear();
		for(int i=0;i<a;i++)if(ret[i])ans.push_back(name[i]);
		std::sort(ans.begin(),ans.end());
		for(int i=0;i<ans.size();i++)printf("%s\n",ans[i].c_str());
		a=na;b=nb;c=nc;
	}
}
accuracy: 1
time_ms: 20
memory_kb: 1328
final_rank: 1

code_snippet: #include<iostream>
#include<cmath>
#include<vector>
#include<string>
#include<numeric>
#include<algorithm>

using namespace std;

int par[123];

int find(int x){
  return (par[x]==x)?x:par[x]=find(par[x]);
}

void unite(int a,int b){
  par[find(a)]=find(b);
}

int ex[123][1234],ey[123][1234];
int evx[123][1234],evy[123][1234];

double sqr(double x){return x*x;}

int main(){
  for(int N,T,R;cin>>N>>T>>R,N|T|R;){
    char nicknames[123][12];
    vector<int> t[123],x[123],y[123],vx[123],vy[123];
    vector<double> ev;
    for(int i=0;i<N;i++){
      cin>>nicknames[i];
      for(int j=0;;j++){
	int ti,xi,yi;
	cin>>ti>>xi>>yi;
	ev.push_back(ti);
	t[i].push_back(ti);
	int cx,cy;
	if(j){
	  vx[i].push_back(xi);
	  vy[i].push_back(yi);
	  for(int k=t[i][j-1]+1;k<=ti;k++){
	    ey[i][k]=ey[i][k-1]+yi;
	    ex[i][k]=ex[i][k-1]+xi;
	    evy[i][k-1]=yi;
	    evx[i][k-1]=xi;
	  }
	  cy=ey[i][ti];
	  cx=ex[i][ti];
	}else{
	  cx=xi;
	  cy=yi;
	  ex[i][0]=cx;
	  ey[i][0]=cy;
	}
	x[i].push_back(cx);
	y[i].push_back(cy);
	if(ti==T)break;
      }
    }
    for(int i=0;i<N;i++){
      for(int j=0;j<vx[i].size();j++){
	int y1=y[i][j]-t[i][j]*vy[i][j];
	int x1=x[i][j]-t[i][j]*vx[i][j];
	for(int k=0;k<i;k++){
	  for(int l=0;l<vx[k].size();l++){
	    int y2=y[k][l]-t[k][l]*vy[k][l];
	    int x2=x[k][l]-t[k][l]*vx[k][l];
	    long long X=x1-x2;
	    long long Y=y1-y2;
	    long long VX=vx[i][j]-vx[k][l];
	    long long VY=vy[i][j]-vy[k][l];
	    long long a=VX*VX+VY*VY;
	    long long b=X*VX+Y*VY;
	    long long c=X*X+Y*Y-R*R;
	    long long inr=b*b-a*c;
	    if(inr>=0&&a){
	      ev.push_back((-b-sqrt(inr))/a);
	      ev.push_back((-b+sqrt(inr))/a);
	    }
	  }
	}
      }
    }
    sort(begin(ev),end(ev));
    bool has[123]={true};
    for(int k=0;k<ev.size()-1;k++){
      double e=(ev[k]+ev[k+1])/2;
      //      cerr<<e<<endl;
      if(e<0||T<e)continue;
      iota(begin(par),end(par),0);
      int g=e;
      double f=e-g;
      for(int i=0;i<N;i++){
	for(int j=0;j<i;j++){
	  if(sqr(ey[i][g]+evy[i][g]*f-(ey[j][g]+evy[j][g]*f))+
	     sqr(ex[i][g]+evx[i][g]*f-(ex[j][g]+evx[j][g]*f))<=R*R){
	    unite(i,j);
	  }
	}
      }
      for(int i=0;i<N;i++){
	has[find(i)]|=has[i];
      }
      for(int i=0;i<N;i++){
	has[i]|=has[find(i)];
      }
    }
    vector<string> ans;
    for(int i=0;i<N;i++){
      if(has[i]){
	ans.push_back(nicknames[i]);
      }
    }
    sort(begin(ans),end(ans));
    for(auto e:ans){
      cout<<e<<endl;
    }
  }
}
accuracy: 1
time_ms: 1330
memory_kb: 5532
final_rank: 19

code_snippet: #include <string>
#include <iostream>
#include <complex>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define ALL(x) (x).begin(),(x).end() 
using namespace std;
const double eps = 1e-10;

typedef complex<double> P;
 
inline double dot(const P &a, const P &b){
    return real(conj(a) * b);
}
inline double cross(const P &a, const P &b){
    return imag(conj(a) * b);
}
int ccw(const P &a, P b, P c){
    b -= a; c -= a;
    if (cross(b, c) > eps)  return +1;  // ccw
    if (cross(b, c) < -eps) return -1;  // cw
    if (dot(b,c) < 0)       return +2;  // c-a-b
    if (norm(b) < norm(c))  return -2;  // a-b-c
    return 0;                           // a-c-b
}
struct Line : public vector<P> {
    Line() { }
    Line(const P &a, const P &b) {
        push_back(a); push_back(b);
    }
};
inline bool parallel(const Line &s, const Line &t){
    return abs(cross(s[1]-s[0], t[1]-t[0])) < eps;
}
inline bool orthogonal(const Line &s, const Line &t){
    return abs(dot(s[1]-s[0], t[1]-t[0])) < eps;
}
P projection(const Line &s, const P &a){
    P v = s[1] - s[0];
    return s[0] + dot(v, a - s[0]) / abs(v) / abs(v) * v;
}
P reflection(const Line &s, const P &a){
    P p = projection(s, a);
    return 2.0 * p - a;
}

struct D{
	double t;
	int a, b;
	D(){}
	D(double t, int a, int b) : t(t), a(a), b(b) { }
};
bool operator<(const D &a, const D &b){
	return a.t < b.t;
}

int main(){
	for(;;){
		int N, T, R;
		cin >> N >> T >> R;
		if(N == 0) return 0;
		vector<string> name(N);
		vector<vector<int> > vt(N);
		vector<vector<P> > vp(N);
		for(int i=0;i<N;++i){
			cin >> name[i];
			for(;;){
				int t, x, y;
				cin >> t >> x >> y;
				vt[i].push_back(t);
				vp[i].push_back(P(x,y));
				if(t == T) break;
			}
		}
		vector<D> ev;
		for(int i=0;i<N;++i)for(int j=i+1;j<N;++j){
			P p = vp[i][0], q = vp[j][0];
			int idx1 = 1, idx2 = 1;
			int lt = 0;
			if(abs(p-q) < R){
				ev.push_back(D(0, i, j));
			}
			while(idx1 < vp[i].size() && idx2 < vp[j].size()){
				P v = vp[i][idx1], u = vp[j][idx2];
				int nt = min(vt[i][idx1], vt[j][idx2]);
				double a = norm(v-u), c = norm(p-q) - R * R;
				double b = 2*((real(p)-real(q)) * (real(v)-real(u))
								+ (imag(p)-imag(q)) * (imag(v)-imag(u)));

				if(abs(v-u) > eps && b*b-4*a*c > 0){
					double t1 = lt + (-b + sqrt(b*b-4*a*c))/(2 * a);
					double t2 = lt + (-b - sqrt(b*b-4*a*c))/(2 * a);
					if(lt-eps < t1 && t1 < nt+eps)
						ev.push_back(D(t1, i, j));
					if(lt-eps < t2 && t2 < nt+eps)
						ev.push_back(D(t2, i, j));
					// cerr << name[i] << "*" << name[j] << t1 << "," << t2 << endl;
				}

				p += v * (double)(nt - lt);
				q += u * (double)(nt - lt);
				lt = nt;
				if(vt[i][idx1] < vt[j][idx2])
					++idx1;
				else
					++idx2;
			}
		}
		sort(ALL(ev));

		vector<vector<int> > d(N, vector<int>(N));
		vector<int> vst(N);
		for(int i=0;i<N;++i) d[i][i] = 1;
		vst[0] = 1;

		/*
		EACH(i, name) cerr << *i << ",";
		cerr << endl;
		cerr << "start" << ev.size() <<  endl;
		*/
		EACH(i, ev){
			d[i->a][i->b] = 1-d[i->a][i->b];
			d[i->b][i->a] = 1-d[i->b][i->a];
			/*
			cerr << ">";
			for(int j=0;j<N;++j) cerr << vst[j];
			cerr << endl;
			
			for(int j=0;j<N;++j){
				for(int k=0;k<N;++k) cerr << d[j][k];
				cerr << endl;
			}*/
			if(vst[i->a] != vst[i->b]){
				queue<int> Q;
				for(int j=0;j<N;++j) if(vst[j]) Q.push(j);
				while(!Q.empty()){
					int v = Q.front(); Q.pop();
					for(int j=0;j<N;++j) if(!vst[j] && d[v][j]){
						vst[j] = 1;
						Q.push(j);
					}
				}
			}
		}

		vector<string> res;
		for(int i=0;i<N;++i) if(vst[i]) res.push_back(name[i]);
		sort(ALL(res));
		EACH(i, res) cout << *i << endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 1460
final_rank: 2

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(a) (a).begin(),(a).end()
#define EQ(a,b) (abs((a)-(b)) < EPS)
using namespace std;
typedef double D;
typedef complex<D> P;
typedef pair<int,int> pii;
typedef pair<D, pii> data;
typedef vector<int> vi;
const D EPS = 1e-8;

int n;
string name[110];
D T,r,x[110],y[110],t[110][1100];
D vx[110][1100], vy[110][1100];

vector<D> cal(int a, int b){
  vector<D> res;
  P pa = P(x[a],y[a]), pb = P(x[b],y[b]);
  if( abs(pa-pb)<r+EPS )res.push_back(0);

  int ta=1, tb=1;
  D cur = 0, nxt = min(t[a][ta],t[b][tb]);
  while(!EQ(cur,T)){
    D tx = pa.real() - pb.real(), ty = pa.imag() - pb.imag();
    D tvx = vx[a][ta] - vx[b][tb], tvy = vy[a][ta] - vy[b][tb];
    D A = tvx*tvx + tvy*tvy, B = 2*tvx*tx + 2*tvy*ty, C = tx*tx + ty*ty - r*r;
    D d = B*B - 4*A*C;
    vector<D> sol;

    if(EQ(A,0)){
      if(!EQ(B,0))sol.push_back(-C/B);
    }else if(EQ(d,0)){
      sol.push_back(-B/2/A);
    }else if(d>EPS){
      sol.push_back( (-B - sqrt(d))/2/A );
      sol.push_back( (-B + sqrt(d))/2/A );
    }

    rep(i,sol.size()){
      if(sol[i]+EPS < 0 || nxt-cur+EPS < sol[i])continue;
      res.push_back(cur + sol[i]);
    }

    D dif = nxt - cur;
    pa += P(vx[a][ta]*dif, vy[a][ta]*dif);
    pb += P(vx[b][tb]*dif, vy[b][tb]*dif);

    cur = nxt;
    if(EQ(t[a][ta],cur))ta++;
    if(EQ(t[b][tb],cur))tb++;
    nxt = min(t[a][ta],t[b][tb]);
  }
  return res;
}

bool prop[110];
vector<vi> g;
void dfs(int v){
  prop[v] = true;
  for(int u : g[v]){
    if(!prop[u])dfs(u);
  }
}

int main(){
  cin.tie(0); ios::sync_with_stdio(0);
  while(cin >> n >> T >> r){
    if(n==0)break;
   
    rep(i,n){
      cin >> name[i];
      cin >> t[i][0] >> x[i] >> y[i];
      for(int j=0;;j++){
	cin >> t[i][j+1] >> vx[i][j+1] >> vy[i][j+1];
	if(EQ(t[i][j+1], T))break;
      }
    }

    vector<data> event;
    rep(i,n)rep(j,i){
      vector<D> sub_event = cal(i,j);
      for(D d : sub_event){
	event.push_back(data(d, pii(i,j)));
      }
    }
    sort(all(event));
    
    memset(prop,0,sizeof(prop));
    prop[0] = true;
    g = vector<vi>(n,vi());

    rep(i,event.size()){
      if(event[i].first>T+EPS)break;
      int a = event[i].second.first, b = event[i].second.second;
      bool f = true;
      rep(j,g[a].size()){
	if(g[a][j] == b){ f = false; break; }
      }

      if(f){
	g[a].push_back(b); g[b].push_back(a);
	if(prop[a] |= prop[b])dfs(a);
      }else{
	rep(j,g[a].size()){
	  if(g[a][j] == b)g[a].erase(g[a].begin()+j);
	}
	rep(j,g[b].size()){
	  if(g[b][j] == a)g[b].erase(g[b].begin()+j);
	}
      }	
    }
    
    vector<string> ans;
    rep(i,n){
      if(prop[i])ans.push_back(name[i]);
    }
    sort(all(ans));
    for(string s : ans)cout << s << endl;
  }
}
accuracy: 1
time_ms: 20
memory_kb: 2604
final_rank: 3