#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
inline int toInt(string s){int v;istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x){ostringstream sout;sout<<x;return sout.str();}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int,int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EACH(t,i,c) for(t::iterator i=(c).begin();i!=(c).end();++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
const double EPS=1e-10;
const double PI=acos(-1.0);
#include <complex>

typedef complex<double> P;

double x[100],y[100],a[100],r[100];

double toRad(int deg){
	return (double)deg*2*PI/360;
}

P getCoord(int i,int j){
	double xx=x[i]+r[i]*cos(toRad(90+a[i]+72*j));
	double yy=y[i]+r[i]*sin(toRad(90+a[i]+72*j));
	return P(xx,yy);
}

double getDist(const P &left, const P &right){
	return sqrt(pow(left.real()-right.real(),2)+pow(left.imag()-right.imag(),2));
}

struct node{
	int n;
	double cost;
	node(int n,double cost):n(n),cost(cost){}
	bool operator<(const node &other)const{
		return cost>other.cost;
	}
};
const int MAX=INT_MAX/10;

typedef vector<double> vd;
typedef vector<vd> vvd;

double cross(P a,P b){
	return (a.real()*b.imag()-a.imag()*b.real());
}
#define EQ(a,b) (abs((a)-(b))<EPS)
bool crossing(P a1,P a2,P b1,P b2){
	if(EQ(cross(a1-a2,b1-b2),0,0))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);
	//return (getDist(a,c)+getDist(c,b)<getDist(a,b)+EPS);
}

int main(){
	int N,M,L;
	while(cin>>N>>M>>L,N){
		REP(i,N){
			cin>>x[i]>>y[i]>>a[i]>>r[i];
		}
		/*
		REP(i,N)REP(j,5){
			cout<<getCoord(i,j).x<<","<<getCoord(i,j).y<<endl;
		}
		*/
		vvd dist(N,vd(N,MAX));
		REP(i,N){
			REP(j,5){
				REP(k,N){
					bool flag=false;
					REP(l,5){
						P left=getCoord(i,j);
						P left2=getCoord(i,(j+2)%5);
						P right=getCoord(k,l);
						P right2=getCoord(k,(l+2)%5);
						if(crossing(left,left2,right,right2)){
							flag=true;
							dist[i][k]=0;
						}
						if(!flag){
							dist[i][k]=min(dist[i][k],getDist(left,right));
						}
					}
				}
			}
		}

		vd cost(N,MAX);

		priority_queue<node> q;
		REP(i,5){
			q.push(node(M-1,0));
			cost[M-1]=0;
		}
		while(!q.empty()){
			node n=q.top();
			q.pop();
			if(n.cost>cost[n.n])continue;

			REP(i,N){
				if(dist[n.n][i]<MAX){
					double dd=cost[n.n]+dist[n.n][i];
					if(cost[i]>dd){
						cost[i]=dd;
						q.push(node(i,dd));
					}
				}
			}
		}

		printf("%.10f\n", cost[L-1]);
	}
}