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 C++14 (judge verdict: Accepted)

#include<iostream>
#include<vector>
#include<algorithm>
#include<cctype>
#include<utility>
#include<string>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#include<tuple>

#define REP(i, n) for(int i = 0;i < n;i++)
#define REPR(i, n) for(int i = n;i >= 0;i--)
#define FOR(i, m, n) for(int i = m;i < n;i++)
#define FORR(i, m, n) for(int i = m;i >= n;i--)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define llong long long
#define pb(a) push_back(a)

using namespace std;

typedef long long int ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef tuple<int, int, int> tiii;


template<typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
	return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template<typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T& t, const V& v) { t = v; }
template<typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T& t, const V& v) {
	for (auto& e : t) fill_v(e, v);
}


#define ARRAY_MAX 100005
int dx[4] = { 1,0,0,-1 };
int dy[4] = { 0,1,-1,0 };
const int MOD = 1e9 + 7;
const int INF = 1e9 + 7;

ll n, m, y, z;
char c[15];
int p[15];
string s;

#define DEBUG 1

struct node {

	int to;
	int cost;

};


int main() {

	int n, m, l, k, a, h;
	while (cin >> n >> m >> l >> k >> a >> h, n | m | l | k | a | h) {

		int cold[105] = {  };
		auto G = make_v<node>(105, 0);
	
		for (int i = 0; i < l; i++)
		{
			int tmp;
			cin >> tmp;
			cold[tmp] = 1;//冷却施設のある町にチェックを入れる
		}
		cold[a] = cold[h] = 1;

		//道の構築
		for (int i = 0; i < k; i++)
		{
			int f, t, c;
			cin >> f >> t >> c;
			G[t].push_back(node{ f, c });
			G[f].push_back(node{ t, c });
		}
		

		//以下拡張ダイクストラ

		auto dist = make_v<int>(105, 105);
		//dist[i][j]:=町iに残り時間jを残して到着した時の最短時間

		fill_v(dist, INF);

		//(現在の時間，今いる頂点，残り時間)
		priority_queue<tiii, vector<tiii>, greater<tiii> > que;
		dist[a][m] = 0;
		que.push(tiii(0, a, m));
	
		while (!que.empty())
		{
			int tm, now, remain;
			tie(tm, now, remain) = que.top();
			que.pop();

			if (dist[now][remain] < tm) {
				continue;
			}

			if (cold[now]) {
				//今いる町に冷却施設がある
				for (auto itr: G[now]) {

					for (int j = 0; j <= m; j++)
					{
						//m分に回復するまで待つ
						if (remain > j) {
							//既にj分以上の余裕がある
							continue;
						}

						int wait = j - remain;//回復するまでの待ち時間
						if (j < itr.cost) {
							//次の町に行けない場合
							continue;
						}

	
						if (dist[now][remain] == INF) {
							continue;
						}

						//今の時間+回復までの待ち時間+移動コストのほうが小さい場合は更新
						if (dist[itr.to][j - itr.cost] > dist[now][remain] + wait + itr.cost) {
							dist[itr.to][j - itr.cost] = dist[now][remain] + wait + itr.cost;
							que.push(tiii(dist[itr.to][j - itr.cost], itr.to, j - itr.cost));
						}


					}
				}
			}
			else
			{
				//冷却施設がない
				for (auto itr : G[now]) {
					
					
					if (remain < itr.cost) {
						//移動できない
						continue;
					}

					if (dist[itr.to][remain - itr.cost] > dist[now][remain] + itr.cost) {
						dist[itr.to][remain - itr.cost] = dist[now][remain] + itr.cost;
						que.push(tiii(dist[itr.to][remain - itr.cost], itr.to, remain - itr.cost));
					}
				}
			}
		}	

		int ans = INF;
		for (int i = 0; i <= m; i++)
		{
			ans = min(ans, dist[h][i]);
		}

		if (ans == INF) {
			cout << "Help!" << endl;
		}
		else
		{
			cout << ans << endl;
		}

		dist.shrink_to_fit();
		G.shrink_to_fit();

	}




	return 0;

}