import std.stdio;
import std.typecons;
import std.container;
import std.algorithm;

alias Edge = Tuple!(int, "dst", int, "cost");

void main()
{
    int n, m, s, t;

    readf(" %s %s %s %s", &n, &m, &s, &t);
    s--;
    t--;

    auto yen = new Edge[][](n, 0);
    auto snk = new Edge[][](n, 0);

    foreach (j; 0..m)
    {
        int u, v, a, b;
        readf(" %s %s %s %s", &u, &v, &a, &b);
        u--;
        v--;

        yen[u] ~= Edge(v, a);
        yen[v] ~= Edge(u, a);
        snk[u] ~= Edge(v, b);
        snk[v] ~= Edge(u, b);
    }

    auto f = dijkstra(yen, s);
    auto b = dijkstra(snk, t);

    auto ans = new long [n + 1];
    ans[$ - 1] = long.max;
    foreach_reverse (i; 0..n)
    {
        ans[i] = min(ans[i + 1], f[i] + b[i]);
    }

    ans[] = 10L ^^ 15 - ans[];
    writefln ("%(%s\n%)", ans[0..n]);
}

auto dijkstra(Edge[][] edges, int s) {
    alias Distance = Tuple!(int, "node", long, "distance");
    auto heap = BinaryHeap!(Array!Distance,"a.distance > b.distance")();
    heap.insert(Distance(s, 0));

    auto ret = new long[edges.length];
    ret[] = long.max;
    ret[s] = 0;

    while (!heap.empty) {
        auto v = heap.front;
        heap.removeFront();

        if (ret[v.node] < v.distance) continue;

        foreach (e; edges[v.node])
        {
            if (ret[e.dst] > ret[v.node] + e.cost) {
                ret[e.dst] = ret[v.node] + e.cost;
                heap.insert(Distance(e.dst, ret[e.dst]));
            }
        }
    }

    return ret;
}
