using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CompetitiveProgCsLib
{
	class MainProg
	{
		static string R => Console.ReadLine();
		static int RI => int.Parse(R);
		static double RD => double.Parse(R);
		static int[] RIs => R.Split(' ').Select(int.Parse).ToArray();
		static double[] RDs => R.Split(' ').Select(double.Parse).ToArray();
		static void Out(object obj) => Console.WriteLine(obj);
		static void OutLine<T>(IEnumerable<T> obj, string separateChar) => Out(String.Join(separateChar, obj));
		static void Outb(bool b) => Out(b ? "Yes" : "No");
		static void OutB(bool b) => Out(b ? "YES" : "NO");
		static bool IsIn(int y, int x, int h, int w) => 0 <= x && x < w && 0 <= y && y < h;

		static void Main(string[] args)
		{
			var nm = RIs;
			var n = nm[0];
			var m = nm[1];
			var s = nm[2];
			var t = nm[3];
			var gs = new ShortestPathProblem(n);
			var gt = new ShortestPathProblem(n);
			for (int i = 0; i < m; i++)
			{
				var uv = RIs;
				gs.addEdge(uv[0] - 1, uv[1] - 1, uv[2]);
				gt.addEdge(uv[0] - 1, uv[1] - 1, uv[3]);
			}
			var smin = gs.GetShortestCost(s - 1);
			var tmin = gt.GetShortestCost(t - 1);
			var sum = new long[n];
			var min_cost = long.MaxValue;
			for (int i = n - 1; i >= 0; i--)
			{
				sum[i] = smin[i] + tmin[i];
				min_cost = Math.Min(sum[i], min_cost);
				if (min_cost < sum[i]) sum[i] = min_cost;
			}
			for (int i = 0; i < n; i++)
			{
				Out(1000000000000000L - sum[i]);
			}
		}

		public class ShortestPathProblem
		{
			/// <summary>
			/// 辺を隣接リストで持つ
			/// </summary>
			private Dictionary<int, long>[] edges;
			public int Size
			{
				get
				{
					return edges.Length;
				}
			}

			public ShortestPathProblem(int n)
			{
				edges = (new Dictionary<int, long>[n]).Select(e => new Dictionary<int, long>()).ToArray();
			}
			
			public void addEdge(int u, int v, long w)
			{
				edges[u].Add(v, w);
				edges[v].Add(u, w);
			}

			/// <summary>
			/// sから全点への最小コストを求める
			/// </summary>
			/// <param name="s"></param>
			/// <returns></returns>
			public long[] GetShortestCost(int s)
			{
				var visited = (new bool[Size]).Select(x => x = false).ToArray();
				var cost = new long[Size];
				var priorityQueue = new PriorityQueue<CurrentState>();
				priorityQueue.Push(new CurrentState(s, 0));
				while (priorityQueue.Length != 0)
				{
					var state = priorityQueue.Pop();
					if (visited[state.position]) continue;
					visited[state.position] = true;
					cost[state.position] = state.weight;
					foreach (var e in edges[state.position])
					{
						priorityQueue.Push(new CurrentState(e.Key, state.weight + e.Value));
					}
				}
				return cost;
			}

			public class CurrentState : IComparable
			{
				public CurrentState(int pos, long w)
				{
					position = pos;
					weight = w;
				}
				public readonly int position;
				public readonly long weight;

				public int CompareTo(object obj)
				{
					return weight.CompareTo(((CurrentState)obj).weight);
				}
			}
		}

		public class PriorityQueue<T> where T : IComparable
		{
			#region member
			private List<T> list;
			private bool reverse;
			#endregion

			#region constructor
			/// <summary>
			/// 
			/// </summary>
			/// <param name="isReverse">定義された順序の逆で評価する</param>
			public PriorityQueue(bool isReverse = false)
			{
				list = new List<T>();
				reverse = isReverse;
			}
			#endregion

			#region private method
			private bool compare(T a, T b)
			{
				return reverse ^ a.CompareTo(b) > 0;
			}

			private void swap(int a, int b)
			{
				T tmp = list[a];
				list[a] = list[b];
				list[b] = tmp;
			}
			#endregion

			#region public method
			/// <summary>
			/// 要素を追加する
			/// </summary>
			/// <param name="item">追加する要素</param>
			public void Push(T item)
			{
				if (Length < list.Count) list[Length] = item;
				else list.Add(item);
				var pos = Length++;
				while (pos != 0)
				{
					var parent = (pos + 1) / 2 - 1;
					if (compare(list[pos], list[parent])) break;
					swap(pos, parent);
					pos = parent;
				}
			}

			/// <summary>
			/// 要素を追加する
			/// </summary>
			/// <param name="items">追加する要素の列</param>
			public void Push(IEnumerable<T> items)
			{
				foreach (var item in items)
				{
					Push(item);
				}
			}

			/// <summary>
			/// 値を確認する
			/// </summary>
			/// <returns></returns>
			public T Peek()
			{
				return list[0];
			}

			/// <summary>
			/// 値を取り出す
			/// </summary>
			/// <returns></returns>
			public T Pop()
			{
				var ret = Peek();
				var pos = 0;
				list[0] = list[--Length];
				while (2 * pos + 1 < Length)
				{
					var child = 2 * pos + 1;
					var child_other = 2 * pos + 2;
					if (child_other < Length && compare(list[child], list[child_other]))
					{
						child = child_other;
					}
					if (compare(list[child], list[pos])) break;
					swap(pos, child);
					pos = child;
				}
				return ret;
			}

			/// <summary>
			/// クリアする
			/// </summary>
			public void Clear()
			{
				list.Clear();
			}
			#endregion

			#region property
			/// <summary>
			/// 要素の長さを取得する
			/// </summary>
			public int Length
			{
				get;
				private set;
			}
			#endregion
		}
	}
}


Measured memory_bytes: 90624