Buggy python submission (verdict: Time Limit Exceeded):
MAX_SPEED = 30
while True:
    N, M = map(int, input().split())
    if not (N | M):
        break
    S, G = map(lambda x: int(x) - 1, input().split())
    edge = []
    for _ in range(M):
        x, y, d, c = map(int, input().split())
        edge.append((x - 1, y - 1, d, c))
        edge.append((y - 1, x - 1, d, c))
    INF = float('inf')
    dist = [[[INF for _ in range(N)] for _ in range(MAX_SPEED + 1)] for _ in range(N)]
    dist[S][0][S] = 0.0
    while True:
        flag = False
        for x, y, d, c in edge:
            for j in range(min(MAX_SPEED + 1, c + 2)):
                for k in range(N):
                    if k == y or (j <= c and dist[x][j][k] == INF):
                        continue
                    # print(x, y, d, c, j, k, dist[x][j][k])
                    if j > 1 and dist[y][j - 1][x] > dist[x][j][k] + d / (j - 1):
                        dist[y][j - 1][x] = dist[x][j][k] + d / (j - 1)
                        flag = True
                    if 0 < j <= c and dist[y][j][x] > dist[x][j][k] + d / j:
                        dist[y][j][x] = dist[x][j][k] + d / j
                        flag = True
                    if j < c and dist[y][j + 1][x] > dist[x][j][k] + d / (j + 1):
                        dist[y][j + 1][x] = dist[x][j][k] + d / (j + 1)
                        flag = True
        if not flag:
            break
    """
    for i in range(N):
        print(*dist[i], sep='\n')
        print()
    """
    ans = min(dist[G][1][j] for j in range(N))
    print("unreachable" if ans == INF else "{:.20f}".format(ans))

Fixed submission:
import sys
import heapq
if sys.version[0] == '2':
    range, input = xrange, raw_input
MAX_SPEED = 30
dvs = (-1, 0, 1)
while True:
    N, M = map(int, input().split())
    if not (N | M):
        break
    S, G = map(lambda x: int(x) - 1, input().split())
    edge = [[] for _ in range(N)]
    for _ in range(M):
        x, y, d, c = map(int, input().split())
        edge[x - 1].append((y - 1, d, c))
        edge[y - 1].append((x - 1, d, c))
    INF = 1e9
    dist = [[[INF for _ in range(N)] for _ in range(MAX_SPEED + 1)] for _ in range(N)]
    que = [(0.0, S, 0, S)]
    while que:
        cost, now, v, prev = heapq.heappop(que)
        if cost > dist[now][v][prev]:
            continue
        if now == G and v == 1:
            print("{:.20f}".format(cost))
            break
        dist[now][v][prev] = cost
        for x, d, c in edge[now]:
            if x == prev:
                continue
            for dv in dvs:
                nv = v + dv
                if 0 < nv <= c and dist[x][nv][now] > dist[now][v][prev] + d / nv:
                    dist[x][nv][now] = dist[now][v][prev] + d / nv
                    heapq.heappush(que, (dist[x][nv][now], x, nv, now))
    else:
        print("unreachable")

Buggy python submission (verdict: Time Limit Exceeded):
from fractions import Fraction
MAX_SPEED = 30
while True:
    N, M = map(int, input().split())
    if not (N | M):
        break
    S, G = map(lambda x: int(x) - 1, input().split())
    edge = []
    for _ in range(M):
        x, y, d, c = map(int, input().split())
        edge.append((x - 1, y - 1, d, c))
        edge.append((y - 1, x - 1, d, c))
    INF = float('inf')
    dist = [[[INF for _ in range(N)] for _ in range(MAX_SPEED + 1)] for _ in range(N)]
    dist[S][0][S] = Fraction()
    while True:
        flag = False
        for x, y, d, c in edge:
            for j in range(min(MAX_SPEED + 1, c + 2)):
                for k in range(N):
                    if k == y or (j <= c and dist[x][j][k] == INF):
                        continue
                    # print(x, y, d, c, j, k, dist[x][j][k])
                    if j > 1 and dist[y][j - 1][x] > dist[x][j][k] + Fraction(d, j - 1):
                        dist[y][j - 1][x] = dist[x][j][k] + Fraction(d, j - 1)
                        flag = True
                    if 0 < j <= c and dist[y][j][x] > dist[x][j][k] + Fraction(d, j):
                        dist[y][j][x] = dist[x][j][k] + Fraction(d, j)
                        flag = True
                    if j < c and dist[y][j + 1][x] > dist[x][j][k] + Fraction(d, j + 1):
                        dist[y][j + 1][x] = dist[x][j][k] + Fraction(d, j + 1)
                        flag = True
        if not flag:
            break
    """
    for i in range(N):
        print(*dist[i], sep='\n')
        print()
    """
    ans = min(dist[G][1][j] for j in range(N))
    print("unreachable" if ans == INF else "{:.20f}".format(float(ans)))

Fixed submission:
import sys
import heapq
if sys.version[0] == '2':
    range, input = xrange, raw_input
MAX_SPEED = 30
dvs = (-1, 0, 1)
while True:
    N, M = map(int, input().split())
    if not (N | M):
        break
    S, G = map(lambda x: int(x) - 1, input().split())
    edge = [[] for _ in range(N)]
    for _ in range(M):
        x, y, d, c = map(int, input().split())
        edge[x - 1].append((y - 1, d, c))
        edge[y - 1].append((x - 1, d, c))
    INF = 1e9
    dist = [[[INF for _ in range(N)] for _ in range(MAX_SPEED + 1)] for _ in range(N)]
    que = [(0.0, S, 0, S)]
    while que:
        cost, now, v, prev = heapq.heappop(que)
        if cost > dist[now][v][prev]:
            continue
        if now == G and v == 1:
            print("{:.20f}".format(cost))
            break
        dist[now][v][prev] = cost
        for x, d, c in edge[now]:
            if x == prev:
                continue
            for dv in dvs:
                nv = v + dv
                if 0 < nv <= c and dist[x][nv][now] > dist[now][v][prev] + d / nv:
                    dist[x][nv][now] = dist[now][v][prev] + d / nv
                    heapq.heappush(que, (dist[x][nv][now], x, nv, now))
    else:
        print("unreachable")