#include <bits/stdc++.h>
using namespace std;
int N, M, L;
const double EPS(1e-10);
const double PI = acos(-1.0);
template <class T>
struct point {
  T x, y;
  point() : x(0), y(0) {}
  point(const T& x, const T& y) : x(x), y(y) {}
  point operator+(const point& a) const { return point(x + a.x, y + a.y); }
  void operator+=(const point& a) {
    x += a.x;
    y += a.y;
  }
  point operator-(const point& a) const { return point(x - a.x, y - a.y); }
  void operator-=(const point& a) {
    x -= a.x;
    y -= a.y;
  }
  point operator*(const double a) const { return point(a * x, a * y); }
  point operator*=(const double a) const {
    x *= a;
    y *= a;
  }
  point operator/(const double a) const { return point(a / x, a / y); }
  point operator/=(const double a) const {
    x /= a;
    y /= a;
  }
  T abs() const { return std::sqrt(x * x + y * y); }
  T dot(const point& a) const { return x * a.x + y * a.y; }
  T cross(const point& a) const { return x * a.y - y * a.x; }
  point rot(double theta) const {
    return point(x * cos(theta) - y * sin(theta),
                 x * sin(theta) + y * cos(theta));
  }
};
template <class T>
struct segment {
  point<T> a, b;
  segment() : a(point<T>()), b(point<T>()) {}
  segment(const point<T>& a, const point<T>& b) : a(a), b(b) {}
  T abs() const { return (a - b).abs(); }
  T dist(const point<T>& c) const {
    if ((b - a).dot(c - a) < EPS) return (c - a).abs();
    if ((a - b).dot(c - b) < EPS) return (c - b).abs();
    return std::abs((b - a).cross(c - a)) / (b - a).abs();
  }
  bool intersect(const segment& c) const {
    if (max(a.x, b.x) + EPS < min(c.a.x, c.b.x) ||
        max(a.y, b.y) + EPS < min(c.a.y, c.b.y) ||
        max(c.a.x, c.b.x) + EPS < min(a.x, b.x) ||
        max(c.a.y, c.b.y) + EPS < min(a.y, b.y))
      return false;
    return ((b - a).cross(c.a - a) * (b - a).cross(c.b - a) < EPS) &&
           ((c.b - c.a).cross(a - c.a) * (c.b - c.a).cross(b - c.a) < EPS);
  }
  T dist(const segment& s) {
    if (intersect(s)) return 0;
    return min(min(dist(s.a), dist(s.b)), min(s.dist(a), s.dist(b)));
  }
};
point<double> pt[101][5];
double dp[101][101];
double get_min(int m, int n) {
  if (m == n) return 0;
  double mn = INT_MAX;
  static int idx[] = {0, 2, 4, 1, 3, 0};
  for (int i = 0; i < 5; i++) {
    segment<double> s = segment<double>(pt[n][idx[i]], pt[n][idx[i + 1]]);
    for (int j = 0; j < 5; j++) {
      segment<double> t = segment<double>(pt[m][idx[j]], pt[m][idx[j + 1]]);
      mn = min(mn, s.dist(t));
    }
  }
  return mn;
}
int main() {
  while (cin >> N >> M >> L, (N || M || L)) {
    for (int i = 0; i < N; i++) {
      double x, y, a, r;
      cin >> x >> y >> a >> r;
      for (int j = 0; j < 5; j++) {
        double alpha = (18 + a + 72 * j) / 180.0 * PI;
        pt[i][j] = point<double>(x, y) + point<double>(r, 0.0).rot(alpha);
      }
    }
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++) dp[i][j] = get_min(i, j);
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        for (int k = 0; k < N; k++)
          dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
    printf("%.20lf\n", dp[M - 1][L - 1]);
  }
  return 0;
}
