#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstdio>
using namespace std;
#define MAX 50
#define INF (1<<28)
#define EPS (1e-8)
struct edge{ int to,cost,l; };
struct state{
  int pos,prev,v;
  double cost;
  bool operator < (const state& p)const{return cost > p.cost;}
};

int n,m,si,ti;
vector<edge> G[MAX];
double d[MAX][MAX][MAX];

void init(){
  for(int i=0;i<MAX;i++){
    G[i].clear();
    for(int j=0;j<MAX;j++)
      for(int k=0;k<MAX;k++)
	d[i][j][k]=INF;
  }
}
void solve(){
  priority_queue<state> Q;
  Q.push((state){si,n,0,0});
  d[si][n][0]=0;
  while(!Q.empty()){
    state s=Q.top();Q.pop();
    if(s.pos==ti&&s.v==1){printf("%.8f\n",s.cost);return;}
    if(s.cost>EPS+d[s.pos][s.prev][s.v])continue;
    for(int i=0;i<(int)G[s.pos].size();i++){
      edge e=G[s.pos][i];
      if(e.to==s.prev)continue;
      for(int j=-1;j<=1;j++){
	int nv=s.v+j;
	if(nv<=0||e.l<nv)continue;
	double ncost=s.cost+(double)e.cost/nv;
	if(nv<=e.l&&nv>0&&ncost<d[e.to][s.pos][nv]-EPS){
	  d[e.to][s.pos][nv]=ncost;
	  Q.push((state){e.to,s.pos,nv,ncost});
	}
      }
    }
  }
  cout<<"unreachable"<<endl;
}

int main(){
  while(1){
    cin>>n>>m;
    if(n==0&&m==0)break;
    init();
    cin>>si>>ti;
    si--,ti--;
    for(int i=0;i<m;i++){
      int a,b,c,d;
      cin>>a>>b>>c>>d;
      a--,b--;
      G[a].push_back((edge){b,c,d});
      G[b].push_back((edge){a,c,d});
    }
    solve();
 
  }
  return 0;
}