#include "bits/stdc++.h"
using namespace std;


template<typename Value, typename Compare = std::less<Value>, typename Index = int>
class BinaryHeap {
	Compare cmp;
	vector<Value> a;
	vector<Index> idx, nodeidx;
	int pos;

public:
	BinaryHeap(Compare cmp_ = Compare()) : cmp(cmp_) { }
	BinaryHeap(int n, Compare cmp_ = Compare()) : cmp(cmp_) { init(n); }

	void init(int n) {
		a.resize(n + 1);
		idx.assign(n + 1, -1);
		nodeidx.assign(n + 1, -1);
		pos = 1;
	}

	const Value &min() const { return a[1]; }
	const Value &get(Index i) const { return a[nodeidx[i]]; }
	Index argmin() const { return idx[1]; }
	Index size() const { return pos - 1; }
	bool empty() const { return pos == 1; }

	const Value &add(Index i, const Value &x) {
		Index node = nodeidx[i];
		if (node >= 0) return a[node];
		a[pos] = x;
		idx[pos] = i;
		nodeidx[i] = pos;
		++ pos;
		up(pos - 1);
		return x;
	}

	const Value &update(Index i, const Value &x) {
		Index node = nodeidx[i];
		if (node < 0) {
			a[pos] = x;
			idx[pos] = i;
			nodeidx[i] = pos;
			++ pos;
			up(pos - 1);
		} else {
			a[node] = x;
			up(node);
			down(node);
		}
		return x;
	}

	const Value &updatemin(Index i, const Value &x) {
		Index node = nodeidx[i];
		if (node >= 0 && !cmp(x, a[node])) return a[node];
		else return update(i, x);
	}

	Value remove(Index i) {
		if (i < 0) return Value();
		Index node = nodeidx[i];
		if (node < 0) return Value();
		-- pos;
		idx[node] = idx[pos];
		nodeidx[idx[pos]] = node;
		nodeidx[i] = -1;
		idx[pos] = -1;
		swap(a[pos], a[node]);
		up(node);
		down(node);
		return a[pos];
	}

private:
	void up(Index i) {
		for (Index c = i, p = c >> 1; p > 0 && cmp(a[c], a[p]); c >>= 1, p >>= 1) {
			swap(a[p], a[c]);
			swap(nodeidx[idx[p]], nodeidx[idx[c]]);
			swap(idx[p], idx[c]);
		}
	}

	void down(Index i) {
		Index bottom = pos;
		for (Index c = i; c * 2 < bottom; ) {
			Index b = c * 2 + (c * 2 + 1 < bottom && cmp(a[c * 2 + 1], a[c * 2]));
			if (!cmp(a[b], a[c])) break;
			swap(a[c], a[b]);
			swap(nodeidx[idx[c]], nodeidx[idx[b]]);
			swap(idx[c], idx[b]);
			c = b;
		}
	}
};

struct Arc {
	int to;
	int w;
	Arc() {}
	Arc(int to, int w) : to(to), w(w) {}
};

struct StaticGraph {
	typedef pair<int, Arc> Edge;

	struct ArcList {
		ArcList() : arcBegin(), arcEnd() {}
		ArcList(const Arc *arcBegin, const Arc *arcEnd) : arcBegin(arcBegin), arcEnd(arcEnd) {}

		const Arc *begin() const { return arcBegin; }
		const Arc *end() const { return arcEnd; }
		int size() const { return (int)(arcEnd - arcBegin); }
		bool empty() const { return arcBegin == arcEnd; }
		Arc operator[](int i) const { return arcBegin[i]; }

	private:
		const Arc * const arcBegin, *const arcEnd;
	};

	int size() const { return (int)offsets.size() - 1; }

	ArcList operator[](int i) const {
		return ArcList(arcs.data() + offsets[i], arcs.data() + offsets[i + 1]);
	}

	void init(int n, const vector<Edge> &edges) {
		int m = (int)edges.size();
		arcs.resize(m + 1);
		offsets.assign(n + 1, 0);
		for (int ei = 0; ei < m; ++ei)
			++offsets[edges[ei].first];
		for (int i = 0; i < n; ++i)
			offsets[i + 1] += offsets[i];
		for (int ei = m - 1; ei >= 0; --ei)
			arcs[--offsets[edges[ei].first]] = edges[ei].second;
	}


	vector<Arc> arcs;
	vector<int> offsets;
};

template<typename Dist, typename Graph>
void dijkstra(const Graph &g, int s, vector<Dist> &dist, vector<int> &parent) {
	int n = g.size();
	parent.assign(n, -1);
	dist.assign(n, numeric_limits<Dist>::max());
	vector<bool> vis(n);
	BinaryHeap<Dist> h(n);
	h.add(s, 0);
	while (!h.empty()) {
		int v = h.argmin(); Dist d = h.min();
		dist[v] = d;
		h.remove(v);
		vis[v] = true;
		for (auto &&e : g[v]) {
			if (!vis[e.to]) {
				if (h.updatemin(e.to, d + e.w) == d + e.w)
					parent[e.to] = v;
			}
		}
	}
}


int main() {
	int n; int m;
	while (~scanf("%d%d", &n, &m)) {
		int s; int t;
		scanf("%d%d", &s, &t), -- s, -- t;
		vector<StaticGraph::Edge> edges, iEdges;
		for (int i = 0; i < m; ++ i) {
			int u; int v; int a; int b;
			scanf("%d%d%d%d", &u, &v, &a, &b), -- u, -- v;
			edges.emplace_back(u, Arc(v, a));
			edges.emplace_back(v, Arc(u, a));
			iEdges.emplace_back(v, Arc(u, b));
			iEdges.emplace_back(u, Arc(v, b));
		}
		StaticGraph g, ig;
		g.init(n, edges);
		ig.init(n, iEdges);
		vector<long long> distA, distB;
		vector<int> dummy;
		dijkstra(g, s, distA, dummy);
		dijkstra(ig, t, distB, dummy);
		vector<long long> ans(n + 1);
		for (int i = n - 1; i >= 0; -- i)
			ans[i] = max(ans[i + 1], (long long)1e15 - distA[i] - distB[i]);
		for (int i = 0; i < n; ++ i)
			printf("%lld\n", ans[i]);
	}
}


Measured memory_bytes: 14628