// May this submission get accepted!

#pragma GCC optimize ("O3")
#pragma GCC target ("tune=native")
#pragma GCC target ("avx")

#include <bits/stdc++.h>
#include <unordered_set>

constexpr bool DEBUG_MODE = false;
constexpr double TIMELIMIT_FACTOR = 1.0;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define DSRNG(i,is,ie) for (long long i=(is), i##_end=(ie); i>=i##_end; i--)
#define STEP(i, is, ie, step) for (long long i=(is), i##_end=(ie), i##_step = (step); i<=i##_end; i+=i##_step)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
template<class T> inline bool chmax(T &a, const T &b) {if (a < b) {a = b; return true;} return false; }
template<class T> inline bool chmin(T &a, const T &b) {if (a > b) {a = b; return true;} return false; }
#define INF 0x7FFFFFFF
#define LINF 0x7FFFFFFFFFFFFFFFLL
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define DUMP(q) cerr << "[DEBUG] " #q ": " << (q) << " at " __FILE__ ":" << __LINE__ << endl
#define DUMPALL(q) do { cerr << "[DEBUG] " #q ": ["; REP(i, (q).size()) { cerr << (q)[i] << (i == i_len-1 ? "" : ", "); } cerr << "] at " __FILE__ ":" << __LINE__ << endl; } while (false)
template<class T> T gcd(T a, T b) { if (a < b) std::swap(a, b); while (b) std::swap(a %= b, b); return a; }
template<class T> T lcm(const T a, const T b) { return a / gcd(a, b) * b; }

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// エイリアス
#define DANCE_ long
#define ROBOT_ unsigned
#define HUMAN_ signed
#define CHOKUDAI_ const
using  ll = DANCE_ HUMAN_ DANCE_;
using ull = DANCE_ ROBOT_ DANCE_;
using cll = DANCE_ DANCE_ CHOKUDAI_;
using  ld = long double;
using namespace std;

// モジュール

// マラソン用モジュール
namespace marathon {
    clock_t start_clock;
    constexpr double time_limit = 29.9 * TIMELIMIT_FACTOR; // 実行時間[s]より0.1ms程度余裕をあける
    constexpr double time_limit_inv = 1.0 / time_limit;
    constexpr double CLOCKS_PER_SEC_INV = 1.0 / CLOCKS_PER_SEC;
    inline double nowtime() { return CLOCKS_PER_SEC_INV * (clock() - start_clock); }
    inline bool intime() { return nowtime() < time_limit; }
    inline double progress() { return nowtime() * time_limit_inv; }
    struct preexec_dummy {
        preexec_dummy() {
            start_clock = clock();
        }
    } preexec_dummy_instance;
}

// XORShift 擬似乱数発生器
uint32_t xor128(void){

    static uint32_t x = 123456789;
    static uint32_t y = 362436069;
    static uint32_t z = 521288629;
    static uint32_t w = 88675123; 
    uint32_t t;

    t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
    
}
inline double rand_uniform(void) { return (double)xor128() / 0x100000000LL; }
template <typename T>
inline T rand_range(T min, T max) { return min + xor128() % (max - min + 1); }
inline bool rand_prob(double p) { return rand_uniform() < p; }
template <typename T>
pair<T, T> choose_two(const T size) {
    pair<T, T> p;
    p.first  = xor128() % size;
    p.second = xor128() % (size - (T)1);
    if (p.first <= p.second) p.second++;
    if (p.first > p.second) swap(p.first, p.second);
    return p;
}

// Union-Find モジュール
struct union_find {
    vector<ull> par;
    vector<ull> num;
    union_find(ull n) : par(n, 0), num(n, 1) { iota(ALL_OF(par), 0); }
    ull root(ull i) { return par[i] == i ? i : (par[i] = root(par[i])); }
    bool same(ull i, ull j) { return root(i) == root(j); }
    void unite(ull i, ull j) {
        ull ri = root(i);
        ull rj = root(j);
        if (ri != rj) {
            if (num[ri] > num[rj]) swap(ri, rj);
            par[ri] = rj;
            num[rj] += num[ri];
        }
    }
};

// 辺
struct edge {

    int src, dst, dist;

    edge(): dst(-1), dist(0) {}
    edge(int u, int v, int d) : src(u), dst(v), dist(d) {}

};

// 無向グラフ
struct undirected_graph {

    
    int vertex_num, edge_num;
    vector<edge> el; // 辺リスト
    vector<vector<edge>> gl; // 隣接リスト
    vector<vector<int>> gm; // 隣接行列
    vector<vector<int>> dm; // 距離行列
    vector<vector<int>> xm; // xm[i][j] := i -> j の最短経路における i の次の点
    vector<pair<double, double>> apx; // 平面に並べたときの座標

    undirected_graph() :
        vertex_num(0), edge_num(0),
        el(), gl(), gm() {}
    undirected_graph(const vector<edge> &_el) : el(_el)
    {
        vertex_num = 1 + accumulate(ALL_OF(el), 0, [](int ac, edge &e) { return max<int>({ac, e.src, e.dst}); });
        edge_num = el.size();
        gl = vector<vector<edge>>(vertex_num);
        gm = vector<vector<int>>(vertex_num, vector<int>(vertex_num, INF));
        xm = vector<vector<int>>(vertex_num, vector<int>(vertex_num, -1));
        for (edge &e : el) {
            gm[e.src][e.dst] = gm[e.dst][e.src] = e.dist;
            gl[e.src].emplace_back(e);
            gl[e.dst].emplace_back(e.dst, e.src, e.dist);
        }

        // Dijkstra O(|V|^2 log |V|)
        dm = vector<vector<int>>(vertex_num, vector<int>(vertex_num, INF));
        using pqitm = pair<int, int>; // {dist, vertex}
        REP(i, vertex_num) {
            priority_queue<pqitm> q;
            q.push(pqitm(dm[i][i] = 0, i));
            while (q.size()) {
                int ud, u; tie(ud, u) = q.top(); q.pop();
                if (dm[i][u] < ud) continue;
                for (const auto &e : gl[u]) {
                    const int alt = ud + e.dist;
                    if (chmin(dm[i][e.dst], alt)) {
                        xm[e.dst][i] = u;
                        q.push(pqitm(dm[i][e.dst], e.dst));
                    }
                }
            }
        }

        init_approx();

    }

    void init_approx() {

        apx = vector<pair<double, double>>(vertex_num);
        vector<pair<double, double>> vel(vertex_num, {0, 0});

        // 初期配置
        REP(i, vertex_num) {
            apx[i] = make_pair(rand_uniform() * 1000 - 500.0, rand_uniform() * 1000 - 500.0);
        }

        // シミュレーション
        constexpr double k = 0.01;
        REP(t, 1000) {
            REP(i, vertex_num) {
                for (edge &e : gl[i]) {
                    const ll j = e.dst;
                    const double dx = apx[j].first  - apx[i].first ;
                    const double dy = apx[j].second - apx[i].second;
                    const double d = max(1e-5, hypot(dx, dy));
                    const double a = k * (d - (double)e.dist) / d;
                    const double ax = dx * a;
                    const double ay = dy * a;
                    vel[i].first  += ax;
                    vel[i].second += ay;
                }
            }
            REP(i, vertex_num) {
                apx[i].first  += vel[i].first ;
                apx[i].second += vel[i].second;
            }
        }

    }

    inline int distance(const int u, const int v) const {
        assert(0 <= u && u < vertex_num);
        assert(0 <= v && v < vertex_num);
        return dm[u][v];
    }

    double approximate_distance(const int u, const int v) const {
        assert(0 <= u && u < vertex_num);
        assert(0 <= v && v < vertex_num);
        double dx = apx[u].first  - apx[v].first ;
        double dy = apx[u].second - apx[v].second;
        return hypot(dx, dy);
    }

    double arg_from_store(const int u) const {
        assert(0 < u && u < vertex_num);
        double dx = apx[u].first  - apx[0].first ;
        double dy = apx[u].second - apx[0].second;
        return atan2(dy, dx);
    }

    // to は含まれるが from は含まれない。注意
    vector<int> route(const int from, const int to) const {
        assert(0 <= from && from < vertex_num);
        assert(0 <= to   && to   < vertex_num);
        vector<int> r; r.reserve(vertex_num / 5);
        for (int x = from; x != to; ) {
            r.push_back(x = xm[x][to]);
        }
        return r;
    }

};

// 注文
struct order {
    int id, t0, dst;
    order() : id(-1), t0(INF), dst(-1) {}
    order(int i, int t, int u) : id(i), t0(t), dst(u) {}
};

// 注文データ
struct order_data {
    vector<order> o;
    order_data() : o() {}
    inline int count() const { return o.size(); }
};

// 入力
struct input_data {

    undirected_graph g;
    int tnow = 0;
    int tmax = 10000;
    order_data o;
    vector<int> f;
    unordered_set<int> load;
    vector<int> prio;
    int curr, dest, goal;
    int progress;
    map<int, int> iddst;

    input_data() : g() {}
    input_data(istream &ist) {

        // 空間情報
        int v, e; ist >> v >> e;
        vector<edge> el;
        REP(i, e) {
            int u, v, d;
            ist >> u >> v >> d;
            u--; v--; // 0-indexed
            el.emplace_back(u, v, d);
        }
        g = undirected_graph(el);

        // 頻度情報
        f = vector<int>(v);
        REP(i, v) ist >> f[i];

        // 時間情報
        tnow = 0;
        ist >> tmax;

        // 位置情報
        curr = 0;
        dest = -1;
        goal = -1;
        progress = 0;
        load = unordered_set<int>();
        iddst = map<int, int>();
        prio = vector<int>(g.vertex_num, INF);

    }

    void initialize_turn(istream &ist) {

        int nnew; ist >> nnew;
        REP(i, nnew) {
            int new_id, dst;
            ist >> new_id >> dst;
            new_id--; dst--;
            o.o.emplace_back(new_id, tnow, dst);
            iddst[new_id] = dst;
        }

        int nput; ist >> nput;
        REP(i, nput) {
            int put_id; ist >> put_id;
            put_id--;
            load.insert(put_id);
        }
        if (nput > 0) {

            vector<int> v; v.reserve(load.size());

            unordered_set<int> l2;
            for (int i : load) {
                int j = iddst[i];
                l2.insert(j);
            }

            // // Nearest Neighbor
            // while (l2.size()) {
            //     int curr = v.empty() ? 0 : v.back();
            //     int j, jmin = INF;
            //     for (int i : l2) {
            //         if (chmin<int>(jmin, g.distance(curr, i) * 5 + g.arg_from_store(i))) {
            //             j = i;
            //         }
            //     }
            //     l2.erase(j);
            //     v.push_back(j);
            // }

            // Greedy

            // vectorize
            int n = l2.size();
            vector<int> lv; lv.reserve(n);
            copy(ALL_OF(l2), back_inserter(lv));

            // edges
            vector<tuple<int, int, int>> e; // lvの添え字+1, 0は始点
            RANGE(i, 0, n-2) RANGE(j, i+1, n-1) {
                e.emplace_back(g.distance(lv[i], lv[j]), i+1, j+1);
            }
            REP(i, n) e.emplace_back(g.distance(0, lv[i]), 0, i+1);

            // kruskal
            union_find uf(n+1);
            vector<int> deg(n+1, 0);
            vector<vector<int>> sg(n+1);
            sort(ALL_OF(e));
            for (auto &ei : e) {
                int d, i, j; tie(d, i, j) = ei;
                if (deg[i] < 2 && deg[j] < 2 && !uf.same(i, j)) {
                    uf.unite(i, j);
                    deg[i]++; deg[j]++;
                    sg[i].push_back(j);
                    sg[j].push_back(i);
                }
            }
            int ef1 = -1, ef2 = -1;
            REP(i, n+1) if (deg[i] < 2) {
                (ef1 < 0 ? ef1 : ef2) = i;
            }
            sg[ef1].push_back(ef2);
            sg[ef2].push_back(ef1);

            // make the route
            vector<int> vst(n+1, 0);
            for (int i = 0; ; ) {
                vst[i] = true;
                if (i != 0) v.push_back(i);
                int ipre = i;
                for (int j : sg[i]) {
                    if (!vst[j]) {
                        i = j;
                        break;
                    }
                }
                if (i == ipre) break;
            }
            assert(v.size() == lv.size());
            for (int &i : v) i = i == 0 ? 0 : lv[i-1];

            vector<int> hst(v.size() + 1, 0);
            int hl = 0, hr = v.size() - 1;
            int hs = 0;

            auto get_score = [&, this](const vector<int> &v) -> int {
                if (hl <= hr) {
                    RANGE(j, hl, hr+1) {
                        const int a = j-1 == -1       ? 0 : v[j-1];
                        const int b = j   == v.size() ? 0 : v[j];
                        const int t = g.distance(a, b);
                        hs += t - hst[j];
                        hst[j] = t;
                    }
                    hl = INF; hr = -INF;
                }
                return hs;
            };

            // 2-opt
            if (v.size() > 1) {
                int score = get_score(v);
                REP(tr, 100000) {
                    int a, b; tie(a, b) = choose_two<int>(v.size());
                    reverse(v.begin() + a, v.begin() + b + 1);
                    chmin(hl, a); chmax(hr, b);
                    int s = get_score(v);
                    if (s < score) {
                        score = s;
                    } else {
                        reverse(v.begin() + a, v.begin() + b + 1);
                        chmin(hl, a); chmax(hr, b);
                    }
                }
            }
            REP(i, v.size()) {
                prio[v[i]] = i;
            }

        }

    }

    int suggest_goal() {
        if (load.size() != 0) {
            int r, dmin = INF;
            for (int i : load) {
                int j = iddst[i];
                // int d = g.distance(curr, j);
                int d = prio[j];
                if (chmin(dmin, d)) {
                    r = j;
                }
            }
            return r;
        } else {
            if (curr == 0) {
                int r = xor128() % (g.vertex_num - 1);
                return ++r;
            } else {
                return 0;
            }
        }
    }

    void act_turn(ostream &ost) {
        
        if (progress >= g.gm[curr][dest] || goal == -1) {
            if (dest == goal) {
                if (dest != -1) curr = dest;
                goal = suggest_goal();
                dest = g.xm[curr][goal];
                progress = 1;
            } else {
                progress = 1;
                curr = dest;
                dest = g.xm[dest][goal];
            }
        } else {
            progress++;
        }
        
        ost << dest+1 << endl;

    }

    void terminate_turn(istream &ist) {

        string verdict; ist >> verdict;
        if (verdict != "OK") {
            exit(EXIT_SUCCESS);
        }

        int nachieve; ist >> nachieve;
        REP(i, nachieve) {
            int achieve_id; ist >> achieve_id;
            achieve_id--;
            load.erase(achieve_id);
        }

    }

};
input_data inp;

// 処理内容
int main() {
    
    // まずは空間の情報から
    inp = input_data(cin);

    REP(t, inp.tmax) {
        inp.initialize_turn(cin);
        inp.act_turn(cout);
        inp.terminate_turn(cin);
    }
    
}

Measured memory_bytes: 5612