#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define MOD 1000000007
using namespace std;

typedef pair<int, int> P;
typedef pair<long long, long long> LLP;

/*
    Dijkstra's Algorithm (Single Source Shortest Path)
        - for directed graph
        - NO edges have negative cost
        - 0-indexed vertexes
 */

class Dijkstra {
    private:
        vector< vector<LLP> > G;
        vector<long long> cost;
        vector<long long> par;
        priority_queue<LLP, vector<LLP>, greater<LLP> > que;

    public:
        Dijkstra(long long n, vector< vector<long long> > g, long long s);
        long long getCost(long long target);
        vector< vector<long long> > getPath(long long target);
};

// n: |V|
// g: [point_from, point_to, cost] (directed graph)
// s: start point
Dijkstra::Dijkstra(long long n, vector< vector<long long> > g, long long s) {
    for (long long i = 0; i < n; i++) {
        G.push_back(vector<LLP>());
        cost.push_back(-1);
        par.push_back(-1);
    }    

    // create adj-Graph
    for (long long i = 0; i < g.size(); i++) {
        G[g[i][0]].push_back(make_pair(g[i][1], g[i][2]));
    }

    // initialize
    cost[s] = 0;
    par[s] = s;
    que.push(make_pair(cost[s], s));

    while (!que.empty()) {
        LLP p = que.top();
        que.pop();

        if (cost[p.second] < p.first) continue;
        for (int i = 0; i < G[p.second].size(); i++) {
            if (cost[G[p.second][i].first] < 0 || cost[G[p.second][i].first] > cost[p.second] + G[p.second][i].second) {
                cost[G[p.second][i].first] = cost[p.second] + G[p.second][i].second;
                par[G[p.second][i].first] = p.second;
                que.push(make_pair(cost[G[p.second][i].first], G[p.second][i].first));
            }
        }
    }
}

// returns the minimum cost from the start point to the target.
// (if there is no path to the target, this returns -1.)
// (if the target is the start point, this returns 0.)
long long Dijkstra::getCost(long long target) {
    return cost[target];
}


// returns a list of path: Array of [point_from, point_to, cost].
// (if there is no path to the target or the target is the start point, this returns an empty vector.)
vector< vector<long long> > Dijkstra::getPath(long long target) {

    vector< vector<long long> > reversePath = vector< vector<long long> >(0);

    if (cost[target] <= 0) return reversePath;
    
    long long now_p = target;
    while (par[now_p] != now_p) {
        vector<long long> temp(3);
        temp[0] = par[now_p];
        temp[1] = now_p;
        temp[2] = cost[now_p] - cost[par[now_p]];
        reversePath.push_back(temp);
        now_p = par[now_p];
    }

    vector< vector<long long> > path = vector< vector<long long> >(0);
    for (long long i = reversePath.size() - 1; i >= 0; i--) path.push_back(reversePath[i]);

    return path;
}

int main() {
    long long n, m, s, t;
    cin >> n >> m >> s >> t;
    vector< vector<long long> > g_yen, g_snook;

    for (long long i = 0; i < m; i++) {
        long long u, v, a, b;
        scanf("%lld %lld %lld %lld", &u, &v, &a, &b);
        u--; v--;
        vector<long long> temp_yen;
        temp_yen.push_back(u);
        temp_yen.push_back(v);
        temp_yen.push_back(a);
        vector<long long> temp_yen2;
        temp_yen2.push_back(v);
        temp_yen2.push_back(u);
        temp_yen2.push_back(a);
        vector<long long> temp_snook;
        temp_snook.push_back(u);
        temp_snook.push_back(v);
        temp_snook.push_back(b);
        vector<long long> temp_snook2;
        temp_snook2.push_back(v);
        temp_snook2.push_back(u);
        temp_snook2.push_back(b);
        g_yen.push_back(temp_yen);
        g_yen.push_back(temp_yen2);
        g_snook.push_back(temp_snook);
        g_snook.push_back(temp_snook2);
    }

    s--; t--;

    Dijkstra tree_yen(n, g_yen, s);
    Dijkstra tree_snook(n, g_snook, t);

    vector<long long> minimumCost(n, -1);
    minimumCost[n - 1] = tree_yen.getCost(n - 1) + tree_snook.getCost(n - 1);

    for (long long i = n - 2; i >= 0; i--) {
        long long cost = tree_yen.getCost(i) + tree_snook.getCost(i);
        minimumCost[i] = min(cost, minimumCost[i + 1]);
    }

    for (int i = 0; i < n; i++) {
        cout << 1000000000000000 - minimumCost[i] << endl;
    }

    return 0;
}

Measured memory_bytes: 56344