#include <iostream>
#include <algorithm>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define INF 1e9
#define rep(i,n) for(int i=0;i<n;i++)
typedef pair<double,int> P;
struct edge{int to;double cost;};

int n,m,s,go;
double d[27002];
vector<edge> g[27002];

void dijkstra(int s){
	multimap<double,int> q;
	fill(d,d+27002,INF);
	d[s]=0;
	q.insert(P(0,s));
	while(!q.empty()){
		P p=*(q.begin());
		q.erase(q.begin());
		int v=p.second;
		if(d[v]<p.first)continue;
		if(v==1)break;
		rep(i,g[v].size()){
			edge e=g[v][i];
			if(d[e.to]>d[v]+e.cost){
				d[e.to]=d[v]+e.cost;
				q.insert(P(d[e.to],e.to));
			}
		}
	}
}

int main(){
	while(cin>>n>>m&&n){
		rep(i,27002)g[i].clear();
		cin>>s>>go;s--;go--;
		edge e;
		rep(i,n){
			e.to=1;
			e.cost=0;
			g[i*n+go+2].push_back(e);
		}
		rep(i,m){
			int x,y,c;
			double dd;
			cin>>x>>y>>dd>>c;
			x--;y--;
			rep(v,c+2)rep(p,n){
				if(v==31)break;
				if(v==0){
					if(x==s){
						e.to=x*n+y+2;
						e.cost=dd;
						g[0].push_back(e);
					}
					if(y==s){
						e.to=y*n+x+2;
						e.cost=dd;
						g[0].push_back(e);
					}
				}
				else{
					for(int j=-1;j<2;j++){
						if(v+j>0&&v+j<=c&&p!=x&&p!=y){
							e.to=(v+j-1)*n*n+x*n+y+2;
							e.cost=dd/(v+j);
							g[(v-1)*n*n+p*n+x+2].push_back(e);
							e.to=(v+j-1)*n*n+y*n+x+2;
							g[(v-1)*n*n+p*n+y+2].push_back(e);
						}
					}
				}
			}
		}
		dijkstra(0);
		if(d[1]<INF)cout<<d[1]<<endl;
		else cout<<"unreachable"<<endl;
	}
}