# -*- coding: utf-8 -*-



"""

参考：https://img.atcoder.jp/soundhound2018-summer-qual/editorial.pdf

　　　https://ikatakos.com/pot/programming_algorithm/contest_history/atcoder/2018/0707_soundhound2018_summer_qual

"""



import sys, re

from collections import deque, defaultdict, Counter

from math import sqrt, hypot, factorial, pi, sin, cos, radians, log10

if sys.version_info.minor >= 5: from math import gcd

else: from fractions import gcd 

from heapq import heappop, heappush, heapify, heappushpop

from bisect import bisect_left, bisect_right

from itertools import permutations, combinations, product, accumulate

from operator import itemgetter, mul, xor

from copy import copy, deepcopy

from functools import reduce, partial

from fractions import Fraction

from string import ascii_lowercase, ascii_uppercase, digits



def input(): return sys.stdin.readline().strip()

def list2d(a, b, c): return [[c] * b for i in range(a)]

def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]

def ceil(x, y=1): return int(-(-x // y))

def round(x): return int((x*2+1) // 2)

def fermat(x, y, MOD): return x * pow(y, MOD-2, MOD) % MOD

def lcm(x, y): return (x * y) // gcd(x, y)

def lcm_list(nums): return reduce(lcm, nums, 1)

def gcd_list(nums): return reduce(gcd, nums, nums[0])

def INT(): return int(eval(input()))

def MAP(): return list(map(int, input().split()))

def LIST(): return list(map(int, input().split()))

def Yes(): print('Yes')

def No(): print('No')

def YES(): print('YES')

def NO(): print('NO')

sys.setrecursionlimit(10 ** 9)

INF = float('inf')

MOD = 10 ** 9 + 7



# ダイクストラ(頂点数, 隣接リスト(0-indexed), 始点)

def dijkstra(N: int, nodes: list, src: int) -> list:

    # 頂点[ある始点からの最短距離]

    # (経路自体を知りたい時はここに前の頂点も持たせる)

    res = [float('inf')] * N

    # スタート位置

    que = [(0, src)]

    res[src] = 0

    # キューが空になるまで

    while len(que) != 0:

        # srcからの距離, 現在のノード

        dist, cur = heappop(que)

        # 出発ノードcurの到着ノードでループ

        for nxt, cost in nodes[cur]:

            # 今回の経路のが短い時

            if res[cur] + cost < res[nxt]:

                res[nxt] = res[cur] + cost

                # 現在の移動距離をキューの優先度として、早い方から先に処理するようにする

                heappush(que, (res[nxt], nxt))

    # ノードsrcからの最短距離リストを返却

    return res



N,M,S,T=MAP()

nodes1=[[] for i in range(N)]

nodes2=[[] for i in range(N)]

for i in range(M):

    u,v,a,b=MAP()

    # 円での始点からダイクストラ用

    nodes1[u-1].append((v-1,a))

    nodes1[v-1].append((u-1,a))

    # スヌークでの終点からダイクストラ用

    nodes2[u-1].append((v-1,b))

    nodes2[v-1].append((u-1,b))



yen=dijkstra(N,nodes1,S-1)

snuk=dijkstra(N,nodes2,T-1)



ans=[0]*N

mn=INF

# 逆順で最小値を取っていけば効率よくやれる

for i in range(N-1, -1, -1):

    ans[i]=mn=min(mn, yen[i]+snuk[i])

# 10^15から引けば答え

for i in range(N):

    print((1000000000000000-ans[i]))

# -*- coding: utf-8 -*-



import sys

from itertools import accumulate



def input(): return sys.stdin.readline().strip()

def list2d(a, b, c): return [[c] * b for i in range(a)]

def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1): return int(-(-x // y))

def INT(): return int(input())

def MAP(): return map(int, input().split())

def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes(): print('Yes')

def No(): print('No')

def YES(): print('YES')

def NO(): print('NO')

sys.setrecursionlimit(10 ** 9)

INF = float('inf')

MOD = 10 ** 9 + 7



def dijkstra(N: int, nodes: list, src: int) -> list:

    """ ダイクストラ高速化版(頂点数, 隣接リスト(0-indexed), 始点) """

    from heapq import heappush, heappop



    # 頂点[ある始点からの最短距離]

    res = [INF] * N

    # スタート位置

    que = [src]

    res[src] = 0

    # キューが空になるまで

    while len(que) != 0:

        # 距離*N + 現在のノード

        cur = heappop(que)

        # 距離とノードに分ける

        dist = cur // N

        cur %= N

        # 出発ノードcurの到着ノードでループ

        for nxt, cost in nodes[cur]:

            # 今回の経路のが短い時

            if dist + cost < res[nxt]:

                res[nxt] = dist + cost

                # 距離*N+ノード番号 の形でキューに詰める

                heappush(que, (dist+cost)*N+nxt)

    # ノードsrcからの最短距離リストを返却

    return res



N, M, s, t = MAP()

s -= 1

t -= 1

nodes1 = tuple([] for i in range(N))

nodes2 = tuple([] for i in range(N))

for i in range(M):

    u, v, a, b = MAP()

    u -= 1

    v -= 1

    nodes1[u].append((v, a))

    nodes1[v].append((u, a))

    nodes2[u].append((v, b))

    nodes2[v].append((u, b))



res1 = dijkstra(N, nodes1, s)

res2 = dijkstra(N, nodes2, t)



A = [0] * N

for i in range(N):

    # sからiまで円、iからtまでスヌークで行く

    A[i] = res1[i] + res2[i]



# 最後のが使える両替所が少ないので、後ろから累積minする

ans = list(accumulate(A[::-1], min))[::-1]

total = 10 ** 15

[print(total-a) for a in ans]

# -*- coding: utf-8 -*-
"""
参考：https://img.atcoder.jp/soundhound2018-summer-qual/editorial.pdf
　　　https://ikatakos.com/pot/programming_algorithm/contest_history/atcoder/2018/0707_soundhound2018_summer_qual
"""
import sys, re
from collections import deque, defaultdict, Counter
from math import sqrt, hypot, factorial, pi, sin, cos, radians, log10

if sys.version_info.minor >= 5:
    from math import gcd
else:
    from fractions import gcd
from heapq import heappop, heappush, heapify, heappushpop
from bisect import bisect_left, bisect_right
from itertools import permutations, combinations, product, accumulate
from operator import itemgetter, mul, xor
from copy import copy, deepcopy
from functools import reduce, partial
from fractions import Fraction
from string import ascii_lowercase, ascii_uppercase, digits


def input():
    return sys.stdin.readline().strip()


def list2d(a, b, c):
    return [[c] * b for i in range(a)]


def list3d(a, b, c, d):
    return [[[d] * c for j in range(b)] for i in range(a)]


def ceil(x, y=1):
    return int(-(-x // y))


def round(x):
    return int((x * 2 + 1) // 2)


def fermat(x, y, MOD):
    return x * pow(y, MOD - 2, MOD) % MOD


def lcm(x, y):
    return (x * y) // gcd(x, y)


def lcm_list(nums):
    return reduce(lcm, nums, 1)


def gcd_list(nums):
    return reduce(gcd, nums, nums[0])


def INT():
    return int(eval(input()))


def MAP():
    return list(map(int, input().split()))


def LIST():
    return list(map(int, input().split()))


def Yes():
    print("Yes")


def No():
    print("No")


def YES():
    print("YES")


def NO():
    print("NO")


sys.setrecursionlimit(10**9)
INF = float("inf")
MOD = 10**9 + 7
# ダイクストラ(頂点数, 隣接リスト(0-indexed), 始点)
def dijkstra(N: int, nodes: list, src: int) -> list:
    # 頂点[ある始点からの最短距離]
    # (経路自体を知りたい時はここに前の頂点も持たせる)
    res = [float("inf")] * N
    # スタート位置
    que = [(0, src)]
    res[src] = 0
    # キューが空になるまで
    while len(que) != 0:
        # srcからの距離, 現在のノード
        dist, cur = heappop(que)
        # 出発ノードcurの到着ノードでループ
        for nxt, cost in nodes[cur]:
            # 今回の経路のが短い時
            if res[cur] + cost < res[nxt]:
                res[nxt] = res[cur] + cost
                # 現在の移動距離をキューの優先度として、早い方から先に処理するようにする
                heappush(que, (res[nxt], nxt))
    # ノードsrcからの最短距離リストを返却
    return res


N, M, S, T = MAP()
nodes1 = [[] for i in range(N)]
nodes2 = [[] for i in range(N)]
for i in range(M):
    u, v, a, b = MAP()
    # 円での始点からダイクストラ用
    nodes1[u - 1].append((v - 1, a))
    nodes1[v - 1].append((u - 1, a))
    # スヌークでの終点からダイクストラ用
    nodes2[u - 1].append((v - 1, b))
    nodes2[v - 1].append((u - 1, b))
yen = dijkstra(N, nodes1, S - 1)
snuk = dijkstra(N, nodes2, T - 1)
ans = [0] * N
mn = INF
# 逆順で最小値を取っていけば効率よくやれる
for i in range(N - 1, -1, -1):
    ans[i] = mn = min(mn, yen[i] + snuk[i])
# 10^15から引けば答え
for i in range(N):
    print((1000000000000000 - ans[i]))

# -*- coding: utf-8 -*-
import sys
from itertools import accumulate


def input():
    return sys.stdin.readline().strip()


def list2d(a, b, c):
    return [[c] * b for i in range(a)]


def list3d(a, b, c, d):
    return [[[d] * c for j in range(b)] for i in range(a)]


def list4d(a, b, c, d, e):
    return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]


def ceil(x, y=1):
    return int(-(-x // y))


def INT():
    return int(input())


def MAP():
    return map(int, input().split())


def LIST(N=None):
    return list(MAP()) if N is None else [INT() for i in range(N)]


def Yes():
    print("Yes")


def No():
    print("No")


def YES():
    print("YES")


def NO():
    print("NO")


sys.setrecursionlimit(10**9)
INF = float("inf")
MOD = 10**9 + 7


def dijkstra(N: int, nodes: list, src: int) -> list:
    """ダイクストラ高速化版(頂点数, 隣接リスト(0-indexed), 始点)"""
    from heapq import heappush, heappop

    # 頂点[ある始点からの最短距離]
    res = [INF] * N
    # スタート位置
    que = [src]
    res[src] = 0
    # キューが空になるまで
    while len(que) != 0:
        # 距離*N + 現在のノード
        cur = heappop(que)
        # 距離とノードに分ける
        dist = cur // N
        cur %= N
        # 出発ノードcurの到着ノードでループ
        for nxt, cost in nodes[cur]:
            # 今回の経路のが短い時
            if dist + cost < res[nxt]:
                res[nxt] = dist + cost
                # 距離*N+ノード番号 の形でキューに詰める
                heappush(que, (dist + cost) * N + nxt)
    # ノードsrcからの最短距離リストを返却
    return res


N, M, s, t = MAP()
s -= 1
t -= 1
nodes1 = tuple([] for i in range(N))
nodes2 = tuple([] for i in range(N))
for i in range(M):
    u, v, a, b = MAP()
    u -= 1
    v -= 1
    nodes1[u].append((v, a))
    nodes1[v].append((u, a))
    nodes2[u].append((v, b))
    nodes2[v].append((u, b))
res1 = dijkstra(N, nodes1, s)
res2 = dijkstra(N, nodes2, t)
A = [0] * N
for i in range(N):
    # sからiまで円、iからtまでスヌークで行く
    A[i] = res1[i] + res2[i]
# 最後のが使える両替所が少ないので、後ろから累積minする
ans = list(accumulate(A[::-1], min))[::-1]
total = 10**15
[print(total - a) for a in ans]

-""" -参考：https://img.atcoder.jp/soundhound2018-summer-qual/editorial.pdf -　　　https://ikatakos.com/pot/programming_algorithm/contest_history/atcoder/2018/0707_soundhound2018_summer_qual -""" -import sys, re -from collections import deque, defaultdict, Counter -from math import sqrt, hypot, factorial, pi, sin, cos, radians, log10 - -if sys.version_info.minor >= 5: -    from math import gcd -else: -    from fractions import gcd -from heapq import heappop, heappush, heapify, heappushpop -from bisect import bisect_left, bisect_right -from itertools import permutations, combinations, product, accumulate -from operator import itemgetter, mul, xor -from copy import copy, deepcopy -from functools import reduce, partial -from fractions import Fraction -from string import ascii_lowercase, ascii_uppercase, digits +import sys +from itertools import accumulate +def list4d(a, b, c, d, e): +    return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)] + + -def round(x): -    return int((x * 2 + 1) // 2) - - -def fermat(x, y, MOD): -    return x * pow(y, MOD - 2, MOD) % MOD - - -def lcm(x, y): -    return (x * y) // gcd(x, y) - - -def lcm_list(nums): -    return reduce(lcm, nums, 1) - - -def gcd_list(nums): -    return reduce(gcd, nums, nums[0]) - - -    return int(eval(input())) +    return int(input()) -    return list(map(int, input().split())) +    return map(int, input().split()) -def LIST(): -    return list(map(int, input().split())) +def LIST(N=None): +    return list(MAP()) if N is None else [INT() for i in range(N)] -# ダイクストラ(頂点数, 隣接リスト(0-indexed), 始点) + + +    """ダイクストラ高速化版(頂点数, 隣接リスト(0-indexed), 始点)""" +    from heapq import heappush, heappop + -    # (経路自体を知りたい時はここに前の頂点も持たせる) -    res = [float("inf")] * N +    res = [INF] * N -    que = [(0, src)] +    que = [src] -        # srcからの距離, 現在のノード -        dist, cur = heappop(que) +        # 距離*N + 現在のノード +        cur = heappop(que) +        # 距離とノードに分ける +        dist = cur // N +        cur %= N -            if res[cur] + cost < res[nxt]: -                res[nxt] = res[cur] + cost -                # 現在の移動距離をキューの優先度として、早い方から先に処理するようにする -                heappush(que, (res[nxt], nxt)) +            if dist + cost < res[nxt]: +                res[nxt] = dist + cost +                # 距離*N+ノード番号 の形でキューに詰める +                heappush(que, (dist + cost) * N + nxt) -N, M, S, T = MAP() -nodes1 = [[] for i in range(N)] -nodes2 = [[] for i in range(N)] +N, M, s, t = MAP() +s -= 1 +t -= 1 +nodes1 = tuple([] for i in range(N)) +nodes2 = tuple([] for i in range(N)) -    # 円での始点からダイクストラ用 -    nodes1[u - 1].append((v - 1, a)) -    nodes1[v - 1].append((u - 1, a)) -    # スヌークでの終点からダイクストラ用 -    nodes2[u - 1].append((v - 1, b)) -    nodes2[v - 1].append((u - 1, b)) -yen = dijkstra(N, nodes1, S - 1) -snuk = dijkstra(N, nodes2, T - 1) -ans = [0] * N -mn = INF -# 逆順で最小値を取っていけば効率よくやれる -for i in range(N - 1, -1, -1): -    ans[i] = mn = min(mn, yen[i] + snuk[i]) -# 10^15から引けば答え +    u -= 1 +    v -= 1 +    nodes1[u].append((v, a)) +    nodes1[v].append((u, a)) +    nodes2[u].append((v, b)) +    nodes2[v].append((u, b)) +res1 = dijkstra(N, nodes1, s) +res2 = dijkstra(N, nodes2, t) +A = [0] * N -    print((1000000000000000 - ans[i])) +    # sからiまで円、iからtまでスヌークで行く +    A[i] = res1[i] + res2[i] +# 最後のが使える両替所が少ないので、後ろから累積minする +ans = list(accumulate(A[::-1], min))[::-1] +total = 10**15 +[print(total - a) for a in ans]