#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double R;//double long double ??????????????? cmath?????¢??°??????????????????????????????????????????????????§????????????
typedef complex<R> Point;
typedef pair<Point , Point> Line;
typedef pair<Point ,R > Circle;
typedef vector<Point> Poly;

#define EPS (1e-10)//??????
#define EQ(a,b) (abs((a)-(b)) < EPS)//??????????????°???????????????
#define EQV(a,b) ( EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()) )//????????????????????????????????????
#define ft first
#define sd second
#define pb push_back
int dy[]={0, 0, 1, -1, 0};
int dx[]={1, -1, 0, 0, 0};

#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define REP(i,n) for (int i=0;i<(n);i++)
#define RREP(i,n) for (int i=(n)-1;i>=0;i--)

R dot(Point a,Point b){
    return (a.real() * b.real() + a.imag() * b.imag());
}
R cross(Point a,Point b){
    return (a.real() * b.imag() - a.imag() * b.real());
}

bool is_orthogonal(Line a,Line b){//2??´????????´?????????
    return EQ(dot(a.ft - a.sd,b.ft - b.sd),0.0);
}
bool is_parallel(Line a,Line b){//2??´??????????????????
    return EQ(cross(a.ft - a.sd,b.ft - b.sd),0.0);
}

////////////////////????????????

int ccw(Point a,Point b,Point c){//ok
    b -= a; c -= a;
    if(cross(b,c) > EPS) return 1;//a???b??§???????¨???¨???????????????b???c
    if(cross(b,c) < -EPS) return -1;//a???b??§????¨???¨???????????????b???c
    if(dot(b,c) < -EPS) return 2;//c--a--b on same line
    if(norm(c) - norm(b) > EPS) return -2;//a--b--c(abs??????????????????????????????????????????????????????????)
    return 0;//a--c--b?????????b==c
}

bool is_intersection_ll(Line l,Line m){//???????????´??????????????????
    return abs(cross(l.sd - l.ft,m.sd - m.ft)) > EPS || //????????§??????
        abs(cross(l.sd - l.ft,m.ft - l.ft)) < EPS; //?????????????????????
}

bool is_intersection_ls(Line l,Line s){//??´???l??¨??????s???????????????
    return cross(l.sd - l.ft, s.ft-l.ft)*       // s[0] is left of l
        cross(l.sd - l.ft, s.sd - l.ft) < EPS; // s[1] is right of l
}

bool is_intersection_lp(Line l,Point p){//??´???l??¨???p???????????????
    return abs(cross(l.sd - p,l.ft - p));
}

bool is_intersection_ss(Line a,Line b){//??????????????????????????????ok
    return ccw(a.ft,a.sd,b.ft)*ccw(a.ft,a.sd,b.sd) <= 0 && ccw(b.ft,b.sd,a.ft)*ccw(b.ft,b.sd,a.sd) <= 0;
}

bool is_intersection_sp(Line s,Point p){//????????¨?????????????????? ????§??????????????????¨
    return abs(s.ft - p) + abs(s.sd - p) - abs(s.ft - s.sd) < EPS;
}

/////////////?????¢

R dis_lp(Line l,Point p){//??´???l??¨???p????????¢
    return abs(cross(l.sd - l.ft,p - l.ft)) / abs(l.sd - l.ft);
}

R dis_ll(Line l,Line m){//???????????´???????????¢
    return is_intersection_ll(l,m) ? 0.0 : dis_lp(l,m.ft);
}

R dis_ls(Line l,Line s){//??´???l??¨??????s????????¢
    if(is_intersection_ls(l,s)) return 0.0;
    return min(dis_lp(l,s.ft),dis_lp(l,s.sd));
}

R dis_sp(Line s,Point p){//??????s??¨???p????????¢
    if(dot(s.sd - s.ft,p - s.ft) < EPS) return abs(p - s.ft);
    if(dot(s.ft - s.sd,p - s.sd) < EPS) return abs(p - s.sd);
    return dis_lp(s,p);
}

R dis_ss(Line s,Line t){//???????????????????????¢
    if(is_intersection_ss(s,t)) return 0.0;
    return min(min(dis_sp(s,t.ft),dis_sp(s,t.sd)),
            min(dis_sp(t,s.ft),dis_sp(t,s.sd)));
}

//////////////?°???±??¨????°?

Point projection(Line l,Point p){//?°???±????±???????
    R t = dot(p - l.ft,l.ft - l.sd) / norm(l.ft - l.sd);
    return l.ft + t * (l.ft - l.sd);
}

Point reflection(Line l,Point p){//????°?????±???????
    return p + 2.0 * (projection(l,p) - p);
}

//////////////??????(????????????????¨???????????????¨??????????????????????????????????????£??????)

Point intersection_ll(Line l,Line m){//????????????????????????????????????????????????
    R A = cross(l.sd - l.ft,m.sd - m.ft);
    R B = cross(l.sd - l.ft,l.sd - m.ft);
    if(abs(A) < EPS && abs(B) < EPS) return m.ft;//?????????
    //if(abs(A) < EPS)assert(false);//????????§????????????
    return m.ft + B / A * (m.sd - m.ft);
}

Line intersection_of_two_circles(Circle c1,Circle c2){//ok ????????????????????????Line?????\????????????(r1 + r2 > sqrt((x1 - x2) ^ 2 + (y1 - y2) ^ 2))???????????????????????????
    R a =  abs(c2.ft - c1.ft);
    R b = c1.sd;
    R c = c2.sd;

    R rc = (a  * a + b * b - c * c) / (2.0 * a);
    R rs = sqrt(b * b - rc * rc);//C++ ??§???????????????????????????????????§???????????????sqrt ????????? float ?????????????????? long double ????????????????????????????????????????????¨?????§???????????? C ????????°????????§??????sqrt ????????? double ??????????????£??????????????????
    Point diff = (c2.ft - c1.ft) / a;

    Line p ;
    p.ft = c1.ft + diff * rc + diff * Point(0,1) * rs;
    p.sd = c1.ft + diff * rc + diff * Point(0,-1) * rs;

    return p;
}



/////////////////////////polygon

#define currP(P,i) P[i]//????????????
#define nextP(P,i) P[(i + 1)%P.size()]//?¬??????????

int is_contains_p_in_Poly(Poly po,Point p){//??????????§???¢????????¨(1)????¢????(-1)????????¨(0)??????????????????????????????
    bool in = false;
    REP(i,po.size()){
        Point a = currP(po,i) - p,b = nextP(po,i) - p;
        if(a.imag() > b.imag())swap(a,b);
        if(a.imag() < EPS && -EPS < b.imag())
            if(cross(a,b) < -EPS) in = !in;
        if(abs(cross(a,b)) == 0.0 && dot(a,b) < EPS)return  -1;
    }
    return in;
}

R area2(Poly po){//????§???¢?????¢????????????????±???????
    R A = 0.0;
    REP(i,po.size())
        A += cross(currP(po,i),nextP(po, i));
    return A;
}

///////////////////////////???

Poly convex_hull(Poly ps){
    int n = ps.size(),k = 0;
    Poly ch(2*n);
    for(int i = 0;i < n;ch[k++] = ps[i++])// lower-hull
        while(k >= 2 && ccw(ch[k - 2],ch[k - 1],ps[i]) <= 0) --k;
    for(int i = n - 2,t = k + 1;i >= 0;ch[k++] = ps[i--])//upper-hull
        while(k >= t && ccw(ch[k - 2],ch[k - 1],ps[i]) <= 0) --k;
    ch.resize(k - 1);
    return ch;
}

#define prevP(P, i) P[(i+P.size()-1) % P.size()]
bool isconvex(Poly P){
    for(int i = 0;i < P.size();++i)
        if(ccw(prevP(P,i),currP(P,i),nextP(P,i)) > 0) return false;
    return true;
}

Poly rotate_poly(Poly po,Point c,R a){//???????¨???????
    REP(i,po.size()){
        po[i] = Point(po[i].real() - c.real(),po[i].imag() - c.imag());
        po[i] = po[i] * Point(cos(a),sin(a));
        po[i] = Point(po[i].real() + c.real(),po[i].imag() + c.imag());
    }
    return po;
}

R convert_deg_to_rad(R deg){
    return deg / 180.0 * M_PI;
}

int N, M, L;
Poly star[100];

bool input() {
  cin>>N>>M>>L;
  R x, y, a, r;
  REP(i, N) {
    star[i].clear();
    cin>>x>>y>>a>>r;
    R ar = convert_deg_to_rad(a+90.0);
    REP(j,5) {
      star[i].pb(Point(x, y)+r*Point(cos(ar), sin(ar)));
      ar += convert_deg_to_rad(72.0);
    }
  }
  return N!=0;
}

#define INF 1000000000.0
R G[100][100];

void solve() {
  fill((R *)G, (R *)G+10000, INF);
  REP(i,N) {
    G[i][i] = 0.0;
  }

  R dis;
  REP(i, N) {
    FOR(j, i+1, N) {
      dis = INF;
      REP(k, 5) {
        REP(l, 5) {
          dis = min(dis,dis_ss(Line(star[i][k],star[i][(k + 2) % 5]), Line(star[j][l], star[j][(l+2)%5])) );
        }
      }
      G[i][j] = dis;
      G[j][i] = dis;
      //cout<<i<<','<<j<<':'<<dis<<endl;
    }
  }
  REP(k,N){
    REP(i,N){
      REP(j,N){
        G[i][j] = min(G[i][j],G[i][k] + G[k][j]);
      }
    }
  }
  printf("%0.10lf\n",G[M-1][L-1]);
  //cout<<showpoint<<G[M-1][L-1]<<endl;
}

int main() {
  while(input()) {
    /*REP(i, N) {
      REP(j, 5) {
        cout<<star[i][j]<<' ';
      }
      cout<<endl;
    }*/
    solve();
  }
  return 0;
}

Measured memory_bytes: 3568