#include <bits/stdc++.h>
using namespace std;
struct Info {
  double x, y;
};
struct Line {
  void set(double arg_x1, double arg_y1, double arg_x2, double arg_y2) {
    x1 = arg_x1;
    y1 = arg_y1;
    x2 = arg_x2;
    y2 = arg_y2;
  }
  double x1, y1, x2, y2;
};
Info roll(double x, double y, double rad) {
  Info ret;
  ret.x = x * cos(rad) - y * sin(rad);
  ret.y = x * sin(rad) + y * cos(rad);
  return ret;
}
int func(double x1, double y1, double x2, double y2, double xp, double yp) {
  double naiseki, norm1, norm2, gaiseki;
  norm1 = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
  norm2 = sqrt((xp - x1) * (xp - x1) + (yp - y1) * (yp - y1));
  naiseki = (xp - x1) * (x2 - x1) + (yp - y1) * (y2 - y1);
  gaiseki = (x2 - x1) * (yp - y1) - (xp - x1) * (y2 - y1);
  if (gaiseki > 0.000000001) {
    return 1;
  } else if (gaiseki < -0.000000001) {
    return -1;
  }
  if (naiseki < -0.000000001) {
    return 2;
  }
  if (norm1 < norm2) {
    return -2;
  }
  return 0;
}
double calc(Info left, Info right) {
  return sqrt((left.x - right.x) * (left.x - right.x) +
              (left.y - right.y) * (left.y - right.y));
}
Info info[101][5];
int N, start, goal;
double dist[101][101];
void func() {
  double x, y, degree, r;
  Info tmp;
  for (int i = 1; i <= N; i++) {
    scanf("%lf %lf %lf %lf", &x, &y, &degree, &r);
    tmp = roll(0.0, r, degree * M_PI / 180.0);
    info[i][0].x = x + tmp.x;
    info[i][0].y = y + tmp.y;
    for (int k = 1; k <= 4; k++) {
      tmp =
          roll(info[i][k - 1].x - x, info[i][k - 1].y - y, (2.0 * M_PI / 5.0));
      info[i][k].x = x + tmp.x;
      info[i][k].y = y + tmp.y;
    }
  }
  double tmp_min, tmp_dist;
  Line left[5], right[5];
  bool isCross;
  for (int i = 1; i <= N; i++) {
    left[0].set(info[i][0].x, info[i][0].y, info[i][3].x, info[i][3].y);
    left[1].set(info[i][3].x, info[i][3].y, info[i][1].x, info[i][1].x);
    left[2].set(info[i][2].x, info[i][2].y, info[i][0].x, info[i][0].y);
    left[3].set(info[i][1].x, info[i][1].y, info[i][4].x, info[i][4].y);
    left[4].set(info[i][4].x, info[i][4].y, info[i][2].x, info[i][2].y);
    for (int k = i; k <= N; k++) {
      if (i != k) {
        tmp_min = DBL_MAX;
        right[0].set(info[k][0].x, info[k][0].y, info[k][3].x, info[k][3].y);
        right[1].set(info[k][3].x, info[k][3].y, info[k][1].x, info[k][1].x);
        right[2].set(info[k][2].x, info[k][2].y, info[k][0].x, info[k][0].y);
        right[3].set(info[k][1].x, info[k][1].y, info[k][4].x, info[k][4].y);
        right[4].set(info[k][4].x, info[k][4].y, info[k][2].x, info[k][2].y);
        isCross = false;
        for (int a = 0; a < 5; a++) {
          for (int b = 0; b < 5; b++) {
            if (func(left[a].x1, left[a].y1, left[a].x2, left[a].y2,
                     right[b].x1, right[b].y1) *
                        func(left[a].x1, left[a].y1, left[a].x2, left[a].y2,
                             right[b].x2, right[b].y2) <=
                    0 &&
                func(right[b].x1, right[b].y1, right[b].x2, right[b].y2,
                     left[a].x1, left[a].y1) *
                        func(right[b].x1, right[b].y1, right[b].x2, right[b].y2,
                             left[a].x2, left[a].y2) <=
                    0) {
              isCross = true;
              tmp_min = 0;
              break;
            }
          }
          if (isCross) break;
        }
        if (!isCross) {
          for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
              tmp_dist = calc(info[i][a], info[k][b]);
              tmp_min = min(tmp_min, tmp_dist);
            }
          }
        }
        dist[i][k] = tmp_min;
        dist[k][i] = tmp_min;
      } else {
        dist[i][k] = 0;
      }
    }
  }
  for (int mid = 1; mid <= N; mid++) {
    for (int st = 1; st <= N; st++) {
      for (int gl = 1; gl <= N; gl++) {
        dist[st][gl] = min(dist[st][gl], dist[st][mid] + dist[mid][gl]);
      }
    }
  }
  printf("%.20lf\n", dist[start][goal]);
}
int main() {
  while (true) {
    scanf("%d %d %d", &N, &start, &goal);
    if (N == 0 && start == 0 && goal == 0) break;
    func();
  }
  return 0;
}
