#include <iostream>
#include <string>
#include <algorithm>
#include <cassert>
#include <array>
#include <queue>
//#include <stack>
#include <vector>
#include <map>
//#include <set>
#include <unordered_map>
//#include <unordered_set>

using namespace std;

struct Vertex;
using Vertices = vector<Vertex *>;
struct Edge;
using Edges = vector<Edge *>;

struct Vertex {
	const int id;
	Edges edges;
	Vertices dsts;
	Vertex(int id);
	void add_edge(Edge *p_e);
	void copy(const Vertex &v);
};

using Weight = long long;
struct Edge {
	Vertex *const p_src, *const p_dst;
	Weight weight;
	Weight a, b;
	Weight lower;
	Edge(Vertex *p_src, Vertex *p_dst, Weight a, Weight b);
};

struct Graph {
	Vertices vertices;
	Edges edges;
	Graph(int nvertices);
	~Graph();
	void add_edge(Edge *p_edge);
	void add_edge(int edge_src, int edge_dst, Weight a, Weight b);
	void copy_vertex(int id_original, int id_copy);
};

Vertex::Vertex(int id) : id(id) {
}
void Vertex::add_edge(Edge *p_e) {
	edges.push_back(p_e);
	dsts.push_back(p_e->p_dst);
}
void Vertex::copy(const Vertex &v) {
	for (const auto &p_e : v.edges) {
		add_edge(p_e);
	}
}

Edge::Edge(Vertex *p_src, Vertex *p_dst, Weight a, Weight b) : p_src(p_src), p_dst(p_dst), a(a), b(b), lower(min(a, b)) {
	weight = a;
}

Graph::Graph(int nvertices) {
	for (int id = 0; id < nvertices; id++) {
		vertices.push_back(new Vertex(id));
	}
}
Graph::~Graph() {
	for (auto &p_vertex : vertices) {
		delete p_vertex;
	}
	for (auto &p_edge : edges) {
		delete p_edge;
	}
}
void Graph::add_edge(Edge *p_edge) {
	(*vertices[p_edge->p_src->id]).add_edge(p_edge);
	edges.push_back(p_edge);
}
void Graph::add_edge(int edge_src, int edge_dst, Weight a, Weight b) {
	add_edge(new Edge(vertices[edge_src], vertices[edge_dst], a, b));
}
void Graph::copy_vertex(int id_original, int id_copy) {
	vertices[id_copy]->copy(*vertices[id_original]);
}

#define INF 1000000000000000000
using Pwi = pair<Weight, int>;
void dijkstra(const Graph &g, int s, vector<Weight> &d) { // P, Weight, INFに気を付けよ
	const int n = g.vertices.size();
	d.assign(n, INF); d[s] = 0;
	vector<bool> is_used;
	is_used.assign(n, false);
	priority_queue<Pwi, vector<Pwi>, greater<Pwi>> que;

	for (que.push(Pwi(0, s)); !que.empty(); ) {
		Pwi p = que.top(); que.pop();
		//Cost tmpd = p.first; // tmpd >= d[tmpv]
		int tmpid = p.second;
		if (is_used[tmpid]) continue;
		is_used[tmpid] = true;
		assert(p.first == d[tmpid]);
		//if (tmpd > d[tmpid]) continue;
		for (const auto &nexte : g.vertices[tmpid]->edges) {
			if (d[nexte->p_dst->id] > d[tmpid] + nexte->weight) {
				d[nexte->p_dst->id] = d[tmpid] + nexte->weight;
				que.push(Pwi(d[nexte->p_dst->id], nexte->p_dst->id));
			}
		}
	}
}

void dijkstra_a(const Graph &g, int s, vector<Weight> &d) { // P, Weight, INFに気を付けよ
	const int n = g.vertices.size();
	d.assign(n, INF); d[s] = 0;
	vector<bool> is_used;
	is_used.assign(n, false);
	priority_queue<Pwi, vector<Pwi>, greater<Pwi>> que;

	for (que.push(Pwi(0, s)); !que.empty(); ) {
		Pwi p = que.top(); que.pop();
		//Cost tmpd = p.first; // tmpd >= d[tmpv]
		int tmpid = p.second;
		if (is_used[tmpid]) continue;
		is_used[tmpid] = true;
		assert(p.first == d[tmpid]);
		//if (tmpd > d[tmpid]) continue;
		for (const auto &nexte : g.vertices[tmpid]->edges) {
			if (d[nexte->p_dst->id] > d[tmpid] + nexte->a) {
				d[nexte->p_dst->id] = d[tmpid] + nexte->a;
				que.push(Pwi(d[nexte->p_dst->id], nexte->p_dst->id));
			}
		}
	}
}

void dijkstra_l(const Graph &g, int s, vector<Weight> &d) { // P, Weight, INFに気を付けよ
	const int n = g.vertices.size();
	d.assign(n, INF); d[s] = 0;
	vector<bool> is_used;
	is_used.assign(n, false);
	priority_queue<Pwi, vector<Pwi>, greater<Pwi>> que;

	for (que.push(Pwi(0, s)); !que.empty(); ) {
		Pwi p = que.top(); que.pop();
		//Cost tmpd = p.first; // tmpd >= d[tmpv]
		int tmpid = p.second;
		if (is_used[tmpid]) continue;
		is_used[tmpid] = true;
		assert(p.first == d[tmpid]);
		//if (tmpd > d[tmpid]) continue;
		for (const auto &nexte : g.vertices[tmpid]->edges) {
			if (d[nexte->p_dst->id] > d[tmpid] + nexte->b) {
				d[nexte->p_dst->id] = d[tmpid] + nexte->b;
				que.push(Pwi(d[nexte->p_dst->id], nexte->p_dst->id));
			}
		}
	}
}


#define MAXN 100000
int n, m, s, t;
int u, v;
Weight a, b;
Weight money;

void solve() {
	Weight ans;
	money = 1000000000000000;

	cin >> n >> m >> s >> t;
	Graph g(n + 1);
	for (int i = 0; i < m; i++)
	{
		cin >> u >> v >> a >> b;
		g.add_edge(u, v, a, b);
		g.add_edge(v, u, a, b);
	}

	vector<Weight> k, l;
	dijkstra_a(g, s, k);
	dijkstra_l(g, t, l);
	priority_queue<Pwi, vector<Pwi>, greater<Pwi>> que;
	for (int i = 1; i <= n; i++)
	{
		que.push(Pwi(k[i] + l[i], i));
	}
	for (int i = 0; i <= n - 1; i++)
	{
		Pwi p = que.top();
		if (p.second <= i) {
			que.pop();
			i--;
			continue;
		}
		ans = money - p.first;
		if (ans <= 0) {
			ans = 0;
			for (int j = i; j <= n - 1; j++)
			{
				cout << ans << endl;
			}
			break;
		}
		else
			cout << ans << endl;
	}


	return;
}

int main() {
	solve();
	return 0;
}	

Measured memory_bytes: 33272