import heapq



N, M, S, T = list(map(int, input().split()))



class Dijkstra:

    def dijkstra(self, adj, start, goal=None):



        num = N  # グラフのノード数

        dist = [float('inf') for i in range(num)]  # 始点から各頂点までの最短距離を格納する

        prev = [float('inf') for i in range(num)]  # 最短経路における，その頂点の前の頂点のIDを格納する



        dist[start] = 0

        q = []  # プライオリティキュー．各要素は，(startからある頂点vまでの仮の距離, 頂点vのID)からなるタプル

        heapq.heappush(q, (0, start))  # 始点をpush



        for i in range(num-1):

            prov_cost, src = heapq.heappop(q)  # pop



            # プライオリティキューに格納されている最短距離が，現在計算できている最短距離より大きければ，distの更新をする必要はない

            if dist[src] < prov_cost:

                continue



            # 他の頂点の探索

            for dest, cost in list(adj[src].items()):

                if dist[dest] > dist[src] + cost:

                    dist[dest] = dist[src] + cost  # distの更新

                    heapq.heappush(q, (dist[dest], dest))  # キューに新たな仮の距離の情報をpush

                    prev[dest] = src  # 前の頂点を記録



        if goal is not None:

            return self.get_path(goal, prev)

        else:

            return dist



    def get_path(self, goal, prev):

        '''

        始点startから終点goalまでの最短経路を求める

        '''

        path = [goal]  # 最短経路

        dest = goal



        # 終点から最短経路を逆順に辿る

        while prev[dest] != float('inf'):

            path.append(prev[dest])

            dest = prev[dest]



        # 経路をreverseして出力

        return list(reversed(path))



from collections import defaultdict

Ey = defaultdict(lambda: defaultdict(lambda: float("inf")))

Es = defaultdict(lambda: defaultdict(lambda: float("inf")))





E = [list(map(int, input().split())) for i in range(M)]



for e in E:

    u, v, a, b = e

    Ey[u-1][v-1] = Ey[v-1][u-1] = a

    Es[u-1][v-1] = Es[v-1][u-1] = b



dj = Dijkstra()

Dy = dj.dijkstra(Ey, S-1)

Ds = dj.dijkstra(Es, T-1)

mi = float("inf")

Ans = [0] * N

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

    mi = min(mi, Dy[i]+Ds[i])

    Ans[i] = mi

for a in Ans:

    print((10**15-a))





import sys



def main():

    N, M, S, T = list(map(int, input().split()))

    A = [[] for _ in range(N+1)]

    B = [[] for _ in range(N+1)]

    for u, v, a, b in zip(*[iter(map(int, sys.stdin.read().split()))]*4):

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

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

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

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



    def dijkstra(E, start):

        from heapq import heappush, heappop

        N = len(E)

        inf = float("inf")

        dist = [inf] * N

        dist[start] = 0

        q = [(0, start)]

        while q:

            dist_v, v = heappop(q)

            if dist[v] != dist_v:

                continue

            for u, dist_vu in E[v]:

                dist_u = dist_v + dist_vu

                if dist_u < dist[u]:

                    dist[u] = dist_u

                    heappush(q, (dist_u, u))

        return dist



    dist_A = dijkstra(A, S)

    dist_B = dijkstra(B, T)

    init = 10**15

    Ans = []

    ans = float("inf")

    for a, b in zip(dist_A[:0:-1], dist_B[:0:-1]):

        ans = min(ans, a+b)

        Ans.append(init-ans)

    Ans.reverse()

    print(("\n".join(map(str, Ans))))



main()

import heapq

N, M, S, T = list(map(int, input().split()))


class Dijkstra:
    def dijkstra(self, adj, start, goal=None):
        num = N  # グラフのノード数
        dist = [float("inf") for i in range(num)]  # 始点から各頂点までの最短距離を格納する
        prev = [float("inf") for i in range(num)]  # 最短経路における，その頂点の前の頂点のIDを格納する
        dist[start] = 0
        q = []  # プライオリティキュー．各要素は，(startからある頂点vまでの仮の距離, 頂点vのID)からなるタプル
        heapq.heappush(q, (0, start))  # 始点をpush
        for i in range(num - 1):
            prov_cost, src = heapq.heappop(q)  # pop
            # プライオリティキューに格納されている最短距離が，現在計算できている最短距離より大きければ，distの更新をする必要はない
            if dist[src] < prov_cost:
                continue
            # 他の頂点の探索
            for dest, cost in list(adj[src].items()):
                if dist[dest] > dist[src] + cost:
                    dist[dest] = dist[src] + cost  # distの更新
                    heapq.heappush(q, (dist[dest], dest))  # キューに新たな仮の距離の情報をpush
                    prev[dest] = src  # 前の頂点を記録
        if goal is not None:
            return self.get_path(goal, prev)
        else:
            return dist

    def get_path(self, goal, prev):
        """
        始点startから終点goalまでの最短経路を求める
        """
        path = [goal]  # 最短経路
        dest = goal
        # 終点から最短経路を逆順に辿る
        while prev[dest] != float("inf"):
            path.append(prev[dest])
            dest = prev[dest]
        # 経路をreverseして出力
        return list(reversed(path))


from collections import defaultdict

Ey = defaultdict(lambda: defaultdict(lambda: float("inf")))
Es = defaultdict(lambda: defaultdict(lambda: float("inf")))
E = [list(map(int, input().split())) for i in range(M)]
for e in E:
    u, v, a, b = e
    Ey[u - 1][v - 1] = Ey[v - 1][u - 1] = a
    Es[u - 1][v - 1] = Es[v - 1][u - 1] = b
dj = Dijkstra()
Dy = dj.dijkstra(Ey, S - 1)
Ds = dj.dijkstra(Es, T - 1)
mi = float("inf")
Ans = [0] * N
for i in range(N - 1, -1, -1):
    mi = min(mi, Dy[i] + Ds[i])
    Ans[i] = mi
for a in Ans:
    print((10**15 - a))

import sys


def main():
    N, M, S, T = list(map(int, input().split()))
    A = [[] for _ in range(N + 1)]
    B = [[] for _ in range(N + 1)]
    for u, v, a, b in zip(*[iter(map(int, sys.stdin.read().split()))] * 4):
        A[u].append((v, a))
        A[v].append((u, a))
        B[u].append((v, b))
        B[v].append((u, b))

    def dijkstra(E, start):
        from heapq import heappush, heappop

        N = len(E)
        inf = float("inf")
        dist = [inf] * N
        dist[start] = 0
        q = [(0, start)]
        while q:
            dist_v, v = heappop(q)
            if dist[v] != dist_v:
                continue
            for u, dist_vu in E[v]:
                dist_u = dist_v + dist_vu
                if dist_u < dist[u]:
                    dist[u] = dist_u
                    heappush(q, (dist_u, u))
        return dist

    dist_A = dijkstra(A, S)
    dist_B = dijkstra(B, T)
    init = 10**15
    Ans = []
    ans = float("inf")
    for a, b in zip(dist_A[:0:-1], dist_B[:0:-1]):
        ans = min(ans, a + b)
        Ans.append(init - ans)
    Ans.reverse()
    print(("\n".join(map(str, Ans))))


main()

-import heapq - -N, M, S, T = list(map(int, input().split())) +import sys -class Dijkstra: -    def dijkstra(self, adj, start, goal=None): -        num = N  # グラフのノード数 -        dist = [float("inf") for i in range(num)]  # 始点から各頂点までの最短距離を格納する -        prev = [float("inf") for i in range(num)]  # 最短経路における，その頂点の前の頂点のIDを格納する +def main(): +    N, M, S, T = list(map(int, input().split())) +    A = [[] for _ in range(N + 1)] +    B = [[] for _ in range(N + 1)] +    for u, v, a, b in zip(*[iter(map(int, sys.stdin.read().split()))] * 4): +        A[u].append((v, a)) +        A[v].append((u, a)) +        B[u].append((v, b)) +        B[v].append((u, b)) + +    def dijkstra(E, start): +        from heapq import heappush, heappop + +        N = len(E) +        inf = float("inf") +        dist = [inf] * N -        q = []  # プライオリティキュー．各要素は，(startからある頂点vまでの仮の距離, 頂点vのID)からなるタプル -        heapq.heappush(q, (0, start))  # 始点をpush -        for i in range(num - 1): -            prov_cost, src = heapq.heappop(q)  # pop -            # プライオリティキューに格納されている最短距離が，現在計算できている最短距離より大きければ，distの更新をする必要はない -            if dist[src] < prov_cost: +        q = [(0, start)] +        while q: +            dist_v, v = heappop(q) +            if dist[v] != dist_v: -            # 他の頂点の探索 -            for dest, cost in list(adj[src].items()): -                if dist[dest] > dist[src] + cost: -                    dist[dest] = dist[src] + cost  # distの更新 -                    heapq.heappush(q, (dist[dest], dest))  # キューに新たな仮の距離の情報をpush -                    prev[dest] = src  # 前の頂点を記録 -        if goal is not None: -            return self.get_path(goal, prev) -        else: -            return dist +            for u, dist_vu in E[v]: +                dist_u = dist_v + dist_vu +                if dist_u < dist[u]: +                    dist[u] = dist_u +                    heappush(q, (dist_u, u)) +        return dist -    def get_path(self, goal, prev): -        """ -        始点startから終点goalまでの最短経路を求める -        """ -        path = [goal]  # 最短経路 -        dest = goal -        # 終点から最短経路を逆順に辿る -        while prev[dest] != float("inf"): -            path.append(prev[dest]) -            dest = prev[dest] -        # 経路をreverseして出力 -        return list(reversed(path)) +    dist_A = dijkstra(A, S) +    dist_B = dijkstra(B, T) +    init = 10**15 +    Ans = [] +    ans = float("inf") +    for a, b in zip(dist_A[:0:-1], dist_B[:0:-1]): +        ans = min(ans, a + b) +        Ans.append(init - ans) +    Ans.reverse() +    print(("\n".join(map(str, Ans)))) -from collections import defaultdict - -Ey = defaultdict(lambda: defaultdict(lambda: float("inf"))) -Es = defaultdict(lambda: defaultdict(lambda: float("inf"))) -E = [list(map(int, input().split())) for i in range(M)] -for e in E: -    u, v, a, b = e -    Ey[u - 1][v - 1] = Ey[v - 1][u - 1] = a -    Es[u - 1][v - 1] = Es[v - 1][u - 1] = b -dj = Dijkstra() -Dy = dj.dijkstra(Ey, S - 1) -Ds = dj.dijkstra(Es, T - 1) -mi = float("inf") -Ans = [0] * N -for i in range(N - 1, -1, -1): -    mi = min(mi, Dy[i] + Ds[i]) -    Ans[i] = mi -for a in Ans: -    print((10**15 - a)) +main()