#include <bits/stdc++.h>
using namespace std;
template <typename T, typename E>
ostream &operator<<(std::ostream &os, const std::pair<T, E> &p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
namespace std {
bool operator<(const complex<double> &a, const complex<double> &b) {
  return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
}
}  // namespace std
const double EPS = 1e-9;
inline bool equal(double a, double b) { return abs(a - b) < EPS; }
istream &operator>>(istream &is, complex<double> &p) {
  double x, y;
  is >> x >> y;
  p = complex<double>(x, y);
  return is;
}
istream &operator>>(istream &is, pair<complex<double>, complex<double> > &l) {
  return is >> l.first >> l.second;
}
inline double cross(const complex<double> &a, const complex<double> &b) {
  return imag(conj(a) * b);
}
inline double dot(const complex<double> &a, const complex<double> &b) {
  return real(conj(a) * b);
}
inline complex<double> rotate(const complex<double> &a, double theta) {
  return a * polar(1.0, theta);
}
inline complex<double> direction(
    const pair<complex<double>, complex<double> > &line) {
  return line.second - line.first;
}
int ccw(const complex<double> &a, complex<double> b, complex<double> c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0) return 1;
  if (cross(b, c) < 0) return -1;
  if (dot(b, c) < 0) return 2;
  if (norm(b) < norm(c)) return -2;
  return 0;
}
int ccw(const pair<complex<double>, complex<double> > &l,
        const complex<double> &a) {
  return ccw(l.first, l.second, a);
}
pair<complex<double>, complex<double> > bisector(const complex<double> &a,
                                                 const complex<double> &b) {
  complex<double> v = rotate(b - a, M_PI / 4);
  complex<double> m = (a + b) * 0.5;
  return pair<complex<double>, complex<double> >(m, m + v);
};
bool intersectSP(const pair<complex<double>, complex<double> > &s,
                 const complex<double> &p) {
  return abs(s.first - p) + abs(s.second - p) - abs(direction(s)) < EPS;
}
bool intersectSS(const pair<complex<double>, complex<double> > &s,
                 const pair<complex<double>, complex<double> > &t) {
  return ccw(s, t.first) * ccw(s, t.second) <= 0 &&
         ccw(t, s.first) * ccw(t, s.second) <= 0;
}
complex<double> projection(const pair<complex<double>, complex<double> > &l,
                           const complex<double> &p) {
  double t = dot(p - l.first, direction(l) / norm(direction(l)));
  return l.first + t * (direction(l));
}
double distanceSP(const pair<complex<double>, complex<double> > &s,
                  const complex<double> &p) {
  const complex<double> r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.first - p), abs(s.second - p));
}
double distanceSS(const pair<complex<double>, complex<double> > &s,
                  const pair<complex<double>, complex<double> > &t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.first), distanceSP(s, t.second)),
             min(distanceSP(t, s.first), distanceSP(t, s.second)));
}
complex<double> crosspoint(const pair<complex<double>, complex<double> > &l,
                           const pair<complex<double>, complex<double> > &m) {
  complex<double> l_vec = direction(l);
  complex<double> m_vec = direction(m);
  double A = cross(l_vec, m_vec);
  assert(!equal(A, 0));
  return m.first + cross(l_vec, l.second - m.first) / A * m_vec;
}
inline size_t next_index(const vector<complex<double> > &poly, size_t curr) {
  return (curr + 1) % poly.size();
}
inline size_t prev_index(const vector<complex<double> > &poly, size_t curr) {
  return (curr + poly.size() - 1) % poly.size();
}
vector<complex<double> > convex_cut(
    const vector<complex<double> > &poly,
    const pair<complex<double>, complex<double> > &line) {
  vector<complex<double> > new_poly;
  for (size_t i = 0; i < poly.size(); i++) {
    complex<double> a = poly[i];
    complex<double> b = poly[next_index(poly, i)];
    if (ccw(line, a) != -1) new_poly.push_back(a);
    if (ccw(line, a) * ccw(line, b) < 0) {
      new_poly.push_back(
          crosspoint(pair<complex<double>, complex<double> >(a, b), line));
    }
  }
  return new_poly;
}
double signed_area(const vector<complex<double> > &poly) {
  double res = 0;
  for (size_t i = 0; i < poly.size(); i++) {
    res += cross(poly[i], poly[next_index(poly, i)]);
  }
  return res * 0.5;
}
double area(const vector<complex<double> > &poly) {
  return abs(signed_area(poly));
}
struct star {
  int x, y, a, r;
  vector<complex<double> > points() const {
    vector<complex<double> > ps;
    complex<double> center = complex<double>(x, y);
    double theta = (double)a / 180 * M_PI + M_PI / 2;
    for (int i = (int)(0); i < (int)(5); i++) {
      ps.push_back(center + polar((double)r, theta + M_PI * i * 2 / 5));
    }
    return ps;
  }
  vector<pair<complex<double>, complex<double> > > segments() const {
    vector<complex<double> > ps = this->points();
    vector<pair<complex<double>, complex<double> > > res;
    for (int i = (int)(0); i < (int)(ps.size()); i++)
      for (int j = (int)(0); j < (int)(i); j++) {
        res.push_back(pair<complex<double>, complex<double> >(ps[j], ps[i]));
      }
    return res;
  }
};
double distance(const star &s, const star &t) {
  vector<pair<complex<double>, complex<double> > > seg_ss = s.segments();
  vector<pair<complex<double>, complex<double> > > seg_ts = t.segments();
  double res = 1e9;
  for (pair<complex<double>, complex<double> > seg_s : seg_ss) {
    for (pair<complex<double>, complex<double> > seg_t : seg_ts) {
      res = min(res, distanceSS(seg_s, seg_t));
    }
  }
  return res;
}
int main() {
  ios::sync_with_stdio(false);
  int N, M, L;
  while (cin >> N >> M >> L && N + M + L) {
    vector<star> stars(N);
    vector<vector<double> > dist(N, vector<double>(N));
    for (int i = (int)(0); i < (int)(N); i++) {
      cin >> stars[i].x >> stars[i].y >> stars[i].a >> stars[i].r;
    }
    for (int i = (int)(0); i < (int)(N); i++)
      for (int j = (int)(0); j < (int)(N); j++) {
        dist[i][j] = distance(stars[i], stars[j]);
      }
    for (int k = (int)(0); k < (int)(N); k++)
      for (int i = (int)(0); i < (int)(N); i++)
        for (int j = (int)(0); j < (int)(N); j++) {
          dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
        }
    printf("%.20lf\n", dist[L - 1][M - 1]);
  }
  return 0;
}
