### BUGGY CODE ###

import sys
input = sys.stdin.readline
n, m, s, t = map(int,input().split())
C = [list(map(int,input().split())) for i in range(m)]
 
s -= 1
t -= 1
 
# O((V + E)log(V))
# Cは [[スタート頂点, ゴール頂点, 重み], ...] のリスト
 
# M = [[] for i in range(n)]
# for i in range(len(C)):
#     M[C[i][0]-1].append([C[i][1]-1, C[i][2]])  # 無向グラフなら両方追加
#     M[C[i][1]-1].append([C[i][0]-1, C[i][2]])  # 無向グラフなら両方追加
 
# N = [[] for i in range(n)]
# for i in range(len(C)):
#     N[C[i][0]-1].append([C[i][1]-1, C[i][3]])  # 無向グラフなら両方追加
#     N[C[i][1]-1].append([C[i][0]-1, C[i][3]])  # 無向グラフなら両方追加
 
M = [[] for i in range(n)]
for i in range(len(C)):
    M[C[i][0]-1].append([C[i][1]-1, C[i][2], C[i][3]])  # 無向グラフなら両方追加
    M[C[i][1]-1].append([C[i][0]-1, C[i][2], C[i][3]])  # 無向グラフなら両方追加
 
import heapq
 
def dijkstra(a, in_connect_list, v, money_kind): 
    out_shortest_list = [10**15 for i in range(v)]
    out_shortest_list[a] = 0
    searching_list = [0] * v
    searching_list[a] = 1
    
    while sum(searching_list) > 0:
        for ii in searching_list:
            i = searching_list[ii]
            if i == 1:
                searching_list[ii] = 0
                for j in in_connect_list[i]:
                    c = j[0]
                    p = j[money_kind] 
                    if out_shortest_list[c] > p + out_shortest_list[i]:
                        out_shortest_list[c] = p + out_shortest_list[i]
                        searching_list[c] = 1
    return out_shortest_list
 
# Ds, _ = dijkstra(s, M)
# Dt, _ = dijkstra(t, N)
 
Ds = dijkstra(s, M, n, 1)
Dt = dijkstra(t, M, n, 2)
 
ANS = [0] * n
 
# print(Ds,Dt)
 
ans = 10**16
for i in range(n-1, -1, -1):
    ans = min(ans, Ds[i] + Dt[i])
    ANS[i] = ans
 
for i in range(n):
    print(10**15 - ANS[i])

### FIXED CODE ###

import sys
input = sys.stdin.readline
n, m, s, t = map(int,input().split())
C = [list(map(int,input().split())) for i in range(m)]

s -= 1
t -= 1

# O((V + E)log(V))
# Cは [[スタート頂点, ゴール頂点, 重み], ...] のリスト

M = [[] for i in range(n)]
for i in range(len(C)):
    M[C[i][0]-1].append([C[i][1]-1, C[i][2]])  # 無向グラフなら両方追加
    M[C[i][1]-1].append([C[i][0]-1, C[i][2]])  # 無向グラフなら両方追加

N = [[] for i in range(n)]
for i in range(len(C)):
    N[C[i][0]-1].append([C[i][1]-1, C[i][3]])  # 無向グラフなら両方追加
    N[C[i][1]-1].append([C[i][0]-1, C[i][3]])  # 無向グラフなら両方追加

import heapq

def dijkstra(s, M):
    D = [10**16] * n  # 頂点0からの距離
    P = [-1] * n  # 頂点0からの最短距離において、そこの直前の頂点(経路復元に利用)
    D[s] = 0
    V = [0] * n  # その頂点のD[i]が最短距離と確定したら1
    Q = []  # 優先度付きキュー
    for v in range(n):
        heapq.heappush(Q, [D[v], v])

    le = len(Q)
    while le > 0:
        q = heapq.heappop(Q)
        u = q[1]
        du = q[0]
        if V[u] == 0:
            V[u] = 1
            le -= 1
            for i in range(len(M[u])):
                v = M[u][i][0]
                luv = M[u][i][1]
                if V[v] == 0:
                    alt = du + luv
                    if D[v] > alt:
                        D[v] = alt
                        P[v] = u
                        heapq.heappush(Q, [alt, v])
    return D, P

Ds, _ = dijkstra(s, M)
Dt, _ = dijkstra(t, N)

ANS = [0] * n

# print(Ds,Dt)

ans = 10**16
for i in range(n-1, -1, -1):
    ans = min(ans, Ds[i] + Dt[i])
    ANS[i] = ans

for i in range(n):
    print(10**15 - ANS[i])