import sys

input = sys.stdin.readline

n, m, s, t = list(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]))
# 「C[i][0]から1を引くのを別のループでやらない」「大きい値にはinfでなく10**16を使う」

# この2つはTLEしないために必須。それでも数回に1回、TLEすることがある



import sys

input = sys.stdin.readline

n, m, s, t = list(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(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



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 = [a]

    

    while searching_list != []:

    

        new_search_list = []

        for i in searching_list:

            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]

                    new_search_list.append(j[0])

        searching_list = new_search_list

 

    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]))
import sys

input = sys.stdin.readline
n, m, s, t = list(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]))

# 「C[i][0]から1を引くのを別のループでやらない」「大きい値にはinfでなく10**16を使う」
# この2つはTLEしないために必須。それでも数回に1回、TLEすることがある
import sys

input = sys.stdin.readline
n, m, s, t = list(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(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
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 = [a]
    while searching_list != []:
        new_search_list = []
        for i in searching_list:
            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]
                    new_search_list.append(j[0])
        searching_list = new_search_list
    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]))

+# 「C[i][0]から1を引くのを別のループでやらない」「大きい値にはinfでなく10**16を使う」 +# この2つはTLEしないために必須。それでも数回に1回、TLEすることがある +# 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[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[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]])  # 無向グラフなら両方追加 - -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 +# 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 +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 = [a] +    while searching_list != []: +        new_search_list = [] +        for i in searching_list: +            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] +                    new_search_list.append(j[0]) +        searching_list = new_search_list +    return out_shortest_list -Ds, _ = dijkstra(s, M) -Dt, _ = dijkstra(t, N) +# Ds, _ = dijkstra(s, M) +# Dt, _ = dijkstra(t, N) +Ds = dijkstra(s, M, n, 1) +Dt = dijkstra(t, M, n, 2)