#include <cassert>
#include <iostream>
#include <algorithm>
#include <vector>
#include <climits>
#include <memory>

#define ALL(a)  (a).begin(),(a).end()

using namespace std;

int cost[400][400];
int lowestCost[400][400];
int nextV[400][400];

int V, E;
int freq[400];

long long Tmax;
vector<int> orderedTime;
vector<int> orderedNo;
vector<int> orderedDst;

const int INF = INT_MAX;
const int TRY_N_SUB = 500;
const int WAIT_SIZE = 30;

long long calcSubScore(const int startTime, const vector<int>& indices) {
    long long score = 0;
    int curV = 0;
    int curTime = startTime;
    for (const int i : indices) {
        int vi = orderedDst[i];
        curTime += lowestCost[curV][vi];
        curV = vi;
        long long waiting = curTime - orderedTime[i];
        score += max(0LL, Tmax*Tmax - waiting*waiting);
    }
    return score;
}
void calcPath(const int startTime, vector<int>& ord_indices) {
    if (ord_indices.size() < 8) {
        // find opt
        sort(ALL(ord_indices));
        long long maxScore = 0;
        vector<int> answer;
        do {
            long long score = calcSubScore(startTime, ord_indices);
            if (maxScore < score) {
                maxScore = score;
                answer = ord_indices;
            }
        } while (next_permutation(ALL(ord_indices)));
        answer.swap(ord_indices);
        return;
    }
    int curV = 0;
    const auto begin = ord_indices.begin();
    for (int i=0; i<ord_indices.size(); i++) {
        auto bestIter = min_element(
            begin + i,
            ord_indices.end(),
            [&](int a, int b){
                int va = orderedDst[a];
                int vb = orderedDst[b];
                int acost = lowestCost[curV][va];
                int bcost = lowestCost[curV][vb];
                return acost < bcost;
            });
        curV = orderedDst[*bestIter];
        int tmp = *bestIter;
        *bestIter = ord_indices[i];
        ord_indices[i] = tmp;
    }

    if (ord_indices.size() <= 1) return;

    long long score = calcSubScore(startTime, ord_indices);
    for (int i=0; i<TRY_N_SUB; i++) {
        int swap0 = rand() % (ord_indices.size()-1); // 前N-1個
        int swap1 = 1 + rand() % (ord_indices.size()-1); // 後ろN-1個
        if (swap0 > swap1) {
            int tmp = swap0;
            swap0 = swap1;
            swap1 = tmp;
        }
        // assert(swap0 <= swap1 < size)
        if (swap0 == swap1) {
            // assert(swap0 == swap1 > 0)
            swap0--;
        }

        swap(ord_indices[swap0], ord_indices[swap1]);
        //reverse(begin+swap0, begin+swap1+1);
        long long scoreX = calcSubScore(startTime, ord_indices);
        if (scoreX < score) {
            swap(ord_indices[swap0], ord_indices[swap1]);
            //reverse(begin+swap0, begin+swap1+1);
        }
        else score = scoreX;
    }
}

void input() {
    for (int i=0; i<400; i++) {
        for (int j=0; j<400; j++) {
            if (i == j) cost[i][j] = 0;
            else cost[i][j] = INF;
        }
    }

    cin >> V >> E;
    for (int i=0; i<E; i++) {
        int u,v,d;
        cin >> u >> v >> d;
        cost[u-1][v-1] = d;
        cost[v-1][u-1] = d;
    }
    for (int i=0; i<V; i++) cin >> freq[i];
    
    cin >> Tmax;
}

void getdata(int i) {
    int Nnew;
    cin >> Nnew;
    for (int j=0; j<Nnew; j++) {
        int newid, d;
        cin >> newid >> d;
        if (lowestCost[0][d-1] != INF) {
            orderedNo.push_back(newid);
            orderedDst.push_back(d-1);
            orderedTime.push_back(i);
        }
    }
    int Nput;
    cin >> Nput;
    int putid;
    for (int i=0; i<Nput; i++) cin >> putid;
}

void senddata(int cmd) {
    if (cmd == -1) cout << -1 << endl;
    else cout << cmd+1 << endl;
    string verdict;
    int N;
    int id;
    cin >> verdict;
    if (verdict == "NG") exit(0);
    cin >> N;
    for (int i=0; i<N; i++) cin >> id;
}

void makeCostMap() {
    for (int i=0; i<400; i++) {
        for (int j=0; j<400; j++) {
            lowestCost[i][j] = cost[i][j];
        }
    }

    for (int i=0; i<400; i++) {
        for (int j=0; j<400; j++) {
            if (cost[i][j] != INF) nextV[i][j] = j;
            else nextV[i][j] = -1;
        }
    }

    for (int i=0; i<400; i++) {
        for (int j=0; j<400; j++) {
            for (int k=0; k<400; k++) {
                if (lowestCost[j][i] != INF && lowestCost[i][k] != INF
                    && lowestCost[j][k] > lowestCost[j][i] + lowestCost[i][k]) {
                    lowestCost[j][k] = lowestCost[j][i] + lowestCost[i][k];
                    nextV[j][k] = nextV[j][i];
                }
            }
        }
    }

    // for (int i=0; i<400; i++) {
    //     for (int j=0; j<400; j++) {
    //         if (lowestCost[i][j] == INF) {
    //             cerr << "[cost]could not go to " <<j << "from "<< i << "!" << endl;
    //         }
    //         if (nextV[i][j] == -1)
    //             cerr << "could not go to " <<j << "from "<< i << "!" << endl;
    //         else if (cost[i][nextV[i][j]] == INF)
    //             cerr << "invalid nextV!" << endl;
    //     }
    // }
}


void setCmd(vector<int>& cmd, int idx, int val) {
    if (idx < Tmax)
        cmd[idx] = val;
}
int waitUntilNextOrder(int startTime, int curOrderSize) {
    int time = startTime;
    while (time < Tmax) {
        getdata(time);
        if (curOrderSize < orderedNo.size()) return time;
        senddata(-1);
        time++;
    }
    return Tmax;
}

int updateOrders(int beforeOrderSize, vector<int>& ords) {
    for (int i=beforeOrderSize; i<orderedNo.size(); i++) ords.push_back(i);
    return orderedNo.size();
}

int deliver(int startTime, vector<int>& orders, vector<int>& cmd, long long& score) {
    calcPath(startTime, orders);
    int v = 0;
    int time = startTime;
    for (auto o : orders) {
        int dst = orderedDst[o];
        while (v != dst) {
            for (int i=0; i<cost[v][nextV[v][dst]]; i++) {
                assert(nextV[v][dst] != -1);
                assert(cost[v][nextV[v][dst]] != INF);
                setCmd(cmd, time, nextV[v][dst]);
                time++;
            }
            v = nextV[v][dst];
        }
        long long waiting = time - orderedTime[o];
        score += max(0LL, Tmax*Tmax - waiting*waiting);
    }
    int dst = 0;
    while (v != dst) {
        for (int i=0; i<cost[v][nextV[v][dst]]; i++) {
            assert(nextV[v][dst] != -1);
            assert(cost[v][nextV[v][dst]] != INF);
            setCmd(cmd, time, nextV[v][dst]);
            time++;
        }
        v = nextV[v][dst];
    }
    orders.clear();
    return time;
}

int main() {
    input();
    makeCostMap();

    cerr << "ready" << endl;
    long long score = 0;
    int curTime = 0;
    int nextTime = waitUntilNextOrder(curTime, 0);
    vector<int> orders;
    vector<int> bufCommand(Tmax);
    int nextOrder = updateOrders(0, orders);
    curTime = nextTime;

    while (1) {
        int nextTime = deliver(curTime, orders, bufCommand, score);
        for (int i=curTime; i<min((int)Tmax, nextTime); i++) {
            if (i > curTime) getdata(i);
            senddata(bufCommand[i]);
        }
        if (nextTime >= Tmax) break;
        nextOrder = updateOrders(nextOrder, orders);
        curTime = nextTime;
        if (orders.empty()) {
            int nextTime = waitUntilNextOrder(curTime, nextOrder);
            nextOrder = updateOrders(nextOrder, orders);
            curTime = nextTime;
            if (curTime >= Tmax) break;
        } else { getdata(curTime); }
    }
    return 0;
}



Measured memory_bytes: 3156