#!/usr/bin/env python3

import sys
from typing import Any, Callable, Deque, Dict, List, Mapping, Optional, Sequence, Set, Tuple, TypeVar, Union
# import time
# import math, cmath
# import numpy as np
# import scipy.sparse.csgraph as cs            # csgraph_from_dense(ndarray, null_value=inf), bellman_ford(G, return_predecessors=True), dijkstra, floyd_warshall
# import random                                # random, uniform, randint, randrange, shuffle, sample
# import string                                # ascii_lowercase, ascii_uppercase, ascii_letters, digits, hexdigits
# import re                                    # re.compile(pattern) => ptn obj; p.search(s), p.match(s), p.finditer(s) => match obj; p.sub(after, s)
# from bisect import bisect_left, bisect_right # bisect_left(a, x, lo=0, hi=len(a)) returns i such that all(val<x for val in a[lo:i]) and all(val>-=x for val in a[i:hi]).
# from collections import deque                # deque class. deque(L): dq.append(x), dq.appendleft(x), dq.pop(), dq.popleft(), dq.rotate()
# from collections import defaultdict          # subclass of dict. defaultdict(facroty)
# from collections import Counter              # subclass of dict. Counter(iter): c.elements(), c.most_common(n), c.subtract(iter)
# from datetime import date, datetime          # date.today(), date(year,month,day) => date obj; datetime.now(), datetime(year,month,day,hour,second,microsecond) => datetime obj; subtraction => timedelta obj
# from datetime.datetime import strptime       # strptime('2019/01/01 10:05:20', '%Y/%m/%d/ %H:%M:%S') returns datetime obj
# from datetime import timedelta               # td.days, td.seconds, td.microseconds, td.total_seconds(). abs function is also available.
# from copy import copy, deepcopy              # use deepcopy to copy multi-dimentional matrix without reference
# from functools import reduce                 # reduce(f, iter[, init])
# from functools import lru_cache              # @lrucache ...arguments of functions should be able to be keys of dict (e.g. list is not allowed)
from heapq import heapify, heappush, heappop # built-in list. heapify(L) changes list in-place to min-heap in O(n), heappush(heapL, x) and heappop(heapL) in O(lgn).
# from heapq import _heapify_max, _heappop_max, _siftdown_max
# from heapq import nlargest, nsmallest        # nlargest(n, iter[, key]) returns k-largest-list in O(n+klgn).
from itertools import count, cycle, repeat   # count(start[,step]), cycle(iter), repeat(elm[,n])
# from itertools import groupby                # [(k, list(g)) for k, g in groupby('000112')] returns [('0',['0','0','0']), ('1',['1','1']), ('2',['2'])]
# from itertools import starmap                # starmap(pow, [[2,5], [3,2]]) returns [32, 9]
# from itertools import product, permutations  # product(iter, repeat=n), permutations(iter[,r])
# from itertools import combinations, combinations_with_replacement
# from itertools import accumulate             # accumulate(iter[, f])
# from operator import itemgetter              # itemgetter(1), itemgetter('key')
# from fractions import Fraction               # Fraction(a, b) => a / b ∈ Q. note: Fraction(0.1) do not returns Fraciton(1, 10). Fraction('0.1') returns Fraction(1, 10)



def main():
    Num = Union[int, float]
    mod = 1000000007                # 10^9+7
    inf = float('inf')              # sys.float_info.max = 1.79e+308
    # inf = 2 ** 63 - 1             # (for fast JIT compile in PyPy) 9.22e+18
    sys.setrecursionlimit(10**6)    # 1000 -> 1000000
    def input():  return sys.stdin.readline().rstrip()
    def ii():     return int(input())
    def isp():    return input().split()
    def mi():     return map(int, input().split())
    def mi_0():   return map(lambda x: int(x)-1, input().split())
    def lmi():    return list(map(int, input().split()))
    def lmi_0():  return list(map(lambda x: int(x)-1, input().split()))
    def li():     return list(input())
    def debug(x): print(x, file=sys.stderr)
    # def _heappush_max(h, item): h.append(item); _siftdown_max(h, 0, len(h)-1)

    class PQueueMin:
        '''
        min priority queue
        Attributes:
            self.pq (list): (priority, count, task) というタプルのエントリからなるヒープ。
            self.counter (iter): ユニークな番号。上記エントリを比較する際、task までに必ず順序関係が決定するようにするためのもの。(task に順序関係がないことがある)
        '''    
        def __init__(self):
            self.pq = []
            self.counter = count()

        def empty(self) -> bool:
            return len(self.pq) == 0

        def add_task(self, task: Any, priority: Num) -> None:
            count = next(self.counter)
            entry = (priority, count, task)
            heappush(self.pq, entry)
        
        def pop_task(self) -> Any:
            if self.empty():
                raise KeyError(f'PQueueMin.pop_task(): pqueue is empty.')
            priority, _, task = heappop(self.pq)
            return (task, priority)

        
    def dijkstra(adj_with_weight: Sequence[Sequence[int]], start: int=0) -> List[Num]:
        '''
        重みつき隣接リストを用いた Dijkstra 法 O((E+V)lgV) (頂点を回るときに最小のものを取り出していくのに VlgV, cost の更新で ElgV)
        負辺を含まぬ重みつきグラフについて、ある頂点から他の頂点までの最短コストを貪欲に計算する
        '''
        V = len(adj_with_weight)
        cost = [float('inf')] * V    # cost[i] = (minimum cost from node_start to node_i)
        cost[start] = 0
        fixed = [False] * V
        pq = PQueueMin()
        # 最初は始点が必ずコスト最小。pq に突っ込む
        pq.add_task(start, cost[start])
        while not pq.empty():
            # 現段階で最短のコストとなっている頂点を選択
            u, cost_of_u = pq.pop_task()
            if not fixed[u]:
                fixed[u] = True
                for v, weight_of_uv in adj_with_weight[u]:
                    if not fixed[v] and cost[v] > cost_of_u + weight_of_uv:
                        cost[v] = cost_of_u + weight_of_uv
                        pq.add_task(v, cost[v])
        return cost
    

    n, m, s, t = mi()
    s -= 1
    t -= 1    
    adj_yen = [[] for _ in range(n)]
    adj_snuke = [[] for _ in range(n)]
    for _ in range(m):
        u, v, a, b = mi()
        u -= 1
        v -= 1
        adj_yen[u].append((v, a))
        adj_yen[v].append((u, a))
        adj_snuke[u].append((v, b))
        adj_snuke[v].append((u, b))

    mincost_from_s_yen = dijkstra(adj_yen, start=s)
    mincost_from_t_snuke = dijkstra(adj_snuke, start=t)

    # debug(mincost_from_s_yen)
    # debug(mincost_from_t_snuke)

    rev_ans = []
    money = 10 ** 15
    prev = inf
    for i in range(n-1, -1, -1):
        # [i] 以降の都市は換金できる
        cost = mincost_from_s_yen[i] + mincost_from_t_snuke[i]
        prev = min(cost, prev)
        rev_ans.append(money - prev)
    
    for elm in reversed(rev_ans):
        print(elm)



if __name__ == "__main__":
    main()


Measured memory_bytes: 84840