#include <bits/stdc++.h>
using namespace std;
struct line : public vector<complex<double> > {
  line() { resize(2); };
  line(complex<double> a, complex<double> b) {
    push_back(a);
    push_back(b);
  }
};
struct circle {
  complex<double> p;
  double r;
  circle() : p(0, 0), r(0){};
  circle(complex<double> p, double r) : p(p), r(r) {}
};
const double EPS = 1e-10;
const double INF = 1e8;
bool eq(complex<double>, complex<double>);
double cross(complex<double>, complex<double>);
double dot(complex<double>, complex<double>);
int ccw(complex<double>, complex<double>, complex<double>);
bool parallel(line, line);
bool orthogonal(line, line);
bool intersect(line, line);
bool intersect(line, complex<double>);
bool intersect(pair<complex<double>, complex<double> >,
               pair<complex<double>, complex<double> >);
bool intersect(pair<complex<double>, complex<double> >, line);
bool intersect(pair<complex<double>, complex<double> >, complex<double>);
int intersect(circle, line);
bool intersect(circle, pair<complex<double>, complex<double> >);
bool intersect(circle, circle);
bool intersect(circle, complex<double>);
double distancion(line, line);
double distance(line, complex<double>);
double distance(complex<double>, complex<double>);
double distance(pair<complex<double>, complex<double> >, complex<double>);
double distance(pair<complex<double>, complex<double> >,
                pair<complex<double>, complex<double> >);
double distance(pair<complex<double>, complex<double> >, line);
complex<double> crosspoint(line, line);
line crosspoint(circle, pair<complex<double>, complex<double> >);
line crosspoint(circle, line);
line crosspoint(circle, circle);
int contains(vector<complex<double> >, complex<double>);
bool contains(circle, complex<double>);
double area2(vector<complex<double> >);
bool isconvex(vector<complex<double> >);
vector<complex<double> > convex(vector<complex<double> >);
namespace std {
bool operator<(const complex<double>& a, const complex<double>& b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
}  // namespace std
line llcomb(pair<complex<double>, complex<double> > a) {
  line line(a.first, a.second);
  return line;
}
pair<complex<double>, complex<double> > llrcomb(line a) {
  pair<complex<double>, complex<double> > line(a[0], a[1]);
  return line;
}
bool eq(complex<double> a, complex<double> b) { return abs(a - b) < EPS; }
double cross(complex<double> a, complex<double> b) { return imag(conj(a) * b); }
double dot(complex<double> a, complex<double> b) { return real(conj(a) * b); }
complex<double> projection(line l, complex<double> p) {
  double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
  return l[0] + t * (l[0] - l[1]);
}
complex<double> reflection(line l, complex<double> p) {
  return p + 2.0 * (projection(l, p) - p);
}
int ccw(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;
}
bool intersect(line a, line b) {
  return ccw(a[0], a[1], b[0]) * ccw(a[0], a[1], b[1]) <= 0 &&
         ccw(b[0], b[1], a[0]) * ccw(b[0], b[1], a[1]) <= 0;
}
bool intersect(line a, complex<double> p) {
  return abs(a[0] - p) + abs(a[1] - p) - abs(a[1] - a[0]) < EPS;
}
bool intersect(pair<complex<double>, complex<double> > l,
               pair<complex<double>, complex<double> > m) {
  return abs(cross(l.second - l.first, m.second - m.first)) > EPS ||
         abs(cross(l.second - l.first, m.first - l.first)) < EPS;
}
bool intersect(pair<complex<double>, complex<double> > l, line s) {
  return cross(l.second - l.first, s[0] - l.first) *
             cross(l.second - l.first, s[1] - l.first) <
         EPS;
}
bool intersect(pair<complex<double>, complex<double> > l, complex<double> p) {
  return abs(cross(l.second - p, l.first - p)) < EPS;
}
bool intersect(circle c, pair<complex<double>, complex<double> > s) {
  return distance(s, c.p) <= c.r + EPS;
}
bool intersect(circle a, circle b) {
  return (norm(a.p - b.p) - (a.r + b.r) * (a.r + b.r) < EPS) &&
         (norm(a.p - b.p) - (a.r - b.r) * (a.r - b.r) > -EPS);
}
int intersect(circle c, line l) {
  if (norm(projection(l, c.p) - c.p) - c.r * c.r > EPS) return 0;
  const double d1 = abs(c.p - l[0]), d2 = abs(c.p - l[1]);
  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;
  const complex<double> h = projection(l, c.p);
  if (dot(l[0] - h, l[1] - h) < 0) return 2;
  return 0;
}
bool intersect(circle c, complex<double> p) {
  return abs(abs(p - c.p) - c.r) < EPS;
}
double distance(line s, complex<double> p) {
  complex<double> r = projection(s, p);
  if (intersect(s, r)) return abs(r - p);
  return min(abs(s[0] - p), abs(s[1] - p));
}
double distancion(line a, line b) {
  if (intersect(a, b)) return 0;
  return min(min(distance(a, b[0]), distance(a, b[1])),
             min(distance(b, a[0]), distance(b, a[1])));
}
double distance(pair<complex<double>, complex<double> > l, complex<double> p) {
  return abs(p - projection(llcomb(l), p));
}
double distance(pair<complex<double>, complex<double> > l,
                pair<complex<double>, complex<double> > m) {
  return intersect(l, m) ? 0 : distance(l, m.first);
}
double distance(pair<complex<double>, complex<double> > l, line s) {
  if (intersect(l, s)) return 0;
  return min(distance(l, s[0]), distance(l, s[1]));
}
double distance(complex<double> a, complex<double> b) { return abs(a - b); }
bool parallel(line a, line b) {
  return abs(cross(a[1] - a[0], b[1] - b[0])) < EPS;
}
bool orthogonal(line a, line b) { return dot(a[0] - a[1], b[0] - b[1]) < EPS; }
enum { OUT, ON, IN };
int contains(vector<complex<double> > Q, complex<double> p) {
  bool in = false;
  for (int i = 0; i < Q.size(); i++) {
    complex<double> a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
    if (imag(a) > imag(b)) swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b) && cross(a, b) < 0) in = !in;
    if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
  }
  return in ? IN : OUT;
}
bool contains(circle c, complex<double> p) { return abs(c.p - p) < c.r + EPS; }
double area2(vector<complex<double> > p) {
  double A = 0;
  for (int i = 0; i < p.size(); ++i) {
    A += cross(p[i], p[(i + 1) % p.size()]);
  }
  return A;
}
bool isconvex(vector<complex<double> > p) {
  for (int i = 0; i < p.size(); ++i) {
    if (ccw(p[(i + p.size() - 1) % p.size()], p[i], p[(i + 1) % p.size()]) > 0)
      return false;
  }
  return true;
}
vector<complex<double> > convex(vector<complex<double> > ps) {
  int k = 0;
  sort(ps.begin(), ps.end());
  vector<complex<double> > ch(2 * ps.size());
  for (int i = 0; i < ps.size(); ch[k++] = ps[i++]) {
    while (k >= 2 and ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
  }
  for (int i = ps.size() - 2, t = k + 1; i >= 0; ch[k++] = ps[i--]) {
    while (k >= t and ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
  }
  ch.resize(k - 1);
  return ch;
}
complex<double> crosspoint(line l, line m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS) return m[0];
  return m[0] + B / A * (m[1] - m[0]);
}
line crosspoint(circle c, pair<complex<double>, complex<double> > l) {
  const complex<double> hp = projection(llcomb(l), c.p), h = hp - c.p;
  const double d2 = norm(h);
  complex<double> v =
      sqrt(c.r * c.r - d2) * (l.second - l.first) / abs(l.second - l.first);
  return line(hp - v, hp + v);
}
line crosspoint(circle c, line l) {
  if (intersect(c, l) == 2) return crosspoint(c, llrcomb(l));
  line ret = crosspoint(c, llrcomb(l));
  if (dot(l[0] - ret[0], l[1] - ret[0]) < 0)
    ret[1] = ret[0];
  else
    ret[0] = ret[1];
  return ret;
}
line crosspoint(circle c1, circle c2) {
  double d = abs(c1.p - c2.p);
  double s = (c1.r + c2.r + d) / 2;
  double S = sqrt(s * (s - c1.r) * (s - c2.r) * (s - d));
  double h = 2 * S / d;
  complex<double> v = (c2.p - c1.p) / (abs(c2.p - c1.p));
  double m = sqrt(c1.r * c1.r - h * h);
  return line(c1.p + m * v + h * v * complex<double>(0, 1),
              c1.p + m * v - h * v * complex<double>(0, 1));
}
double Degree_to_Radian(double n) { return n * M_PI / 180.0; }
double Radian_to_Degree(double n) { return n * 180.0 / M_PI; }
struct edge {
  int to;
  double cost;
  edge(int to, double cost) : to(to), cost(cost){};
};
vector<vector<edge> > info;
vector<line> comb(int x, int y, int a, int r) {
  vector<complex<double> > hosi(5);
  for (int i = 0; i < 5; i++) {
    double theta = Degree_to_Radian(a + 72 * i);
    double nx = r * sin(theta), ny = r * cos(theta);
    hosi[i] = complex<double>(x - nx, y + ny);
  }
  vector<line> ls(5);
  for (int i = 0; i < 5; i++) {
    ls[i] = line(hosi[i * 2 % 5], hosi[(i + 1) * 2 % 5]);
  }
  return ls;
}
double dist(vector<line> a, vector<line> b) {
  double ret = INF;
  for (int i = 0; i < a.size(); i++) {
    for (int j = 0; j < b.size(); j++) {
      ret = min(ret, distancion(a[i], b[i]));
    }
  }
  return ret;
}
bool used[101];
double Dijkstra(int st, int gl) {
  priority_queue<pair<double, int>, vector<pair<double, int> >,
                 greater<pair<double, int> > >
      que;
  fill_n(used, 101, false);
  que.push(pair<double, int>(0.0, st));
  while (!que.empty()) {
    pair<double, int> p = que.top();
    que.pop();
    if (p.second == gl) return p.first;
    if (used[p.second]++) continue;
    for (int i = 0; i < info[p.second].size(); i++)
      que.push(pair<double, int>(info[p.second][i].cost + p.first,
                                 info[p.second][i].to));
  }
}
int main() {
  int n, m, l;
  vector<vector<line> > stars(101, vector<line>(5));
  while (cin >> n >> m >> l, l) {
    info.resize(n + 1);
    for (int i = 1; i <= n; i++) {
      int x, y, a, r;
      cin >> x >> y >> a >> r;
      vector<line> ret = comb(x, y, a, r);
      copy(ret.begin(), ret.end(), stars[i].begin());
    }
    for (int i = 1; i <= n; i++) {
      for (int j = n; j > i; j--) {
        double mindistance = dist(stars[i], stars[j]);
        info[i].push_back(edge(j, mindistance));
        info[j].push_back(edge(i, mindistance));
      }
    }
    cout << fixed << setprecision(10) << Dijkstra(m, l) << endl;
    info.resize(0);
  }
}
