### BUGGY CODE ###

from heapq import *
import numpy as np

n, m, s, t = map(int, input().split())
# zero start
s -= 1
t -= 1

# 
vertices = []
for i in range(n):
    v = []
    vertices.append(v)

#print(n, m, s, t)
# load node
for k in range(m):
    u, v, a, b = map(int, input().split())
    vertices[u-1].append([v-1, a, b])
    vertices[v-1].append([u-1, a, b])


#print('-----------------')

#print(n, m, s, t)
#for i in range(n):
#    print(vertices[i].list_adj)

mode = 0
# return list of [no_adj, cost]
def get_adj(v):
    res = []
    for adj in vertices[v]:
        res.append([adj[0], adj[1+mode]])
    return res

#print('show adjcent(a)')
#for k in range(n):
#    print(get_adj(vertices[k]))

mode = 1
#print('show adjcent(b)')
#for k in range(n):
#    print(get_adj(vertices[k]))

def dijkstra(s):
    inf = int(10e20)
    dist_pre = [inf] * n
    dist = [inf] * n
    h = []
    heappush(h, (0, s))
    dist_pre[s] = 0
    while len(h) > 0:
        # pop 1 node
        dv, v = heappop(h)
        # if already decided, continue
        if dist[v] < inf:
            continue
        dist[v] = dv
        # push adjcent node
        list_adj = get_adj(v)
        for adj in list_adj:
            if dist[adj[0]] == inf:
                dnew = dv + adj[1]
                if dnew < dist_pre[adj[0]]:
                    dist_pre[adj[0]] = dnew
                    heappush(h, (dnew, adj[0]))
                pass
        pass
    return dist

mode = 0
dist_a = dijkstra(s)
mode = 1
dist_b = dijkstra(t)
#cost = []
#for k in range(len(dist_a)):
#    cost.append(dist_a[k] + dist_b[k])
cost = np.array(dist_a,dtype = 'int') + np.array(dist_b,dtype = 'int')
cost = np.array(cost, dtype='int')
#print(cost)

m0 = int(1e15)
for i in range(n):
    cost_available = cost[i:]
    print(m0-np.amin(cost_available))

### FIXED CODE ###

from heapq import heappush, heappop

n, m, s, t = map(int, input().split())
# zero start
s -= 1
t -= 1

# 
vertices = []
for i in range(n):
  v = []
  vertices.append(v)

#print(n, m, s, t)
# load node
for k in range(m):
    u, v, a, b = map(int, input().split())
    vertices[u-1].append([v-1, a, b])
    vertices[v-1].append([u-1, a, b])


#print('-----------------')

#print(n, m, s, t)
#for i in range(n):
#    print(vertices[i])

mode = 0
# return list of [no_adj, cost]
def get_adj(v):
    res = []
    for adj in vertices[v]:
        res.append([adj[0], adj[1+mode]])
    return res

#print('show adjcent(a)')
#for k in range(n):
#    print(get_adj(vertices[k]))

mode = 1
#print('show adjcent(b)')
#for k in range(n):
#    print(get_adj(vertices[k]))

def dijkstra(s):
    inf = int(10e20)
    dist_pre = [inf] * n
    dist = [inf] * n
    h = []
    heappush(h, (0, s))
    dist_pre[s] = 0
    while len(h) > 0:
        # pop 1 node
        dv, v = heappop(h)
        # if already decided, continue
        if dist[v] < inf:
            continue
        dist[v] = dv
        # push adjcent node
        list_adj = get_adj(v)
        #print(v, list_adj)
        for adj in list_adj:
            if dist[adj[0]] == inf:
                dnew = dv + adj[1]
                if dnew < dist_pre[adj[0]]:
                    dist_pre[adj[0]] = dnew
                    heappush(h, (dnew, adj[0]))
                pass
        pass
    return dist

mode = 0
dist_a = dijkstra(s)
mode = 1
dist_b = dijkstra(t)
cost = [a+b for a, b in zip(dist_a, dist_b)]
#cost = []
#for k in range(len(dist_a)):
#    cost.append(dist_a[k] + dist_b[k])
#cost = np.array(dist_a,dtype = 'int') + np.array(dist_b,dtype = 'int')
#cost = np.array(cost, dtype='int')
#print(dist_a)
#print(dist_b)
#print(cost)
#cost = np.array(cost, dtype='int')

res = [0]*n

min_temp = int(1e20)
m0 = int(1e15)
for i in range(n):
    k = n-1-i
    if(cost[k]<min_temp):
        min_temp = cost[k]
    res[k] = m0 - min_temp
    #cost_available = cost[i:]
    #print(m0-np.amin(cost_available))

for r in res:
    print(r)