#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define countof(array) (sizeof(array) / sizeof(array[0]))
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define rrep(i,n) for(int i = (n)-1; i >= 0; --i)
#define rep2(i,n) for(int i = 1; i <= (n); ++i)
#define rrep2(i,n) for(int i = (n); i > 0; --i)
#define srep(i,s,n) for(int i = s; i < (n); ++i)
#define rsrep(i,s,n) for(int i = (n)-1; i >= s; --i)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define aall(a) (a), (a)+countof(a)//for array sorting
#define raall(a) (a), (a)+countof(a), greater<>()
#define show(x) cout<<#x<<" = "<<(x)<<endl;
#define vfind(v, a) find(all(v), a) != v.end()
#define yn(f) { if (f) puts("YES"); else puts("NO"); }
#define yns(f) { if (f) puts("Yes"); else puts("No"); }
#define show_ary(...) { cout<<#__VA_ARGS__<<" = "; for (const auto& x : (__VA_ARGS__)) { cout<<x<<" "; } cout<<endl; }
#define show_pair(...) cout<<#__VA_ARGS__<<" = "<<endl; for (const auto& x : (__VA_ARGS__)) { cout<<"  "<<x.fi<<" : "<<x.se<<endl; }
#define out_ary(...) { int n = (__VA_ARGS__).size(); rep(i, n) printf("%d%s", (__VA_ARGS__)[i], i != n-1 ? " " : "\n"); }
#define argmax(v) distance((v).begin(), max_element(all(v)))
#define argmin(v) distance((v).begin(), min_element(all(v)))
#define vmax(v) *max_element(all(v))
#define vmin(v) *min_element(all(v))
typedef long long int ll;
typedef pair<ll, int> P;
typedef vector<P> vpair;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<double> vdouble;
typedef vector<string> vstr;
typedef vector<bool> vbool;
typedef vector<vint> vvint;
typedef vector<vll> vvll;
typedef vector<vstr> vvstr;
typedef vector<vbool> vvbool;
const ll LINF = 2000000000000000000ll;
const int INF = 1000000100;
const ll MOD = 1e9+7;


struct SegmentTree {
    int n;
    vector<ll> node;
    SegmentTree(vector<ll> v) {
        int sz = v.size();
        n = 1; while(n < sz) n *= 2;
        node.resize(2*n-1, INF);
        for(int i=0; i<sz; i++) node[i+n-1] = v[i];
        for(int i=n-2; i>=0; i--) node[i] = min(node[2*i+1], node[2*i+2]);
    }

    void update(int k, int val) {
        k += (n - 1);
        node[k] = val;
        while(k > 0) {
            k = (k - 1) / 2;
            node[k] = min(node[2*k+1], node[2*k+2]);
        }
    }

    ll query(int a, int b, int k=0, int l=0, int r=-1) {
        if(r < 0) r = n;
        if(r <= a || b <= l) return LINF;
        if(a <= l && r <= b) return node[k];
        ll vl = query(a, b, 2*k+1, l, (l+r)/2);
        ll vr = query(a, b, 2*k+2, (l+r)/2, r);
        return min(vl, vr);
    }
};

vll dijkstra(int s, vpair edges[], vll d) {
    priority_queue<P, vector<P>, greater<P>> que;
    d[s] = 0;
    que.push(P(0, s));

    while (que.size()) {
        P p = que.top();
        que.pop();
        int v = p.se;
        if (d[v] < p.fi) continue;
        for (auto e : edges[v]) {
            if (d[e.fi] > d[v] + e.se) {
                d[e.fi] = d[v] + e.se;
                que.push(P(d[e.fi], e.fi));
            }
        }
    }
    return d;
}

int main() {
    int n, m, s, t;
    cin >> n >> m >> s >> t;
    --s;
    --t;
    vpair ea[n], eb[n];
    vll da(n, LINF), db(n, LINF);
    rep(i, m) {
        int u, v, a, b;
        cin >> u >> v >> a >> b;
        --u;
        --v;
        ea[u].emplace_back(v, a);
        ea[v].emplace_back(u, a);
        eb[u].emplace_back(v, b);
        eb[v].emplace_back(u, b);
    }
    da = dijkstra(s, ea, da);
    db = dijkstra(t, eb, db);
    vll money(n, 0);
    rep(i, n) {
        money[i] = da[i] + db[i];
    }
    SegmentTree st(money);
    rep(i, n) {
        ll ans = 1e15 - st.query(i, n);
        cout << ans << endl;
    }
    return 0;
}

Measured memory_bytes: 21756