#include #include #include using namespace std; #define REP(i,n) for(int i = 0; i < (int)(n); i++) #define FOR(i,c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i) #define ALLOF(c) (c).begin(), (c).end() typedef complex P; struct C { P p; int r; }; istream& operator>>(istream& is, P& p) { int x, y; is >> x >> y; p = P(x, y); return is; } bool cp_contains(const C& c, const P& p) { return (norm(c.p-p) < c.r*c.r); } bool cc_contains(const C& c1, const C& c2) { return (c1.r > c2.r && norm(c1.p-c2.p) < (c1.r-c2.r)*(c1.r-c2.r)); } bool cc_outside(const C& c1, const C& c2) { return (norm(c1.p-c2.p) > (c1.r+c2.r)*(c1.r+c2.r)); } int search(int i, const vector& cs, const P& s, const P& t, vector& memo) { const int n = cs.size(); int& res = memo[i]; if (res < 0) { if (cp_contains(cs[i], s) == cp_contains(cs[i], t)) { res = 0; } else if (cp_contains(cs[i], s)) { res = 1; REP(j, n) { if ((cp_contains(cs[j], s) && !cp_contains(cs[j], t) && cc_contains(cs[j], cs[i])) || (!cp_contains(cs[j], s) && cp_contains(cs[j], t) && cc_outside(cs[j], cs[i]))) { res = max(res, 1+search(j, cs, s, t, memo)); } } } else { // cp_contains(cs[i], t) res = 1; REP(j, n) { if (!cp_contains(cs[j], s) && cp_contains(cs[j], t) && cc_contains(cs[i], cs[j])) { res = max(res, 1+search(j, cs, s, t, memo)); } } } } return res; } int main() { int n; P s, t; while(cin >> n >> s >> t && !(n == 0)) { vector cs(n); REP(i, n) { C& c = cs[i]; cin >> c.p >> c.r; } int res = 0; vector memo(n, -1); REP(k, n) res = max(res, search(k, cs, s, t, memo)); cout << res << endl; } return 0; }