#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;
const double PI = acos(-1);
typedef struct Point {
  double x, y;
  Point(double x_, double y_) : x(x_), y(y_) {}
  Point operator+(const Point& a) const { return Point(x + a.x, y + a.y); }
  Point operator-(const Point& a) const { return Point(x - a.x, y - a.y); }
} Vector;
double norm(const Point& a) { return a.x * a.x + a.y * a.y; }
double abs(const Point& a) { return sqrt(norm(a)); }
double dot(const Vector& a, const Vector& b) { return a.x * b.x + a.y * b.y; }
double cross(const Vector& a, const Vector& b) { return a.x * b.y - a.y * b.x; }
double dist(const Point& a, const Point& b) { return abs(a - b); }
Point rotate(const Point& p, double s) {
  return Point(p.x * cos(s) - p.y * sin(s), p.x * sin(s) + p.y * cos(s));
}
int ccw(const Point& _a, const Point& _b, const Point& _c) {
  Vector ba = _b - _a, ca = _c - _a;
  if (cross(ba, ca) > EPS) return +1;
  if (cross(ba, ca) < -EPS) return -1;
  if (dot(ba, ca) < -EPS) return +2;
  if (abs(ba) + EPS < abs(ca)) return -2;
  return 0;
}
typedef struct Line {
  Point s, e;
  Line(Point s_, Point e_) : s(s_), e(e_) {}
} Segment;
bool is_cross(const Segment& _a, const Segment& _b) {
  return (ccw(_a.s, _a.e, _b.s) * ccw(_a.s, _a.e, _b.e) <= 0 &&
          ccw(_b.s, _b.e, _a.s) * ccw(_b.s, _b.e, _a.e) <= 0);
}
double dist_point_line(const Point& p, const Line& l) {
  return fabs(cross(p - l.s, l.e - l.s)) / abs(l.e - l.s);
}
double dist_point_seg(const Point& p, const Segment& s) {
  if (dot(s.e - s.s, p - s.s) < EPS) return abs(p - s.s);
  if (dot(s.s - s.e, p - s.e) < EPS) return abs(p - s.e);
  return dist_point_line(p, s);
}
double dist_seg_seg(const Segment& a, const Segment& b) {
  if (is_cross(a, b)) return 0.0;
  double res = dist_point_seg(b.s, a);
  res = min(res, dist_point_seg(b.e, a));
  res = min(res, dist_point_seg(a.s, b));
  res = min(res, dist_point_seg(a.e, b));
  return res;
}
struct Star {
  vector<Segment> vs;
  Star(Point c, double a, double r) {
    vector<Point> vp;
    Point uc(0, r);
    vp.push_back(rotate(uc, a * PI / 180.));
    for (int i = 0; i < 4; ++i) vp.push_back(rotate(vp[i], 0.4 * PI));
    vs.push_back(Segment(vp[0] + c, vp[2] + c));
    vs.push_back(Segment(vp[2] + c, vp[4] + c));
    vs.push_back(Segment(vp[4] + c, vp[1] + c));
    vs.push_back(Segment(vp[1] + c, vp[3] + c));
    vs.push_back(Segment(vp[3] + c, vp[0] + c));
  }
};
int N, M, L;
vector<Star> vst;
double dst[111][111];
double dist_star(const Star& a, const Star& b) {
  double res = 1e5;
  for (int i = 0; i < 5; ++i)
    for (int j = 0; j < 5; ++j)
      res = min(res, dist_point_seg(a.vs[i].s, b.vs[j]));
  for (int i = 0; i < 5; ++i)
    for (int j = 0; j < 5; ++j)
      res = min(res, dist_point_seg(b.vs[i].s, a.vs[j]));
  return res;
}
void solve() {
  for (int i = 0; i < N; ++i)
    for (int j = i + 1; j < N; ++j) {
      dst[i][j] = dst[j][i] = dist_star(vst[i], vst[j]);
    }
  for (int k = 0; k < N; ++k)
    for (int i = 0; i < N; ++i)
      for (int j = 0; j < N; ++j) {
        dst[i][j] = min(dst[i][j], dst[i][k] + dst[k][j]);
      }
  printf("%.20lf\n", dst[M - 1][L - 1]);
}
int main() {
  while (cin >> N >> M >> L, N) {
    vst.clear();
    for (int i = 0; i < N; ++i) {
      double x, y, a, r;
      scanf("%lf %lf %lf %lf", &x, &y, &a, &r);
      vst.push_back(Star(Point(x, y), a, r));
    }
    solve();
  }
  return 0;
}
