#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e+12;
const double PI = acos(-1.0);
double dot(complex<double> a, complex<double> b) { return real(conj(a) * b); }
double cross(complex<double> a, complex<double> b) { return imag(conj(a) * b); }
double to_rad(double deg) { return deg * PI / 180.0; }
complex<double> rot(complex<double> p, double a) {
  double x = p.real() * cos(a) - p.imag() * sin(a);
  double y = p.real() * sin(a) + p.imag() * cos(a);
  return complex<double>(x, y);
}
complex<double> rot2(complex<double> a, complex<double> b, double angle) {
  complex<double> p = b - a;
  return rot(p, angle) + a;
}
struct Segment {
  complex<double> a, b;
  Segment(complex<double> a_, complex<double> b_) {
    a = a_;
    b = b_;
  }
  double distance(complex<double> p) {
    if (dot(b - a, p - a) < EPS) return abs(p - a);
    if (dot(a - b, p - b) < EPS) return abs(p - b);
    return abs(cross(b - a, p - a)) / abs(b - a);
  }
  bool is_intersection(const Segment& s) {
    return (cross(b - a, s.a - a) * cross(b - a, s.b - a) < EPS &&
            cross(s.b - s.a, b - s.a) * cross(s.b - s.a, b - s.a) < EPS);
  }
  bool contain(complex<double> p) {
    return (abs(a - p) + abs(p - b) < abs(a - b) + EPS);
  }
  double distance(Segment s) {
    double A = this->distance(s.a);
    double B = this->distance(s.b);
    double C = s.distance((*this).a);
    double D = s.distance((*this).b);
    if (this->is_intersection(s)) {
      double d1 = abs(cross(s.b - s.a, a - s.a));
      double d2 = abs(cross(s.b - s.a, b - s.a));
      if (abs(d1) < EPS && abs(d2) < EPS) {
        if (this->contain(s.a) || this->contain(s.b)) {
          return 0.0;
        } else if (s.contain(a) || s.contain(b)) {
          return 0.0;
        } else {
          return min(min(A, B), min(C, D));
        }
      }
      return 0.0;
    }
    return min(min(A, B), min(C, D));
  }
  void print() {
    printf("line(%f,%f,%f,%f);\n", a.real(), a.imag(), b.real(), b.imag());
  }
};
int main() {
  int n, m, l;
  while (scanf("%d %d %d", &n, &m, &l), n || m || l) {
    m--;
    l--;
    vector<vector<Segment> > v;
    for (int i = 0; i < n; i++) {
      int x, y, a, r;
      scanf("%d %d %d %d", &x, &y, &a, &r);
      double angle = to_rad(a + 90);
      complex<double> p1(x + r * cos(angle), y + r * sin(angle));
      complex<double> p2 = rot2(complex<double>(x, y), p1, to_rad(72));
      complex<double> p3 = rot2(complex<double>(x, y), p2, to_rad(72));
      complex<double> p4 = rot2(complex<double>(x, y), p3, to_rad(72));
      complex<double> p5 = rot2(complex<double>(x, y), p4, to_rad(72));
      vector<Segment> vs;
      vs.push_back(Segment(p1, p3));
      vs.push_back(Segment(p3, p5));
      vs.push_back(Segment(p5, p2));
      vs.push_back(Segment(p2, p4));
      vs.push_back(Segment(p4, p1));
      v.push_back(vs);
    }
    double G[101][101];
    for (int i = 0; i < 101; i++) {
      for (int j = 0; j < 101; j++) {
        G[i][j] = (i == j) ? 0 : INF;
      }
    }
    for (int i = 0; i < v.size(); i++) {
      for (int j = i + 1; j < v.size(); j++) {
        double d = INF;
        for (int k1 = 0; k1 < v[i].size(); k1++) {
          for (int k2 = 0; k2 < v[j].size(); k2++) {
            Segment s1 = v[i][k1];
            Segment s2 = v[j][k2];
            d = min(d, s1.distance(s2));
          }
        }
        G[i][j] = G[j][i] = d;
      }
    }
    for (int k = 0; k < n; k++) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
        }
      }
    }
    printf("%.8f\n", G[m][l]);
  }
}
