Problem:
Princess in Danger

お姫様の危機

English text is not available in this practice contest.

ある貧乏な国のおてんばで勇敢なお姫様が，政略結婚のため別の国に嫁ぐことになった．ところが，お姫様を亡き者としようとしている悪漢に嫁ぎ先への道中で襲われお姫様が大けがをしてしまい，近くの病院に搬送された．ところが，悪漢はお姫様は確実に亡き者とするため特殊な毒を使っていた．そのため，お姫様を助けるには本国から特別な薬と冷凍された肉親の血液を大急ぎで運ばなければならなくなった．

この血液は冷凍状態で輸送されるのだが，鮮度を保つため，前回の冷凍から最大 M 分以内に血液冷凍施設で再冷凍しなければならない．しかし，冷凍施設が設置されている場所は数カ所しかない．

血液は，十分に冷凍した状態から，再冷凍なしで M 分の間無事である．再冷凍しなくてすむ残り時間が S 分のときに，T 分間冷凍しないで輸送した場合，再冷凍しなくてすむ残り時間は S - T 分となる．再冷凍しなくてすむ残り時間は，再冷凍することにより，最大 M 分まで回復する．血液の再冷凍にかかる時間は，どれだけ冷凍するかに依存する．血液を冷凍施設で，1分冷凍するごとに再冷凍しなくてすむ残り時間は1分回復する．

本国の首都を出発する時点の，血液を再冷凍しなくてすむ残り時間はM分である．

お姫様の従者であるあなたは，大切な主君の命を救うため，本国の首都からお姫様が搬送された病院まで血液の鮮度を保ったまま輸送するための経路を計算しなければならない．そう，あなたの使命は，本国の首都からその病院への最短経路を割り出し，その最短時間を求めることである．

Input

入力は，複数のデータセットより構成される．各データセットの最初の行には，6 つの非負の整数 N(2 ≦ N ≦ 100)，M(1 ≦ M ≦ 100)，L(0 ≦ L ≦ N - 2)，K，A(0 ≦ A ＜ N)，H(0 ≦ H ＜ N) が与えられる．これらはそれぞれ，町の数，再冷凍を行うまでの制限時間，冷凍施設のある町の数，町と町を直接結ぶ道路の数，本国の首都を表す番号，お姫様が搬送された病院のある町の番号を表す．本国の首都とお姫様が搬送された病院は，異なる町である．なお，町には 0 〜 N-1 までの番号がそれぞれ割り当てられているものとする．続く行には，L 個の非負の整数が 1 つの空白で区切られて与えられる．これらは，冷凍施設がある町の番号を表す．なお，本国の首都とお姫様が搬送された病院はこのリストには含まれないが，冷凍施設があるものと考えて良い．続く K 行では，町と町を結ぶ道路の情報が与えられる．その第 i 行目では，3 つの非負の整数 X ，Y ，T が 1 つの空白で区切られて与えられ，これは町 X と町 Y を直接結ぶ道があり，移動には時間 T を要するということを表す．なお，この道は双方向に通行可能である．また，町Xと町Yを直接結ぶ道は高々一つしか無い．

入力は N = M = L = K = A = H = 0 の時に終了し，これはデータセットに含まれない．

Output

各データセットについて，鮮度を保ったまま血液を届けることができる最短時間を出力せよ．もし届けることができない場合には "Help!" と出力せよ．

Sample Input

2 1 0 1 0 1
0 1 2
3 1 1 2 0 1
2
0 2 1
1 2 1
3 2 1 2 0 1
2
0 2 1
1 2 1
4 4 1 4 1 3
2
0 1 2
1 2 4
0 2 1
3 0 3
5 3 2 6 0 3
1 2
2 1 2
1 0 1
3 4 1
2 4 1
4 1 2
2 0 2
5 4 2 6 0 3
1 2
4 2 4
2 1 2
4 3 1
0 1 5
1 4 2
2 0 3
0 0 0 0 0 0

Output for the Sample Input

Help!
3
2
10
5
12

Solution in Ruby (judge verdict: Wrong Answer)

class Heap
	require 'forwardable'
	extend Forwardable

	def initialize
		@array = []
		@index = {}
	end

	def add(obj, key)
		@array << [obj, key]
		@index[obj] = @array.size - 1
		lift_up(@array.size - 1)
	end

	def swap(i, j)
		u = @array[i]
		v = @array[j]
		@index[u[0]], @index[v[0]] = j, i
		@array[i], @array[j] = v, u
	end

	def lift_up(i)
		return if i == 0
		j = (i - 1) / 2
		if @array[i][1] < @array[j][1]
			swap(i, j)
			lift_up(j)
		end
	end

	def del_min
		raise "heap is empty!" if empty?
		min = @array[0]
		if size > 1
			swap(0, @array.size-1)
			@array.pop
			lift_down(0)
		else
			@array.pop
		end
		@index.delete(min[0])
		min
	end

	def inc_key(obj, diff)
		i = @index[obj]
		@array[i][1] += diff
		lift_down(i)
	end

	def dec_key(obj, diff)
		i = @index[obj]
		@array[i][1] -= diff
		lift_up(i)
	end

	def update_key(obj, new_key)
		i = @index[obj]
		return unless i
		return if new_key >= @array[i][1]
		@array[i][1] = new_key
		lift_up(i)
	end

	def min_obj
		@array[0][0]
	end

	def min_key
		@array[0][1]
	end

	def lift_down(i)
		j = 2 * i + 1
		k = j + 1
		if k >= size
			return if j >= size
			if @array[i][1] > @array[j][1]
				swap(i, j)
				lift_down(j)
			end
		else
			l = (@array[j][1] < @array[k][1] ? j : k)
			if @array[i][1] > @array[l][1]
				swap(i, l)
				lift_down(l)
			end
		end
	end

	def_delegators :@array, :empty?, :size
end

module Graphical
	require 'set'

	def reachable_from(s, max_depth = nil)
		reached = Set[s]
		queue = [s]
		depth = 0
		loop {
			break if max_depth && depth >= max_depth
			next_queue = []
			until queue.empty?
				u = queue.shift
				each_to_node_of(u){|v|
					next if reached.include?(v)
					reached << v
					next_queue << v
				}
			end
			break if next_queue.empty?
			queue = next_queue
			depth += 1
		}
		return reached
	end

	def dijkstra(start, setting = {})
		raise "invalid setting" if setting.class != Hash
		raise "invalid setting" if setting.keys - [:goal, :multi_source, :multi_sink, :max_dist] != []
		
		start = Set[start] if !setting[:multi_source]
		goal = setting[:goal]
		goal = Set[goal] if goal && !setting[:multi_sink]
		max_dist = setting[:max_dist]

		h = Heap.new
		reached = Set.new
		start.each{|v|
			h.add(v, 0)
			reached << v
		}

		dist = {}
		until h.empty?
			u, key = h.del_min
			return key if setting[:goal] && goal.include?(u)
			break if max_dist && key > max_dist
			dist[u] = key
			each_to_node_of(u){|v|
				d = dist[u] + edge_length(u, v)
				if reached.include?(v)
					h.update_key(v, d)
				else
					h.add(v, d)
					reached << v
				end
			}
		end
		goal ? nil : dist
	end

	def bidir_dijkstra(s, t)
		f_dist = {}
		b_dist = {}

		f_heap = Heap.new
		b_heap = Heap.new

		f_heap.add(s, 0)
		b_heap.add(t, 0)

		f_reached = Set[s]
		b_reached = Set[t]

		f_current_dist = b_current_dist = 0
		best = Float::INFINITY

		loop {
			if !f_heap.empty?
				u, key = f_heap.del_min
				f_dist[u] = key
				f_current_dist = key
				each_to_node_of(u){|v|
					d = f_dist[u] + edge_length(u, v)
					if b_dist[v]
						path_len = d + b_dist[v]
						best = path_len if path_len < best
					end
					if f_reached.include?(v)
						f_heap.update_key(v, d)
					else
						f_heap.add(v, d)
						f_reached << v
					end
				}
			end

			if !b_heap.empty?
				u, key = b_heap.del_min
				b_dist[u] = key
				b_current_dist = key
				each_from_node_of(u){|v|
					d = b_dist[u] + edge_length(v, u)
					if f_dist[v]
						path_len = d + f_dist[v]
						best = path_len if path_len < best
					end
					if b_reached.include?(v)
						b_heap.update_key(v, d)
					else
						b_heap.add(v, d)
						b_reached << v
					end
				}
			end

			return best if f_current_dist + b_current_dist >= best
			return nil if f_heap.empty? && b_heap.empty?
		}
	end
end

class Graph
	include Graphical
	require 'set'

	def add_node(label = nil)
		Node.new(label)
	end

	def add_edge(u, v, label = nil)
		e = Edge.new(u, v, label)
		u.neighbour[v] = e
		v.neighbour[u] = e
		e
	end
	
	def del_edge(e)
		u, v = e.from, e.to
		u.neighbour.delete(v)
		v.neighbour.delete(u)
		e
	end

	class Node
		def initialize(label)
			@label = label
			@neighbour = {}
		end

		def to_s
			@label
		end
		
		attr_accessor :neighbour
		attr_reader :label
	end

	class Edge
		def initialize(u, v, label = nil)
			@from = u	
			@to = v
			@label = label
		end
		attr_reader :from, :to, :label
	end


	def each_to_node_of(u)
		u.neighbour.each_key{|v|
			yield v
		}
	end
	alias :each_from_node_of :each_to_node_of

	def edge_length(u, v)
		u.neighbour[v] ? 1 : nil
	end

end

class WeightedGraph < Graph
	def add_edge(u, v, length, label = nil)
		e = Edge.new(u, v, length, label)
		u.neighbour[v] = e
		v.neighbour[u] = e
		e
	end

	class Edge
		def initialize(u, v, length, label = nil)
			@from = u	
			@to = v
			@length = length
			@label = label
		end
		attr_reader :from, :to, :length, :label
	end

	def edge_length(u, v)
		u.neighbour[v].length
	end
end


start = Time.new

def warshall_floyd(dist_matrix)
	dist = dist_matrix
	n = dist.size
	raise "dist_matrix is not square" if dist.any?{|row| row.size != n}

	(0..n-1).each{|k|
		next_dist = (1..n).map{ Array.new(n) }	
		(0..n-1).each{|i|
			(0..n-1).each{|j|
				x = dist[i][j]
				y = dist[i][k] + dist[k][j]
				next_dist[i][j] = (x < y ? x : y)
			}
		}
		dist = next_dist
	}
	dist
end

loop {
	n, m, l, k, a, h = gets.split.map &:to_i
	break if n == 0

	freezer = (gets.split.map(&:to_i) + [a, h]).sort

	g = WeightedGraph.new
	nodes = (1..n).map{ g.add_node }

	k.times {
		x, y, t = gets.split.map &:to_i
		g.add_edge(nodes[x], nodes[y], t)
	}
	
	g2 = WeightedGraph.new
	f_nodes = {}
	freezer.each{|i|
		f_nodes[i] = g2.add_node
	}

	d2 = freezer.map{|x|
		d = g.dijkstra(nodes[x])
		freezer.map{|y|
			g2.add_edge(f_nodes[x], f_nodes[y], d[nodes[y]]) if d[nodes[y]]
		}
	}
	
	d = g2.dijkstra(f_nodes[a], {:goal => f_nodes[h]})
	if d
		puts d + (d < m ? 0 : d - m)
	else
		puts 'Help!'
	end
}