Problem:
Score : 400 points

Problem Statement

Kenkoooo is planning a trip in Republic of Snuke.
In this country, there are n cities and m trains running.
The cities are numbered 1 through n, and the i-th train connects City u_i and v_i bidirectionally.
Any city can be reached from any city by changing trains.

Two currencies are used in the country: yen and snuuk.
Any train fare can be paid by both yen and snuuk.
The fare of the i-th train is a_i yen if paid in yen, and b_i snuuk if paid in snuuk.

In a city with a money exchange office, you can change 1 yen into 1 snuuk.
However, when you do a money exchange, you have to change all your yen into snuuk.
That is, if Kenkoooo does a money exchange when he has X yen, he will then have X snuuk.
Currently, there is a money exchange office in every city, but the office in City i will shut down in i years and can never be used in and after that year.

Kenkoooo is planning to depart City s with 10^{15} yen in his pocket and head for City t, and change his yen into snuuk in some city while traveling.
It is acceptable to do the exchange in City s or City t.

Kenkoooo would like to have as much snuuk as possible when he reaches City t by making the optimal choices for the route to travel and the city to do the exchange.
For each i=0,...,n-1, find the maximum amount of snuuk that Kenkoooo has when he reaches City t if he goes on a trip from City s to City t after i years.
You can assume that the trip finishes within the year.

Constraints

2 \leq n \leq 10^5

1 \leq m \leq 10^5

1 \leq s,t \leq n

s \neq t

1 \leq u_i < v_i \leq n

1 \leq a_i,b_i \leq 10^9

If i\neq j, then u_i \neq u_j or v_i \neq v_j.

Any city can be reached from any city by changing trains.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

n m s t
u_1 v_1 a_1 b_1
:
u_m v_m a_m b_m

Output

Print n lines.
In the i-th line, print the maximum amount of snuuk that Kenkoooo has when he reaches City t if he goes on a trip from City s to City t after i-1 years.

Sample Input 1

4 3 2 3
1 4 1 100
1 2 1 10
1 3 20 1

Sample Output 1

999999999999998
999999999999989
999999999999979
999999999999897

After 0 years, it is optimal to do the exchange in City 1.

After 1 years, it is optimal to do the exchange in City 2.

Note that City 1 can still be visited even after the exchange office is closed.
Also note that, if it was allowed to keep 1 yen when do the exchange in City 2 and change the remaining yen into snuuk, we could reach City 3 with 999999999999998 snuuk, but this is NOT allowed.

After 2 years, it is optimal to do the exchange in City 3.

After 3 years, it is optimal to do the exchange in City 4.
Note that the same train can be used multiple times.

Sample Input 2

8 12 3 8
2 8 685087149 857180777
6 7 298270585 209942236
2 4 346080035 234079976
2 5 131857300 22507157
4 8 30723332 173476334
2 6 480845267 448565596
1 4 181424400 548830121
4 5 57429995 195056405
7 8 160277628 479932440
1 6 475692952 203530153
3 5 336869679 160714712
2 7 389775999 199123879

Sample Output 2

999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994

Solution in Ruby (2.3.3) (judge verdict: Time Limit Exceeded)

class AVLtree
	class Node
		attr_reader :left, :data, :right, :depth

		def initialize(left, data, right, depth = nil)
			@left, @data, @right = left, data, right
			@depth = depth || [left.depth, right.depth].max + 1
		end

		def null?() false end

		def inspect
			'(%s %s %s)' % [@left.inspect, @data.inspect, @right.inspect]
		end
	end

	def initialize(root = NULL, &block)
		@root = root
		@cmp = block || lambda{ |a,b| a <=> b }
	end
	#
	# Priority comparison procedure.
	#
	attr_reader :cmp

	NULL = Object.new
	def NULL.depth() 0 end
	def NULL.null?() true end
	def NULL.inspect() 'null' end

	attr_reader :root
	def inspect() @root.inspect end

	def insert(x)
		if @root.null?
			@root = Node.new(NULL, x, NULL)
			return self
		end
		path = []
		node = @root
		while not node.null?
			if @cmp.call(x,node.data) == -1
				path.push [:left, node]
				node = node.left
			else
				path.push [:right, node]
				node = node.right
			end
		end
		@root = backroot(:insert, path, Node.new(NULL, x, NULL))
		self
	end
	alias push insert
	
	def delete(x)
		return self if @root.null?
		path = []
		j, just, node = nil, nil, @root
		while not node.null?
			j, just = path.size, node if @cmp.call(x,node.data)==0
			if @cmp.call(x,node.data)==1 || @cmp.call(x,node.data)==0
				path.push [:left, node]
				node = node.left
			else
				path.push [:right, node]
				node = node.right
			end
		end
		return self if just.nil?
		_, n = path.pop
		if not just.equal?(n)
			path[j][1] = Node.new(just.left, n.data, just.right, just.depth)
		end
		node = if n.right.null? then n.left else n.right end
		@root = backroot(:delete, path, node)
		self
	end

	# deletes and returns the top element
	def bottom
		return nil if @root.null?
		path = []
		j, just, node = nil, nil, @root
		prev = nil
		while not node.null?
			path.push [:left, node]
			prev = node
			node = node.left
		end
		_, n = path.pop
		node = if n.right.null? then n.left else n.right end
		@root = backroot(:delete, path, node)
		prev.data
	end
	alias pop bottom

	# returns reconstructed node
	def backroot(d, path, node)
		balanced = false
		path.reverse_each do |fn, n|
			if fn == :left
				node = Node.new(node, n.data, n.right)
			else
				node = Node.new(n.left, n.data, node)
			end
			next if balanced
			if (d == :delete) ^ (fn == :left)
				node = balance_left_heavy(node)
			else
				node = balance_right_heavy(node)
			end
			balanced = (d == :delete) ^ (node.left.depth == node.right.depth)
		end
		node
	end
	def balance_left_heavy(node)
		if node.right.depth - node.left.depth < -1 and not node.left.null?
			ll, d1, lr, d3, p4 = node.left.left, node.left.data, node.left.right, node.data, node.right
			if ll.depth >= lr.depth
				node = Node.new(ll, d1, Node.new(lr, d3, p4))
			else
				node = Node.new(Node.new(ll, d1, lr.left), lr.data, Node.new(lr.right, d3, p4))
			end
		end
		node
	end
	def balance_right_heavy(node)
		if node.right.depth - node.left.depth > 1 and not node.right.null?
			p0, d1, rl, d3, rr = node.left, node.data, node.right.left, node.right.data, node.right.right
			if rl.depth <= rr.depth
				node = Node.new(Node.new(p0, d1, rl), d3, rr)
			else
				node = Node.new(Node.new(p0, d1, rl.left), rl.data, Node.new(rl.right, d3, rr))
			end
		end
		node
	end

	def empty?
		return true if @root.null?
		false
	end
end

require 'pp'
# IS_DEBUG = true
IS_DEBUG = false
def dputs str
	if(IS_DEBUG)
		puts str
	end
end
def dpp str
	if(IS_DEBUG)
		pp str
	end
end

require 'pp'

INT_MAX = 999999999999999999999999

n,m,s,t=gets.chomp.split(' ').map{|n| n.to_i}
s -= 1
t -= 1
ey = Array.new(n){[]}
es = Array.new(n){[]}
1.upto(m){
	p=gets.chomp.split(' ').map{|n| n.to_i}
	p[0] -= 1
	p[1] -= 1
	ey[p[0]].push([p[1],p[2]])
	ey[p[1]].push([p[0],p[2]])
	es[p[0]].push([p[1],p[3]])
	es[p[1]].push([p[0],p[3]])
}
dpp ey
dpp es

# note : length of from point is set __1__
def dijkstra(e,s,t,darr)
	darr[s] = 0
	pq = AVLtree.new(){|a,b| b[1] <=> a[1]}
	pq.push([s,0])
	while(! pq.empty?)
		u = pq.pop
		# dpp u
		# dpp "poped u #{u} #{u[0][0]}"
		eu = e[u[0]]
		eu.each{|e_tgt|
			d_tgt = darr[e_tgt[0]]
			# dputs "u,e_tgt1 : #{u}, #{e_tgt[1]}"
			# dpp darr
			d_cand = darr[u[0]]+e_tgt[1]
			if(d_tgt.nil? || d_tgt > d_cand)
				d_tgt = darr[e_tgt[0]] = d_cand
				pq.push([e_tgt[0], d_tgt])
			end
		}
	end
end

dysarr = Array.new(n) { nil }
dstarr = Array.new(n) { nil }
dijkstra(ey,s,t,dysarr)
dijkstra(es,t,s,dstarr)
dpp dysarr
dpp "dstarr"
dpp dstarr
minarr = Array.new(n) { |i|  }
0.upto(n-1){|i|
	minarr[i] = dysarr[i]+dstarr[i]
}
minarrsort = minarr.each_with_index.sort{|(d,i),(d2,i2)| d <=> d2}

dpp minarrsort
0.upto(n-1){|yeari|
	minarrsort.each{|d,minarri|
		if(yeari<minarri+1)
			puts 10**15-d
			break
		end
	}
}