//dijkstra rezolvare cu heap-uri

#include <cstdio>
#include <vector>
#include <iostream>

//FILE *fin = fopen("dijkstra.in", "r");
//FILE *fout = fopen("dijkstra.out", "w");

#define MAXN 100000
#define MAXM 100000
#define MAXC 1000000000000000
#define LL long long

int h[MAXN + 1], poz[MAXN + 1], k, n;
LL dist[MAXN + 1][2], max[MAXN + 1];

std::vector<std::pair<int, std::pair<int, int>>> v[MAXM + 1];
std::vector<std::pair<int, std::pair<int, int>>>::iterator it;


void swap(int a, int b) {
    int t = h[a];
    h[a] = h[b];
    h[b] = t;
}

void upheap(int x, bool type) {
    int t;
    while (x > 1) {
        t = x / 2;
        if(dist[h[t]][type] > dist[h[x]][type]) {
            poz[h[x]] = t;
            poz[h[t]] = x;

            swap(t, x);

            x = t;
        }
        else {
            return;
        }
    }
}

void downheap(int x, bool type) {
    int f;
    while(x <= k) {
        if (x * 2 <= k) {
            f = x * 2;
            if (f + 1 <= k)
                if (dist[h[f]][type] > dist[h[f + 1]][type])
                    f++;
            if (dist[h[x]][type] > dist[h[f]][type]) {
                poz[h[x]] = f;
                poz[h[f]] = x;

                swap(f, x);

                x = f;
            }
            else
                return;
        }
        else
            return;
    }
}

void dijkstra(int start, bool type) {
    dist[start][type] = 0;
    h[1] = start;
    poz[start] = 1;
    k++; //marimea cozii

    //cat timp exista elemente in coada
    while(k) {
        //nodul cu valoarea minima este primul element din coada
        int min = h[1];
        //eliminam nodul curent din coada
        swap(1, k);
        poz[h[1]] = 1;
        k--;
        downheap(1, type);
        //actualizarea distantelor vecinilor nodului curent
        for (it = v[min].begin(); it != v[min].end(); it++) {
            //nodul vecin
            int y = it->first;

            //distanta de la nodul curent la nodul vecin
            int c;
            if (!type)
                c = it->second.first;
            else
                c = it->second.second;
            //actualizam distanta minima de la nodul initial daca se poate obtine una mai buna
            if(dist[y][type] > dist[min][type] + c) {
                dist[y][type] = dist[min][type] + c;
                //daca nodul vecin era deja in coada, ii actualizam pozitia in coada
                if ( poz[y] != -1 )
                    upheap(poz[y], type);
                //daca nodul vecin nu era in coada, il adaugam si actualizam coada
                else {
                    h[++k] = y;
                    poz[h[k]] = k;
                    upheap(k, type);
                }
            }
        }
    }
}
int main() {
    int n, m, x, y, a, b, s, t;
    //read
    fscanf(stdin, "%d%d%d%d", &n, &m, &s, &t);
    for (int i = 1; i <= m; i++) {
        fscanf(stdin, "%d%d%d%d", &x, &y, &a, &b);
        v[x].push_back(std::make_pair(y, std::make_pair(a, b)));
        v[y].push_back(std::make_pair(x, std::make_pair(a, b)));
    }

    //marcam nodurile ca nevizitate
    for (int i = 1; i <= n; i++) {
        dist[i][0] = MAXC /10 * 11;
        dist[i][1] =  MAXC / 10 * 11;
        poz[i] = -1;
        h[i] = 0;
    }
    k = 0;
    dijkstra(s, 0);
    for (int i = 1; i <= n; i++) {;
        poz[i] = -1;
        h[i] = 0;
    }
    k = 0;
    dijkstra(t, 1);
    max[n] = dist[n][0] + dist[n][1];
    for (int i = n - 1; i >= 1; i--) {
        LL d = dist[i][0] + dist[i][1];
        max[i] = max[i + 1];
        if (d < max[i])
            max[i] = d;
    }
    for (int i = 1; i <= n; i++)
        fprintf(stdout, "%lld\n", MAXC - max[i]);
    return 0;
}


Measured memory_bytes: 11392