### constant

INF = Float::INFINITY
MAX_V = 30

### main

loop do
  n, m = gets.split.map(&:to_i)
  break if (n | m) == 0

  st, gl = gets.split.map{|s| s.to_i - 1}

  edges = n.times.map{[]}
  nbrs = n.times.map{[]}
  
  m.times do
    xi, yi, di, ci = gets.split.map(&:to_i)
    xi -= 1
    yi -= 1
    di = di.to_f

    edges[xi][yi] = edges[yi][xi] = [di, ci]
    nbrs[xi] << yi
    nbrs[yi] << xi
  end
  #p edges
  #p nbrs

  times = n.times.map{n.times.map{(MAX_V + 1).times.map{INF}}}
  times[st][st][0] = 0.0

  q = [[st, st, 0]]
  min_t = INF
  
  while ! q.empty?
    u = q.min{|a, b| times[a[0]][a[1]][a[2]] <=> times[b[0]][b[1]][b[2]]}
    q.delete(u)

    un, uf, uv = u
    ut = times[un][uf][uv]

    if un == gl && uv == 1
      min_t = ut if min_t > ut
      next
    end

    for vn in nbrs[un]
      next if vn == uf

      vd, vc = edges[un][vn]
      next if uv - 1 > vc
      
      for vv in [uv - 1, uv, uv + 1]
        next if vv <= 0 || vv > vc
        dt = vd / vv
        vt = times[vn][un][vv]
        nvt = ut + dt
        if vt > nvt
          times[vn][un][vv] = nvt
          q << [vn, un, vv] if vt >= INF
        end
      end
    end
  end

  puts (min_t >= INF ? 'unreachable' : "%.5f" % min_t)
end