#include <bits/stdc++.h>
using namespace std;
double EPS = 1e-10;
double EQ(double a, double b) { return abs(a - b) < EPS; }
const double PI = atan(1.0) * 4;
int N, M, L;
double xs[101];
double ys[101];
double as[101];
double rs[101];
complex<double> starP[101][101];
pair<complex<double>, complex<double> > starEdges[101][101];
struct edge {
  int to;
  double cost;
};
vector<edge> G[10001];
complex<double> roundPoint(complex<double> p, double a) {
  return complex<double>(cos(a) * p.real() - sin(a) * p.imag(),
                         sin(a) * p.real() + cos(a) * p.imag());
}
double dot(complex<double> a, complex<double> b) {
  return (a.real() * b.real() + a.imag() * b.imag());
}
double cross(complex<double> a, complex<double> b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}
double distance_ls_p(complex<double> a, complex<double> b, complex<double> c) {
  if (dot(b - a, c - a) < EPS) return abs(c - a);
  if (dot(a - b, c - b) < EPS) return abs(c - b);
  return abs(cross(b - a, c - a)) / abs(b - a);
}
bool is_intersected_ls(complex<double> a1, complex<double> a2,
                       complex<double> b1, complex<double> b2) {
  if (abs(cross(a2 - a1, b2 - b1) < EPS)) return false;
  return (cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - a1) < EPS) &&
         (cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - b1) < EPS);
}
double d[101][101];
const double INF = (1LL << 30);
double dijkstra() {
  priority_queue<pair<double, pair<int, int> >,
                 vector<pair<double, pair<int, int> > >,
                 greater<pair<double, pair<int, int> > > >
      pq;
  for (int i = 0; i < 101; i++)
    for (int j = 0; j < 101; j++) d[i][j] = INF;
  for (int i = 0; i < 5; i++) {
    d[M][i] = 0;
    pq.push(pair<double, pair<int, int> >(0, pair<int, int>(M, i)));
  }
  while (pq.size()) {
    pair<double, pair<int, int> > p = pq.top();
    pq.pop();
    double ccost = p.first;
    int cnode = p.second.first;
    int cedge = p.second.second;
    if (!EQ(d[cnode][cedge], ccost) && d[cnode][cedge] < ccost) continue;
    for (int i = 0; i < G[cnode * 5 + cedge].size(); i++) {
      edge &e = G[cnode * 5 + cedge][i];
      int tnode = (e.to) / 5;
      int tedge = (e.to) % 5;
      if (!EQ(d[tnode][tedge], ccost + e.cost) &&
          d[tnode][tedge] > ccost + e.cost) {
        d[tnode][tedge] = ccost + e.cost;
        pq.push(pair<double, pair<int, int> >(d[tnode][tedge],
                                              pair<int, int>(tnode, tedge)));
      }
    }
  }
  double res = INF;
  for (int i = 0; i < 5; i++) {
    res = min(res, d[L][i]);
  }
  return res;
}
void solve() {
  while (cin >> N >> M >> L && (N | M | L)) {
    M--;
    L--;
    for (int i = 0; i < 10001; i++) G[i].clear();
    for (int i = 0; i < N; i++) cin >> xs[i] >> ys[i] >> as[i] >> rs[i];
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 4; j++) {
        edge e;
        e.cost = 0;
        int from = i * 5 + j;
        int to = i * 5 + (j + 1);
        e.to = to;
        G[from].push_back(e);
        e.to = from;
        G[to].push_back(e);
      }
    }
    for (int i = 0; i < N; i++) {
      complex<double> cp = complex<double>(xs[i], ys[i]);
      complex<double> up = complex<double>(xs[i], ys[i] + rs[i]);
      complex<double> base = complex<double>(0, rs[i]);
      complex<double> roundP = roundPoint(base, (1.0 * as[i] / 180) * PI);
      starP[i][0] = roundP + cp;
      for (int j = 1; j < 5; j++) {
        roundP = roundPoint(roundP, (72.0 / 180) * PI);
        starP[i][j] = roundP + cp;
      }
    }
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 5; j++) {
        starEdges[i][j] = make_pair(starP[i][j], starP[i][(j + 1) % 5]);
      }
    }
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 5; j++) {
        for (int k = 0; k < N; k++) {
          if (i == k) continue;
          for (int l = 0; l < 5; l++) {
            pair<complex<double>, complex<double> > &e1 = starEdges[i][j];
            pair<complex<double>, complex<double> > &e2 = starEdges[k][l];
            if (is_intersected_ls(e1.first, e1.second, e2.first, e2.second)) {
              int from = i * 5 + j;
              int to = k * 5 + l;
              edge e;
              e.cost = 0;
              e.to = to;
              G[from].push_back(e);
              e.to = from;
              G[to].push_back(e);
            }
            {
              double dist = distance_ls_p(e2.first, e2.second, e1.first);
              edge e;
              e.cost = dist;
              e.to = k * 5 + l;
              int from = i * 5 + j;
              int to = k * 5 + l;
              G[from].push_back(e);
              e.to = from;
              G[to].push_back(e);
            }
            {
              double dist = distance_ls_p(e2.first, e2.second, e1.second);
              edge e;
              e.cost = dist;
              e.to = k * 5 + l;
              int from = i * 5 + j;
              int to = k * 5 + l;
              G[from].push_back(e);
              e.to = from;
              G[to].push_back(e);
            }
          }
        }
      }
    }
    double res = dijkstra();
    printf("%.10f\n", res);
  }
}
int main() {
  solve();
  return 0;
}
