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

Submitted solutions:

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

// #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG // 配列外参照のエラー
// #endif

// スタンダードライブラリ
#include <bits/stdc++.h>
using namespace std;

// 型関連
using ll = long long;
using lint = long long;
using pll = pair<ll, ll>;
using plll = tuple<ll, ll, ll>;
using pii = pair<int, int>;
using piii = tuple<ll, ll, ll>;
template <class T> using prique = priority_queue<T>;

// 型定数
constexpr ll mod = 998244353;
constexpr ll MOD = 1000000007;
int INF32 = 2e9;
ll INF64 = 9e18;
#define endl '\n';

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

/////////////////////////// print関連
template <typename T> void print(vector<T> A);
void print();
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail);
void print(string S);
template <typename T> void print(vector<vector<T>> &F);

inline void Yes(bool f);

///////////////////ここから//////////////////////
bool solve() {

    int N, M, L, K, A, H;
    cin >> N >> M >> L >> K >> A >> H;
    if (N == 0) {
        return false;
    }
    unordered_set<int> LS;
    for (int i = 0; i < L; i++) {
        int l;
        cin >> l;
        LS.insert(l);
    }
    vector<vector<pii>> G(N);
    for (int i = 0; i < K; i++) {
        int a, b, t;
        cin >> a >> b >> t;
        G[a].emplace_back(b, t);
        G[b].emplace_back(a, t);
    }
    vector<vector<int>> dist(N, vector<int>(M + 1, INF32));
    vector<vector<int>> f(N, vector<int>(M + 1, 0));
    priority_queue<piii, vector<piii>, greater<piii>> que;
    que.emplace(0, A, M);
    dist[A][M] = 0;
    while (!que.empty()) {
        auto [d, v, m] = que.top();
        que.pop();
        if (f[v][m]) {
            continue;
        }
        f[v][m] = 1;
        
        if (LS.count(v) && m < M) {
            int nv = v, nm = m + 1;
            if (dist[nv][nm] > dist[v][m] + 1) {
                dist[nv][nm] = dist[v][m] + 1;
                que.emplace(d+1,nv, nm);
            }
        }
        for (auto [nv, t] : G[v]) {
            if (t > m) {
                continue;
            }
            int nm = m - t;
            if (dist[nv][nm] > dist[v][m] + t) {
                dist[nv][nm] = dist[v][m] + t;
                que.emplace(d+t,nv, nm);
            }
        }
    }

    int ans = INF32;
    for (int m = 0; m <= M; m++) {
        if (ans > dist[H][m]) {
            ans = dist[H][m];
        }
    }
    if (ans == INF32) {
        print("Help!");
    } else {
        print(ans);
    }

    return true;
}

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while (solve())
        ;
}

////////////////////print/////////////////////////
// 1次元ベクトルを出力する
template <typename T> void print(vector<T> A) {
    if (A.size() == 0) {
        return;
    }
    for (size_t i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}

// 2次元ベクトルを出力する
template <typename T> void print(vector<vector<T>> &F) {
    for (size_t i = 0; i < F.size(); i++) {
        for (size_t j = 0; j < F[i].size(); j++) {
            cout << F[i][j];
            if (j < F[i].size() - 1) {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

// 空白行を出力するprint
void print() { cout << endl; }

// 数値・文字列を空白区切りで出力する. print(a,b)など
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

void print(string S) { cout << S << endl; }

//////////////出力関連

inline void Yes(bool f) {
    if (f) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 250
memory_kb: 3968
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve() {
    int N, M, L, K, A, H;
    cin >> N >> M >> L >> K >> A >> H;
    if (N == 0 && M == 0 && L == 0 && K == 0 && A == 0 && H == 0) return false;
    vector<bool> hos(N);
    hos[A] = hos[H] = true;
    for (int u; L--; ) {
        cin >> u;
        hos[u] = true;
    }
    vector<vector<pair<int, int>>> G(N);
    for (int u, v, w; K--; ) {
        cin >> u >> v >> w;
        G[u].emplace_back(v, w);
        G[v].emplace_back(u, w);
    }
    vector<vector<int>> D(N, vector<int>(M + 1, 1 << 30));
    using T = tuple<int, int, int>;
    priority_queue<T, vector<T>, greater<T>> q;
    D[A][M] = 0;
    q.emplace(0, A, M);
    while (q.size()) {
        auto [d, u, m] = q.top();
        q.pop();
        for (auto [v, w] : G[u]) {
            if (m >= w && D[v][m - w] > d + w) {
                D[v][m - w] = d + w;
                q.emplace(d + w, v, m - w);
            }
        }
        if (hos[u] && m < M && D[u][m + 1] > d + 1) {
            D[u][m + 1] = d + 1;
            q.emplace(d + 1, u, m + 1);
        }
    }
    int ans = 1 << 30;
    for (int m = 0; m <= M; m++) {
        ans = min(ans, D[H][m]);
    }
    if (ans == 1 << 30) {
        cout << "Help!\n";
    } else {
        cout << ans << '\n';
    }
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 240
memory_kb: 3968
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
bool solve();
int main(){
    while(solve());
    return 0;
}

using pii = pair<int,int>;

bool solve(){
    int N, M, L, K, A, H;
    cin>>N>>M>>L>>K>>A>>H;
    if(N==0)return false;
    vector<bool> have_frz(N,false);
    for(int i=0;i<L;i++){
        int l;cin>>l;
        have_frz[l]=true;
    }
    vector<vector<pii>>G(N);
    for(int i=0;i<K;i++){
        int u,v,c;cin>>u>>v>>c;
        if(c>M)continue;
        G[u].push_back(pii(v,c));
        G[v].push_back(pii(u,c));
    }
    const int inf=1e8;
    vector dp(N,vector<int>(M+1,inf));
    priority_queue<pair<int,pii>,vector<pair<int,pii>>,greater<pair<int,pii>>>q;
    q.push(pair<int,pii>(0,pii(A,M)));
    dp[A][M]=0;
    while(!q.empty()){
        int u=q.top().second.first;
        int m=q.top().second.second;
        q.pop();
        for(auto [to,c]:G[u]){
            int nm=m-c;
            if(nm<0)continue;
            if(dp[to][nm]>dp[u][m]+c){
                dp[to][nm]=dp[u][m]+c;
                q.push(pair<int,pii>(dp[to][nm],pii(to,m-c)));
            }
        }
        if(have_frz[u])for(int i=1;;i++){
            int nm=m+i;
            if(nm>M)break;
            if(dp[u][nm]>dp[u][m]+i){
                dp[u][nm]=dp[u][m]+i;
                q.push(pair<int,pii>(dp[u][nm],pii(u,nm)));
            }            
        }
    }
    int ans=inf;
    for(int i=0;i<=M;i++)ans=min(ans,dp[H][i]);
    if(ans==inf){
        cout<<"Help!"<<endl;
    }else{
        cout<<ans<<endl;
    }
    return true;
}
accuracy: 1
time_ms: 320
memory_kb: 3840
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

bool solve(){
    int N, M, L, K, A, H; cin >> N >> M >> L >> K >> A >> H;
    // cerr << "# " << N << " " << M << " " << L << " " << K << " " << A << " " << H << endl;
    if(N == 0) return false;
    auto V = [&](int n, int m) -> int {return n * (M + 1) + m;};
    vector G(N * (M + 1), vector<pair<int, int>>{});
    for(int i = 0; i < L; ++i){
        int l; cin >> l;
        for(int j = 0; j < M; ++j){
            G[V(l, j)].emplace_back(V(l, j + 1), 1);
        }
    }
    for(int i = 0; i < K; ++i){
        int X, Y, T; cin >> X >> Y >> T;
        for(int j = T; j <= M; ++j){
            G[V(X, j)].emplace_back(V(Y, j - T), T);
            G[V(Y, j)].emplace_back(V(X, j - T), T);
        }
    }
    using P = pair<int, int>;
    priority_queue<P, vector<P>, greater<P>> que;
    int INF = 1 << 28;
    vector dist(N * (M + 1), INF);
    que.emplace(0, V(A, M));
    dist[V(A, M)] = 0;
    while(que.size()){
        auto [d, u] = que.top(); que.pop();
        if(dist[u] != d) continue;
        for(auto [v, c] : G[u]){
            if(d + c < dist[v]){
                // cerr << "# " << u << " -> " << v << " : " << c << endl;
                dist[v] = d + c;
                que.emplace(d + c, v);
            }
        }
    }
    // for(int i = 0; i < N; ++i){
    //     cerr << "#";
    //     for(int j = 0; j <= M; ++j){
    //         cerr << " " << dist[V(i, j)];
    //     }
    //     cerr << endl;
    // }
    int ans = INF;
    for(int j = 0; j <= M; ++j){
        ans = min(ans, dist[V(H, j)]);
    }
    if(ans == INF) cout << "Help!" << endl;
    else cout << ans << endl;
    return true;
}

int main(){
    while(1){
        if(!solve()) break;
    }
}
accuracy: 1
time_ms: 520
memory_kb: 5356
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll   = long long;
using edge = pair<int, ll>; // {to, w}

constexpr bool DEBUG = false;
constexpr ll INF     = 2e18;

ll solve(int N, int M, int L, int K, int S, int G) {
    vector<bool> frz(N, false);
    for (int i = 0; i < L; i++) {
        int u;
        cin >> u;
        frz[u] = true;
    }
    frz[S] = true;
    frz[G] = true;

    vector<vector<edge>> graph(N);
    for (int i = 0; i < K; i++) {
        int u, v, t;
        cin >> u >> v >> t;
        graph[u].emplace_back(v, t);
        graph[v].emplace_back(u, t);
    }

    vector<vector<ll>> dist(N, vector<ll>(M + 1, INF));
    priority_queue<tuple<ll, int, int>, vector<tuple<ll, int, int>>, greater<>> pq; // {cost, from, rem}
    dist[S][M] = 0;
    pq.emplace(0, S, M);
    while (!pq.empty()) {
        auto [cost, from, rem] = pq.top();
        pq.pop();
        if (cost > dist[from][rem]) {
            continue;
        }

        for (auto [to, w] : graph[from]) {
            ll next_rem  = rem - w;
            ll next_cost = cost + w;

            if (rem < w) {
                continue;
            }

            if (dist[to][next_rem] > next_cost) {
                dist[to][next_rem] = next_cost;
                pq.emplace(next_cost, to, next_rem);
            }
        }

        if (frz[from] && rem < M) {
            int to       = from;
            ll next_cost = cost + 1;
            ll next_rem  = rem + 1;
            if (dist[to][next_rem] > next_cost) {
                pq.emplace(next_cost, to, next_rem);
            }
        }
    }

    ll ans = INF;
    for (int rem = 0; rem <= M; rem++) {
        ans = min(ans, dist[G][rem]);
    }
    return ans;
}

int main() {
    while (true) {
        int N, M, L, K, A, H;
        cin >> N >> M >> L >> K >> A >> H;
        if (N == 0) {
            break;
        }
        ll ans = solve(N, M, L, K, A, H);
        if (ans == INF) {
            cout << "Help!" << endl;
        } else {
            cout << ans << endl;
        }
    }
}
accuracy: 1
time_ms: 370
memory_kb: 3840
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll   = long long;
using edge = pair<int, ll>; // {to, w}

constexpr bool DEBUG = false;
constexpr ll INF     = 2e18;

ll solve(int N, int M, int L, int K, int S, int G) {
    vector<bool> has_freeze(N, false);
    for (int i = 0; i < L; i++) {
        int u;
        cin >> u;
        has_freeze[u] = true;
    }
    has_freeze[S] = true;
    has_freeze[G] = true;

    vector<vector<edge>> graph(N);
    for (int i = 0; i < K; i++) {
        int u, v, t;
        cin >> u >> v >> t;
        graph[u].emplace_back(v, t);
        graph[v].emplace_back(u, t);
    }

    vector<vector<ll>> dist(N, vector<ll>(M + 1, INF));
    priority_queue<tuple<ll, int, int>, vector<tuple<ll, int, int>>, greater<>> pq; // {cost, from, rem}
    dist[S][M] = 0;
    pq.emplace(0, S, M);
    while (!pq.empty()) {
        auto [cost, from, rem] = pq.top();
        pq.pop();
        if (cost > dist[from][rem]) {
            continue;
        }

        for (auto [to, w] : graph[from]) {
            ll next_rem  = rem - w;
            ll next_cost = cost + w;

            if (rem < w) {
                continue;
            }

            if (dist[to][next_rem] > next_cost) {
                dist[to][next_rem] = next_cost;
                pq.emplace(next_cost, to, next_rem);
            }
        }

        if (has_freeze[from] && rem < M) {
            int to       = from;
            ll next_cost = cost + 1;
            ll next_rem  = rem + 1;
            if (dist[to][next_rem] > next_cost) {
                pq.emplace(next_cost, to, next_rem);
            }
        }
    }

    ll ans = INF;
    for (int rem = 0; rem <= M; rem++) {
        ans = min(ans, dist[G][rem]);
    }
    return ans;
}

int main() {
    while (true) {
        int N, M, L, K, A, H;
        cin >> N >> M >> L >> K >> A >> H;
        if (N == 0) {
            break;
        }
        ll ans = solve(N, M, L, K, A, H);
        if (ans == INF) {
            cout << "Help!" << endl;
        } else {
            cout << ans << endl;
        }
    }
}
accuracy: 1
time_ms: 370
memory_kb: 3968
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = LLONG_MAX / 4;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    while (true) {
        int N, M, L, K, A, H;
        cin >> N >> M >> L >> K >> A >> H;
        // 全てが0なら入力終了
        if (!cin || (N == 0 && M == 0 && L == 0 && K == 0 && A == 0 && H == 0))
            break;

        // 冷凍施設の有無を管理 (町ごと)
        vector<bool> has_freeze(N, false);
        for (int i = 0; i < L; i++) {
            int x; cin >> x;
            has_freeze[x] = true;
        }
        // 首都(A)と病院(H)も冷凍施設があるとみなす
        has_freeze[A] = has_freeze[H] = true;

        // グラフの隣接リスト (町uから町vへ移動時間t)
        vector<vector<pair<int,int>>> graph(N);
        for (int i = 0; i < K; i++) {
            int u, v, t;
            cin >> u >> v >> t;
            graph[u].emplace_back(v, t);
            graph[v].emplace_back(u, t);
        }

        // dist[u][r] = 残り鮮度r分で町uに到達するための最小時間
        vector<vector<ll>> dist(N, vector<ll>(M + 1, INF));
        // 優先度付きキュー (最小時間優先): (time, node, remaining)
        using T = tuple<ll,int,int>;
        priority_queue<T, vector<T>, greater<T>> pq;
        dist[A][M] = 0;          // 首都出発時は鮮度M分
        pq.emplace(0, A, M);

        // Dijkstra 法
        while (!pq.empty()) {
            auto [t, u, rem] = pq.top();
            pq.pop();
            if (t > dist[u][rem]) continue;

            // 1) 道路を移動する遷移
            for (auto &e : graph[u]) {
                int v = e.first;
                int cost = e.second;
                if (rem >= cost) {
                    int next_rem = rem - cost;
                    ll nt = t + cost;
                    if (nt < dist[v][next_rem]) {
                        dist[v][next_rem] = nt;
                        pq.emplace(nt, v, next_rem);
                    }
                }
            }
            // 2) 再冷凍する遷移 (冷凍施設があり、残り鮮度 < M の場合)
            if (has_freeze[u] && rem < M) {
                int next_rem = rem + 1;
                ll nt = t + 1;
                if (nt < dist[u][next_rem]) {
                    dist[u][next_rem] = nt;
                    pq.emplace(nt, u, next_rem);
                }
            }
        }

        // 病院(H)への到達時間の最小値を求める
        ll ans = INF;
        for (int rem = 0; rem <= M; rem++) {
            ans = min(ans, dist[H][rem]);
        }
        if (ans == INF) {
            cout << "Help!" << '\n';
        } else {
            cout << ans << '\n';
        }
    }
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 3968
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = LLONG_MAX / 4;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    while (true) {
        int N, M, L, K, A, H;
        cin >> N >> M >> L >> K >> A >> H;
        if (!cin || (N == 0 && M == 0 && L == 0 && K == 0 && A == 0 && H == 0))
            break;

        vector<bool> has_freeze(N, false);
        for (int i = 0; i < L; i++) {
            int x; cin >> x;
            has_freeze[x] = true;
        }
        has_freeze[A] = has_freeze[H] = true;

        vector<vector<pair<int,int>>> graph(N);
        for (int i = 0; i < K; i++) {
            int u, v, t;
            cin >> u >> v >> t;
            graph[u].emplace_back(v, t);
            graph[v].emplace_back(u, t);
        }

        vector<vector<ll>> dist(N, vector<ll>(M + 1, INF));
        using T = tuple<ll,int,int>;
        priority_queue<T, vector<T>, greater<T>> pq;
        dist[A][M] = 0;
        pq.emplace(0, A, M);

        while (!pq.empty()) {
            auto [t, u, rem] = pq.top();
            pq.pop();
            if (t > dist[u][rem]) continue;
            for (auto &e : graph[u]) {
                int v = e.first;
                int cost = e.second;
                if (rem >= cost) {
                    int next_rem = rem - cost;
                    ll nt = t + cost;
                    if (nt < dist[v][next_rem]) {
                        dist[v][next_rem] = nt;
                        pq.emplace(nt, v, next_rem);
                    }
                }
            }
            if (has_freeze[u] && rem < M) {
                int next_rem = rem + 1;
                ll nt = t + 1;
                if (nt < dist[u][next_rem]) {
                    dist[u][next_rem] = nt;
                    pq.emplace(nt, u, next_rem);
                }
            }
        }

        ll ans = INF;
        for (int rem = 0; rem <= M; rem++) {
            ans = min(ans, dist[H][rem]);
        }
        if (ans == INF) {
            cout << "Help!" << '\n';
        } else {
            cout << ans << '\n';
        }
    }
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 3968
final_rank: 3

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    #include <ext/pb_ds/assoc_container.hpp>
    using namespace __gnu_pbds;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    using P=pair<int,int>;
    using T=tuple<int,int,int>;
    const ll INF=1001001001; 
    const ll INFL=1e18;
    const ll mod=998244353;


    void solve(int n,int m,int l,int k,int a,int h){
        vector<int>frozen(n);
        rep(i,l){
            int p;
            cin>>p;
            frozen[p]=1;
        }
        vector<vector<P>>G(n);
        rep(i,k){
            int u,v,d;
            cin>>u>>v>>d;
            G[u].emplace_back(v,d);
            G[v].emplace_back(u,d);
        }
        vector<vector<int>>dist(n,vector<int>(m+1,INF));
        priority_queue<T,vector<T>,greater<T>>q;
        q.push(make_tuple(0,a,m));
        dist[a][m]=0;
        while(q.size()){
            auto[d,v,M]=q.top();q.pop();
            if(d>dist[v][M])continue;
            for(auto[u,nd]:G[v]){
                if(M-nd<0)continue;
                if(chmin(dist[u][M-nd],dist[v][M]+nd)){
                    q.push(make_tuple(dist[u][M-nd],u,M-nd));
                }
            }
            if(frozen[v]){
                for(int i=M+1;i<=m;i++){
                    if(chmin(dist[v][i],dist[v][M]+(i-M))){
                        q.push(make_tuple(dist[v][i],v,i));
                    }
                }
            }
        }
        int ans=INF;
        rep(i,m+1){
            chmin(ans,dist[h][i]);
        }
        if(ans==INF){
            cout<<"Help!"<<endl;
        }else{
            cout<<ans<<endl;
        }
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        
        while(1){
            int n,m,l,k,a,h;
            cin>>n>>m>>l>>k>>a>>h;
            if(n==0&&m==0&&l==0&&k==0&&a==0&&h==0){
                break;
            }
            solve(n,m,l,k,a,h);
        }
        return 0;
    }
accuracy: 1
time_ms: 300
memory_kb: 3968
final_rank: 9

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
while(1) {
    int N, M, L, K, S, G;
    cin >> N >> M >> L >> K >> S >> G;
    if (N == 0) return 0;
    vector<int> X;
    X.push_back(S), X.push_back(G);
    rep(i,0,L) {
        int _;
        cin >> _;
        X.push_back(_);
    }
    L += 2;
    vector<vector<int>> D1(N,vector<int>(N,inf));
    rep(i,0,N) D1[i][i] = 0;
    rep(i,0,K) {
        int s, t, c;
        cin >> s >> t >> c;
        chmin(D1[s][t], c);
        chmin(D1[t][s], c);
    }
    rep(k,0,N) {
        rep(i,0,N) {
            rep(j,0,N) {
                chmin(D1[i][j], D1[i][k] + D1[k][j]);
            }
        }
    }
    vector<vector<int>> D2(L,vector<int>(L,inf));
    rep(i,0,L) {
        rep(j,0,L) {
            if (D1[X[i]][X[j]] <= M) chmin(D2[i][j], D1[X[i]][X[j]]);
        }
    }
    rep(k,0,L) {
        rep(i,0,L) {
            rep(j,0,L) {
                chmin(D2[i][j], D2[i][k] + D2[k][j]);
            }
        }
    }
    if (D2[0][1] == inf) cout << "Help!" << endl;
    else cout << D2[0][1] + max(0,D2[0][1] - M) << endl;
}
}
accuracy: 1
time_ms: 530
memory_kb: 3620
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "./debug.hpp"
#else
#define debug(...)
#define print_line
#endif

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using pi = pair<int,int>;
using pl = pair<ll,ll>;
const int INF = 1e9 + 10;
const ll INFL = 4e18;
#define rep(i, a, b) for (ll i = (a); i < (ll)(b); i++)
#define all(x) x.begin(),x.end()

template <typename T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template <typename T> bool chmin(T &a, const T &b) { if (a > b) { a = b; return true; } return false; }

// --------------------------------------------------------

int D[101][101];

int main(){
	while(true){
		int N,M,L,K,A,H;cin>>N>>M>>L>>K>>A>>H;
		if(N==0)break;
		for(int i=0;i<N;i++)for(int j=0;j<=M;j++)D[i][j]=INF;
		vector<bool>cool(N,false);
		for(int i=0;i<L;i++){
			int l;cin>>l;
			cool[l]=true;
		}
		cool[A]=true;
		cool[H]=true;
		vector<vector<pair<int,int>>>G(N);
		for(int i=0;i<K;i++){
			int X,Y,T;cin>>X>>Y>>T;
			if(T>M)continue;
			G[X].push_back({Y,T});
			G[Y].push_back({X,T});
		}

		D[A][M]=0;
		using T=tuple<int,int,int>;
		priority_queue<T,vector<T>,greater<>>pq;
		pq.push({0,A,M});
		while(!pq.empty()){
			auto[time,now,rem]=pq.top();pq.pop();
			for(auto[nxt,cost]:G[now]){
				if(rem-cost>=0&&D[nxt][rem-cost]>time+cost){
					D[nxt][rem-cost]=time+cost;
					pq.push({time+cost,nxt,rem-cost});
				}
			}
			if(cool[now]&&rem+1<=M&&D[now][rem+1]>time+1){
				D[now][rem+1]=time+1;
				pq.push({time+1,now,rem+1});
			}
		}

		int ans=INF;
		for(int i=0;i<=M;i++)ans=min(ans,D[H][i]);

		if(ans==INF)cout<<"Help!"<<endl;
		else cout<<ans<<endl;
	}
}
accuracy: 1
time_ms: 310
memory_kb: 3380
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<long long>;
using vvl = vector<vector<long long>>; using vs = vector<string>;
using pl = pair<long long, long long>;
template <typename T> inline bool chmin(T& a, const T& b) {bool compare = a > b; if (a > b) a = b; return compare;}
template <typename T> inline bool chmax(T& a, const T& b) {bool compare = a < b; if (a < b) a = b; return compare;}
template<class T>using rp_queue=priority_queue<T,vector<T>,greater<T>>;
template <typename T> T gcd(T a, T b) {if (b == 0)return a; else return gcd(b, a % b);}
template <typename T> inline T lcm(T a, T b) {return a /gcd(a, b)*b;}
const ll INF = 1LL << 60;
const ld PI = acos(-1);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec);
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr);
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const pair<T, U> &pa);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp);
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp);
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl);
 
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
template <class... T> std::istream &operator>>(std::istream &is, std::tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa) { return os << '(' << pa.first << ',' << pa.second << ')'; }
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl
#define dbgif(cond, x) ((cond) ? std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl : std::cerr)
#else
#define dbg(x) ((void)0)
#define dbgif(cond, x) ((void)0)
#endif
void solve();
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout<<fixed<<setprecision(15);
  int num_tc = 1;
  //cin >> num_tc;
  rep(tc,num_tc){
    //cout << "Case #" << tc+1 << ": " ;// << endl;
    solve();
  }
}
//見切り発車で実装しては行けない．頭の中でコードが完全に出来上がるまで書き始めるな．
void solve(){
  while(true){
    ll N,M,L,K,A,H;
    cin>>N>>M>>L>>K>>A>>H;
    if(N==0&&M==0&&L==0&&K==0&&A==0&&H==0)return;
    set<ll> st;
    rep(i,L){
      ll r;cin>>r;
      st.insert(r);
    }
    vector<vector<pl>> G(N);
    rep(i,K){
      ll x,y,t;cin>>x>>y>>t;
      G[x].push_back({y,t});
      G[y].push_back({x,t});
    }
    //頑張ってダイクストラ
    //dist[i][残り時間] = 最小コスト
    vvl dist(N,vl(M+1,INF));
    dist[A][M]=0;
    //最短経路,場所,残りのうけつ
    rp_queue<tuple<ll,ll,ll>> que;
    que.push({0,A,M});
    while(!que.empty()){
      auto [d,a,m] = que.top();
      que.pop();
      //すでに最短経路があればいらない
      if(d>dist[a][m])continue;
      //再度輸血する
      if(st.count(a)&&m+1<=M&&chmin(dist[a][m+1],dist[a][m]+1)){
        que.push({dist[a][m+1],a,m+1});
      }
      for(auto [v,t]:G[a]){
        if(m-t>=0&&chmin(dist[v][m-t],dist[a][m]+t)){
          que.push({dist[v][m-t],v,m-t});
        }
      }
    }
    ll ans = INF;
    for(int j=0;j<=M;j++)chmin(ans,dist[H][j]);
    if(ans==INF)cout<<"Help!"<<endl;
    else cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 360
memory_kb: 3712
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long 
#define rep(i,n) for(ll i = 0;i < (ll)(n);i++)
const  ll INF = 1LL << 60;

void chmin(ll &a,ll b){
  if(a > b){
    a = b;
  }
}


ll warshal(vector<vector<ll>> &dist){
  ll siz =dist.size();
  rep(k,siz)rep(i,siz)rep(j,siz){
    if(i == j){
      chmin(dist[i][j],0LL);
    }
    if(dist[i][k] != INF && dist[k][j] != INF){
      chmin(dist[i][j],dist[i][k] + dist[k][j]);
    }
  }
  rep(i,siz){
    if(dist[i][i] < 0){
      return -1;
    }
  }
  return 1;
}

void solve(ll n,ll m,ll l,ll k,ll a,ll h){
  vector<ll> f(l);
  rep(i,l){
    cin >> f[i];
  }
  f.push_back(a);
  f.push_back(h);
  vector<vector<ll>> g(n,vector<ll>(n,INF));
  rep(i,k){
    ll x,y,c;
    cin >> x>> y >> c;
    g[x][y] = c;
    g[y][x] = c;
  }

  warshal(g);

  vector<vector<pair<ll,ll>>> gg(n);
  for(auto & p:f){
    for(auto & q:f){
      if(p == q)continue;
      if(g[p][q]  < INF){
        gg[p].push_back({q,g[p][q]});
      }
    }
  }
  

  vector<ll> dist(n,INF);
  queue<ll> que;
  dist[a] = 0;
  que.push(a);
  while(!que.empty()){
    ll now = que.front();
    que.pop();
    for(auto [i,cost]:gg[now]){

      if(cost <= m && dist[now] + cost < dist[i]){
        dist[i] = dist[now] + cost;
        que.push(i);
      }
    }
  }
  if(dist[h] == INF){
    cout << "Help!" << endl;
  }else{
    if(dist[h] <= m){
      cout << dist[h] << endl;
    }else{
      cout << dist[h] + (dist[h] - m) << endl;
    }
  }

}

int main(){
  while(true){
    ll n,m,l,k,a,h;
    cin >> n >> m >> l >> k >> a >> h;
    if(n + m + l + k + a + h == 0)break;
    solve(n,m,l,k,a,h);
  }
}
accuracy: 1
time_ms: 510
memory_kb: 3684
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)
#define Rep(i,a,b) for(int i=a;i<b;i++)
#define ALL(x) (x).begin(),(x).end()
#define dbgv(x); for(auto now : x) cout << now << " "; cout << endl;

struct UnionFind {
  vector<int> par;
  UnionFind(int n=0): par(n,-1) {}
  int find(int x) {
    if(par[x] < 0) return x;
    return par[x] = find(par[x]);
  }
  bool unite(int x, int y){
    x = find(x); y = find(y);
    if(x==y) return false;
    if(par[x] > par[y]) swap(x,y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  bool same(int x, int y) {return find(x) == find(y);}
  int size(int x) {return -par[find(x)];}
};

int main(){
    int n, m, l, k, a, h;
    while (1) {
        cin >> n >> m >> l >> k >> a >> h;
        if(n == 0) break;
        vector<vector<pair<int, int> > > g(n);
        vector<bool> heal(n);
        for (int i = 0; i < l; ++i) {
            int p;
            cin >> p;
            heal[p] = true;
        }
        for (int i = 0; i < k; ++i) {
            int u, v, c;
            cin >> u >> v >> c;
            g[u].emplace_back(v, c);
            g[v].emplace_back(u, c);
        }

        vector<vector<long long> > dist(n, vector<long long>(m + 1, 1LL<<60));
        priority_queue<tuple<long long, int, int>,vector<tuple<long long, int, int>>,greater<tuple<long long, int, int>>> pq;

        dist[a][m] = 0;
        pq.emplace(0, a, m);

        while (!pq.empty()) {
            auto [cd, cn, cl] = pq.top();
            pq.pop();
            if (dist[cn][cl] < cd) continue;
            if (heal[cn]) {
                for (int i = 1; cl + i <= m; ++i) {
                    if (dist[cn][cl + i] > dist[cn][cl] + i) {
                        dist[cn][cl + i] = dist[cn][cl] + i;
                        pq.emplace(dist[cn][cl + i], cn, cl + i);
                    }
                }
            }
            for (auto [nn, len] : g[cn]) {
                if (cl - len >= 0 && dist[nn][cl - len] > dist[cn][cl] + len) {
                    dist[nn][cl - len] = dist[cn][cl] + len;
                    pq.emplace(dist[nn][cl - len], nn, cl - len);
                }
            }
        }

        long long ans = *min_element(dist[h].begin(),dist[h].end());

        if (ans == (long long)1LL<<60) {
            cout << "Help!\n";
        } else {
            cout << ans << '\n';
        }
    }
}
accuracy: 1
time_ms: 420
memory_kb: 3704
final_rank: 11

code_snippet: #include <bits/stdc++.h>

int solve() {
    int n, max_blood, cold_n, m, s, g;
    std::cin >> n >> max_blood >> cold_n >> m >> s >> g;
    if (n == 0) return 1;
    std::vector graph(n, std::vector<std::pair<int, int>>());
    std::vector<bool> is_cold(n);
    for (int i = 0; i < cold_n; i++) {
        int u;
        std::cin >> u;
        is_cold[u] = true;
    }
    for (int i = 0; i < m; i++) {
        int u, v, w;
        std::cin >> u >> v >> w;
        graph[u].emplace_back(v, w);
        graph[v].emplace_back(u, w);
    }

    const int INF = 1e9;
    using P = std::tuple<int, int, int>;
    std::priority_queue<P, std::vector<P>, std::greater<P>> que;
    std::vector dist(n, std::vector<int>(max_blood + 1, INF));
    dist[s][max_blood] = 0;
    que.emplace(dist[s][max_blood], s, max_blood);
    while (!que.empty()) {
        auto [d, u, i] = que.top();
        que.pop();
        if (dist[u][i] < d) continue;
        if (is_cold[u] && i < max_blood) {
            if (dist[u][i + 1] > dist[u][i] + 1) {
                dist[u][i + 1] = dist[u][i] + 1;
                que.emplace(dist[u][i + 1], u, i + 1);
            }
        }
        for (auto [v, w]: graph[u]) {
            if (i - w >= 0 && dist[v][i - w] > dist[u][i] + w) {
                dist[v][i - w] = dist[u][i] + w;
                que.emplace(dist[v][i - w], v, i - w);
            }
        }
    }
    int ans = INF;
    for (int i = 0; i <= max_blood; i++) {
        ans = std::min(ans, dist[g][i]);
    }
    if (ans == INF) {
        std::cout << "Help!" << '\n';
    } else {
        std::cout << ans << '\n';
    }
    return 0;
}

int main() {
    while (!solve());
}
accuracy: 1
time_ms: 310
memory_kb: 3596
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
template <typename T = int>
struct Edge {
    int from, to;
    T cost;
    int idx;
    Edge()
        : from(-1), to(-1), cost(-1), idx(-1) {}
    Edge(int from, int to, T cost = 1, int idx = -1)
        : from(from), to(to), cost(cost), idx(idx) {}
    operator int() const {
        return to;
    }
};
template <typename T = int>
struct Graph {
    Graph(int N)
        : n(N), es(0), g(N) {}
    int size() const {
        return n;
    }
    int edge_size() const {
        return es;
    }
    void add_edge(int from, int to, T cost = 1) {
        assert(0 <= from and from < n);
        assert(0 <= to and to < n);
        g[from].emplace_back(from, to, cost, es);
        g[to].emplace_back(to, from, cost, es++);
    }
    void add_directed_edge(int from, int to, T cost = 1) {
        assert(0 <= from and from < n);
        assert(0 <= to and to < n);
        g[from].emplace_back(from, to, cost, es++);
    }
    inline vector<Edge<T>>& operator[](const int& k) {
        assert(0 <= k and k < n);
        return g[k];
    }
    inline const vector<Edge<T>>& operator[](const int& k) const {
        assert(0 <= k and k < n);
        return g[k];
    }

   private:
    int n, es;
    vector<vector<Edge<T>>> g;
};
template <typename T = int>
using Edges = vector<Edge<T>>;
template <typename T>
vector<pair<T, int>> dijkstra(const Graph<T>& g, const int s = 0) {
    int n = g.size();
    assert(0 <= s and s < n);
    vector<pair<T, int>> d(n, {numeric_limits<T>::max(), -1});
    priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> pq;
    d[s] = {0, -1};
    pq.push({0, s});
    while(!pq.empty()) {
        pair<T, int> p = pq.top();
        pq.pop();
        T dist = p.first;
        int cur = p.second;
        if(d[cur].first < dist) continue;
        for(const Edge<T>& edge : g[cur]) {
            if(d[edge.to].first > d[cur].first + edge.cost) {
                d[edge.to] = {d[cur].first + edge.cost, cur};
                pq.push({d[edge.to].first, edge.to});
            }
        }
    }
    return d;
}
int main(void) {
    while(1) {
        int n, m, l, k, a, h;
        cin >> n >> m >> l >> k >> a >> h;
        if(n == 0) break;
        Graph<int> g(n * (m + 1));
        rep(i, 0, l) {
            int x;
            cin >> x;
            rep(j, 0, m) {
                g.add_directed_edge(x * (m + 1) + j, x * (m + 1) + j + 1, 1);
            }
        }
        rep(i, 0, k) {
            int x, y, t;
            cin >> x >> y >> t;
            rep(j, 0, m + 1) {
                if(j - t < 0) continue;
                g.add_directed_edge(x * (m + 1) + j, y * (m + 1) + j - t, t);
                g.add_directed_edge(y * (m + 1) + j, x * (m + 1) + j - t, t);
            }
        }
        auto d = dijkstra(g, a * (m + 1) + m);
        int ans = 1e9;
        rep(i, 0, m + 1) {
            ans = min(ans, d[h * (m + 1) + i].first);
        }
        if(ans == 1e9) {
            cout << "Help!" << '\n';
        } else {
            cout << ans << '\n';
        }
    }
}
accuracy: 1
time_ms: 550
memory_kb: 6500
final_rank: 19

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

tuple<vl, vi> dijkstra(int s, int N, vv<pair<int, ll>> &g){
    using P = pair<ll, int>;
    vl dist(N, INF);
    vi bef(N);
    priority_queue<P, vc<P>, greater<P>> q;
    dist[s] = 0;
    q.push({0, s});
    while (!q.empty()){
        auto [c, now] = q.top();q.pop();
        if (dist[now] < c) continue;
        for (auto&& [nxt, nc]: g[now]) if (dist[nxt] > c + nc){
            dist[nxt] = c + nc;
            bef[nxt] = now;
            q.push({dist[nxt], nxt}); 
        }
    }
    return {dist, bef};
}

ll solve(int N, int M, int L, int K, int A, int H){
    vv<pair<int, ll>> g(N * (M + 1));
    rep(i, L){
        int v; cin >> v;
        rep(j, M) g[j * N + v].push_back({(j + 1) * N + v, 1});
    }
    rep(i, K){
        int x, y, t; cin >> x >> y >> t;
        rep(j, M + 1) if (j + t <= M){
            g[(j + t) * N + x].push_back({j * N + y, t});
            g[(j + t) * N + y].push_back({j * N + x, t});
        }
    }
    auto [dist, bef] = dijkstra(M * N + A, N * (M + 1), g);
    ll ans = INF;
    rep(j, M + 1) ans = min(dist[j * N + H], ans);
    return ans;
}

int main(){
    vc<ll> ans;
    while (true){
        int N, M, L, K, A, H; cin >> N >> M >> L >> K >> A >> H;
        if (N == 0) break;
        ans.push_back(solve(N, M, L, K, A, H));
    }
    for (auto x : ans){
        if (x == INF) cout << "Help!" << endl;
        else cout << x << endl;
    }
}
accuracy: 1
time_ms: 610
memory_kb: 6724
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define r(i, n) for (int i = 0; i < n; i++)
#define INF 1e9
using namespace std;

int main() {
  int n, m, l, k, a, h, t1, t2, t3;

  while (cin >> n >> m >> l >> k >> a >> h, n) {
    vector<bool> rei(n, false);
    rei[a] = rei[h] = true;
    int b[n][n], re, x[n][n];
    r(i, n) r(j, n) x[i][j] = b[i][j] = INF;
    r(i, l) cin >> re, rei[re] = true;
    r(i, k) cin >> t1 >> t2 >> t3, b[t1][t2] = b[t2][t1] = t3;
    r(o, n) r(i, n) r(j, n) b[i][j] = min(b[i][j], b[i][o] + b[o][j]);
    r(i, n) if (rei[i]) r(j, n) if (rei[j]) if (b[i][j] <= m)
      x[i][j] = b[i][j];
    r(o, n) if (rei[o]) r(i, n) if (rei[i]) r(j, n) if (rei[j]) 
      x[i][j] = min(x[i][j], x[i][o] + x[o][j]);
    if (x[a][h] >= INF)
      cout << "Help!" << endl;
    else if (x[a][h] < m)
      cout << x[a][h] << endl;
    else
      cout << x[a][h] * 2 - m << endl;
  }
}
accuracy: 1
time_ms: 680
memory_kb: 3164
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;

#define r(i, n) for (int i = 0; i < n; i++)
#define INF 1000000000

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n, m, l, k, a, h, t1, t2, t3;
    while (cin >> n >> m >> l >> k >> a >> h, n) {
        vector<int> rei(n, 0);
        rei[a] = rei[h] = 1;
        int b[n][n], re, x[n][n];
        r(i, n) r(j, n) x[i][j] = b[i][j] = INF;
        r(i, l) cin >> re, rei[re] = 1;
        r(i, k) cin >> t1 >> t2 >> t3, b[t1][t2] = b[t2][t1] = t3;
        r(o, n) r(i, n) r(j, n) b[i][j] = min(b[i][j], b[i][o] + b[o][j]);
        r(i, n) if (rei[i]) r(j, n) if (rei[j]) if (b[i][j] <= m)
            x[i][j] = b[i][j];
        r(o, n) r(i, n) r(j, n) x[i][j] = min(x[i][j], x[i][o] + x[o][j]);
        if (x[a][h] >= INF)
            cout << "Help!" << "\n";
        else if (x[a][h] < m)
            cout << x[a][h] << "\n";
        else
            cout << x[a][h] * 2 - m << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 1210
memory_kb: 3212
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#define r(i, n) for (int i = 0; i < n; i++)
#define INF 1e9
using namespace std;
int main() {
  int n, m, l, k, a, h, t1, t2, t3;
  while (cin >> n >> m >> l >> k >> a >> h, n) {
    set<int> q;
    q.insert(a), q.insert(h);
    int b[n][n], e, x[n][n];
    r(i, n) r(j, n) x[i][j] = b[i][j] = INF;
    r(i, l) cin >> e, q.insert(e);
    r(i, k) cin >> t1 >> t2 >> t3, b[t1][t2] = b[t2][t1] = t3;
    r(o, n) r(i, n) r(j, n) b[i][j] = min(b[i][j], b[i][o] + b[o][j]);
    r(i, n) if (q.count(i)) r(j, n) if (q.count(j)) if (b[i][j] <= m) x[i][j] =
        b[i][j];
    r(o, n) r(i, n) r(j, n) x[i][j] = min(x[i][j], x[i][o] + x[o][j]);
    if (x[a][h] >= INF)
      cout << "Help!" << endl;
    else if (x[a][h] < m)
      cout << x[a][h] << endl;
    else
      cout << x[a][h] * 2 - m << endl;
  }
}
accuracy: 1
time_ms: 750
memory_kb: 3164
final_rank: 16