#include <bits/stdc++.h>
typedef struct {
  int node;
  double t;
} QUE;
QUE que[10000];
int qsize;
void min_heapify(int i) {
  int l, r, min;
  QUE qt;
  l = ((i) << 1), r = (((i) << 1) + 1);
  if (l < qsize && que[l].t < que[i].t)
    min = l;
  else
    min = i;
  if (r < qsize && que[r].t < que[min].t) min = r;
  if (min != i) {
    qt = que[i], que[i] = que[min], que[min] = qt;
    min_heapify(min);
  }
}
void deq() {
  que[0] = que[--qsize];
  min_heapify(0);
}
void enq(int n, double t) {
  int i, min;
  QUE qt;
  i = qsize++;
  que[i].node = n, que[i].t = t;
  while (i > 0 && que[min = ((i) >> 1)].t > que[i].t) {
    qt = que[i], que[i] = que[min], que[min] = qt;
    i = min;
  }
}
int ppOnSeg(double x, double y, double x1, double y1, double x2, double y2) {
  double d;
  if (x1 > x2) d = x1, x1 = x2, x2 = d;
  if (y1 > y2) d = y1, y1 = y2, y2 = d;
  return ((fabs(x1 - x) <= 1e-9) || x1 <= x) &&
         ((fabs(x - x2) <= 1e-9) || x <= x2) &&
         ((fabs(y1 - y) <= 1e-9) || y1 <= y) &&
         ((fabs(y - y2) <= 1e-9) || y <= y2) &&
         (fabs((y - y1) * (x2 - x1) - (y2 - y1) * (x - x1)) <= 1e-9);
}
int isCrossSeg(double x11, double y11, double x12, double y12, double x21,
               double y21, double x22, double y22) {
  double s11, s12, s21, s22;
  int r = 0;
  s11 = (x22 - x21) * (y11 - y21) + (y22 - y21) * (x21 - x11);
  s12 = (x22 - x21) * (y12 - y21) + (y22 - y21) * (x21 - x12);
  s21 = (x12 - x11) * (y21 - y11) + (y12 - y11) * (x11 - x21);
  s22 = (x12 - x11) * (y22 - y11) + (y12 - y11) * (x11 - x22);
  if ((fabs(s11 - 0) <= 1e-9)) {
    if (!r) r = ppOnSeg(x11, y11, x21, y21, x22, y22);
  }
  if ((fabs(s12 - 0) <= 1e-9)) {
    if (!r) r = ppOnSeg(x12, y12, x21, y21, x22, y22);
  }
  if ((fabs(s21 - 0) <= 1e-9)) {
    if (!r) r = ppOnSeg(x21, y21, x11, y11, x12, y12);
  }
  if ((fabs(s22 - 0) <= 1e-9)) {
    if (!r) r = ppOnSeg(x22, y22, x11, y11, x12, y12);
  }
  if (!r)
    r = ((s11 <= 0 && s12 >= 0) || (s11 >= 0 && s12 <= 0)) &&
        ((s21 <= 0 && s22 >= 0) || (s21 >= 0 && s22 <= 0));
  return r;
}
double pp2pp(double x1, double y1, double x2, double y2) {
  return hypot(x2 - x1, y2 - y1);
}
double pp2line(double x, double y, double sx, double sy, double ex, double ey,
               int *on) {
  double us, ub;
  double xx, yy;
  us = (x - sx) * (ex - sx) + (y - sy) * (ey - sy);
  ub = (ex - sx) * (ex - sx) + (ey - sy) * (ey - sy);
  *on = ((fabs(us - 0) <= 1e-9) || us >= 0) &&
        ((fabs(us - ub) <= 1e-9) || us <= ub);
  if ((fabs(us - 0) <= 1e-9))
    xx = (double)sx, yy = (double)sy;
  else if ((fabs(us - ub) <= 1e-9))
    xx = (double)ex, yy = (double)ey;
  else {
    xx = sx + (ex - sx) * (double)us / (double)ub;
    yy = sy + (ey - sy) * (double)us / (double)ub;
  }
  return hypot(x - xx, y - yy);
}
double distSeg2Seg(double x11, double y11, double x12, double y12, double x21,
                   double y21, double x22, double y22) {
  int on;
  double t, d = 1e10;
  if (isCrossSeg(x11, y11, x12, y12, x21, y21, x22, y22)) return 0;
  t = pp2line(x11, y11, x21, y21, x22, y22, &on);
  if (on && t < d) d = t;
  t = pp2line(x12, y12, x21, y21, x22, y22, &on);
  if (on && t < d) d = t;
  t = pp2line(x21, y21, x11, y11, x12, y12, &on);
  if (on && t < d) d = t;
  t = pp2line(x22, y22, x11, y11, x12, y12, &on);
  if (on && t < d) d = t;
  t = pp2pp(x11, y11, x21, y21);
  if (t < d) d = t;
  t = pp2pp(x11, y11, x22, y22);
  if (t < d) d = t;
  t = pp2pp(x12, y12, x21, y21);
  if (t < d) d = t;
  t = pp2pp(x12, y12, x22, y22);
  if (t < d) d = t;
  return d;
}
typedef struct {
  double x[5], y[5];
} T;
T tbl[101];
int N;
double dist[101][101];
char visited[101];
double dijkstra(int start, int goal) {
  int i, s;
  double d;
  qsize = 0;
  memset(visited, 0, sizeof(visited));
  enq(start, 0);
  while (qsize) {
    s = que[0].node, d = que[0].t;
    deq();
    if (s == goal) return d;
    if (visited[s]) continue;
    visited[s] = 1;
    for (i = 0; i < N; i++) {
      if (dist[s][i] == 0) continue;
      enq(i, d + dist[s][i]);
    }
  }
  return 1e10;
}
void calcPos(int i, int x0, int y0, int a, int r) {
  int j;
  for (a += 90, j = 0; j < 5; j++, a += 72) {
    tbl[i].x[j] = x0 + r * cos(a * 0.01745329251994329576923690768489);
    tbl[i].y[j] = y0 + r * sin(a * 0.01745329251994329576923690768489);
  }
}
void calcDist() {
  int i, j, ii, jj;
  double d, x;
  T *p, *q;
  memset(dist, 0x55, sizeof(dist));
  for (i = 0; i < N; i++) dist[i][i] = 0;
  for (p = tbl, ii = 0; ii < N; ii++, p++)
    for (q = tbl + ii + 1, jj = ii + 1; jj < N; jj++, q++) {
      d = 1e10;
      for (i = 0; i < 5; i++)
        for (j = 0; j < 5; j++) {
          x = distSeg2Seg(p->x[i], p->y[i], p->x[(i + 2) % 5],
                          p->y[(i + 2) % 5], q->x[j], q->y[j],
                          q->x[(j + 2) % 5], q->y[(j + 2) % 5]);
          if (x < d) d = x;
          if ((fabs(d - 0) <= 1e-9)) goto done;
        }
    done:
      dist[ii][jj] = dist[jj][ii] = d;
    }
}
int main() {
  int M, L, i, x, y, a, r;
  while (scanf("%d%d%d", &N, &M, &L) && N > 0) {
    M--, L--;
    for (i = 0; i < N; i++) {
      scanf("%d%d%d%d", &x, &y, &a, &r);
      calcPos(i, x, y, a, r);
    }
    if (M == L) {
      puts("0.00000000000000000000");
      continue;
    }
    calcDist();
    printf("%.20lf\n", dijkstra(M, L));
  }
  return 0;
}
