void main()
{
    long n, m, s, t;
    rdVals(n, m, s, t);
    --s, --t;
    Edge[][] yen = new Edge[][](n), snk = new Edge[][](n);
    foreach (i; 0 .. m)
    {
        long u, v, a, b;
        rdVals(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);
    }

    long[] Dijkstra(long x, Edge[][] edge)
    {
        long[] result = new long[n];
        result[] = inf;
        result[x] = 0;
        auto que = new BinaryHeap!(Array!Edge, "a.cost > b.cost");
        que.insert(Edge(x, 0));
        while (!que.empty)
        {
            Edge f = que.front;
            que.popFront;
            foreach (e; edge[f.to])
            {
                if (result[e.to] <= result[f.to] + e.cost) continue;
                result[e.to] = result[f.to] + e.cost;
                que.insert(Edge(e.to, result[e.to]));
            }
        }
        return result;
    }

    long money = 10L ^^ 15;
    long[] dyen = Dijkstra(s, yen), dsnk = Dijkstra(t, snk);
    long[] result = new long[n];
    result[n-1] = money - dyen[n-1] - dsnk[n-1];
    foreach_reverse (i; 0 .. n-1)
    {
        result[i] = max(result[i+1], money-dyen[i]-dsnk[i]);
    }

    foreach (r; result)
    {
        r.writeln;
    }
}

struct Edge
{
    long to, cost;
}

enum long mod = 10^^9 + 7;
enum long inf = 1L << 60;
enum double eps = 1.0e-9;

T rdElem(T = long)()
if (!is(T == struct))
{
    return readln.chomp.to!T;
}

alias rdStr = rdElem!string;
alias rdDchar = rdElem!(dchar[]);

T rdElem(T)()
if (is(T == struct))
{
    T result;
    string[] input = rdRow!string;
    assert(T.tupleof.length == input.length);
    foreach (i, ref x; result.tupleof)
    {
        x = input[i].to!(typeof(x));
    }
    return result;
}

T[] rdRow(T = long)()
{
    return readln.split.to!(T[]);
}

T[] rdCol(T = long)(long col)
{
    return iota(col).map!(x => rdElem!T).array;
}

T[][] rdMat(T = long)(long col)
{
    return iota(col).map!(x => rdRow!T).array;
}

void rdVals(T...)(ref T data)
{
    string[] input = rdRow!string;
    assert(data.length == input.length);
    foreach (i, ref x; data)
    {
        x = input[i].to!(typeof(x));
    }
}

void wrMat(T = long)(T[][] mat)
{
    foreach (row; mat)
    {
        foreach (j, compo; row)
        {
            compo.write;
            if (j == row.length - 1) writeln;
            else " ".write;
        }
    }
}

import std.stdio;
import std.string;
import std.array;
import std.conv;
import std.algorithm;
import std.range;
import std.math;
import std.numeric;
import std.mathspecial;
import std.traits;
import std.container;
import std.functional;
import std.typecons;
import std.ascii;
import std.uni;
import core.bitop;