#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target ("sse4.2")

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <functional>
#include <numeric>
#include <random>
#include <chrono>
#include <cstring>
#include <climits>
#include <cassert>

#include <x86intrin.h>

using namespace std;

typedef long long int ll;

struct xorshift64 {
  unsigned long long int x = 88172645463325252ULL;
  inline unsigned short nextUShort() {
    x = x ^ (x << 7);
    return x = x ^ (x >> 9);
  }
  inline unsigned int nextUShortMod(unsigned long long int mod) {
    x = x ^ (x << 7);
    x = x ^ (x >> 9);
    return ((x & 0x000000000000ffff) * mod) >> 48;
  }
  inline unsigned int nextUInt() {
    x = x ^ (x << 7);
    return x = x ^ (x >> 9);
  }
  inline unsigned int nextUIntMod(unsigned long long int mod) {
    x = x ^ (x << 7);
    x = x ^ (x >> 9);
    return ((x & 0x00000000ffffffff) * mod) >> 32;
  }
  inline unsigned long long int nextULL() {
    x = x ^ (x << 7);
    return x = x ^ (x >> 9);
  }
  inline double nextDouble() {
    x = x ^ (x << 7);
    x = x ^ (x >> 9);
    return (double)x * 5.42101086242752217e-20;
  }
};

struct timer {
  double t = 0.0;
  inline void restart() {
    t = now();
  }
  inline double time() {
    return now() - t;
  }
  inline double now() {
    unsigned long long l, h;
    __asm__ ("rdtsc" : "=a"(l), "=d"(h));
    return (double)(l | h << 32) * 3.5714285714285715e-10; // 1 / 2.8e9
  }
};

//#define DEBUG

xorshift64 theRandom;
timer theTimer;

constexpr short tMax = 10000;
constexpr short vMax = 400;

short tNow = 0;

short V, E;

list<pair<short, short> > graphAdj[vMax];
short dist[vMax][vMax];
vector<short> route[vMax][vMax];

vector<vector<short> > order(vMax);
short orderCount[vMax];
short totalOrderCount;
short orderFrequency[vMax];

vector<short> visitOrder, bestVisitOrder;
short visitOrderLength;
short nowEnded, lastEnded;

void doTSP() {
  visitOrder = vector<short>();
  for (int i = 0; i < V; i++) visitOrder.push_back(i);
  visitOrderLength = visitOrder.size();

  auto calcTotalDist = [&]() {
    int totalDist = 0;
    for (int i = 1; i < visitOrder.size(); i++) totalDist += dist[visitOrder[i-1]][visitOrder[i]];
    totalDist += dist[visitOrder[visitOrderLength-1]][visitOrder[0]];
    return totalDist;
  };

  int score = calcTotalDist();
  int lastScore = score;
  int bestScore = score;

  double temperature = 1.0e1;
  double decayRate = 1.0e-6;

  double timeLimit = 2.000;

  int iterCount = 0;

  while (theTimer.time() < timeLimit) {
    if (theRandom.nextDouble() < 0.5) { // swap
      int v1 = theRandom.nextUIntMod(visitOrderLength-1) + 1;
      int v2 = theRandom.nextUIntMod(visitOrderLength-1) + 1;
      if (v1 == v2 || visitOrder[v1] == visitOrder[v2]) continue;
      swap(visitOrder[v1], visitOrder[v2]);

      score = calcTotalDist();

      #ifdef DEBUG
      if (iterCount % 10000 == 0) cerr << iterCount << " " << theTimer.time() << " " << score << " " << lastScore << " " << bestScore << " " << lastEnded << " " << temperature << endl;
      #endif

      if (score <= lastScore) {
        lastScore = score;
        if (score <= bestScore) {
          bestScore = score;
          bestVisitOrder = visitOrder;
        }
        lastEnded = nowEnded;
      }
      else if (theRandom.nextDouble() < exp((lastScore - score) / temperature)) { // accept
        lastScore = score;
        lastEnded = nowEnded;
      }
      else { // rollback
        swap(visitOrder[v1], visitOrder[v2]);
      }
    }
    else { // insert
      int v1 = theRandom.nextUIntMod(visitOrderLength-1) + 1;
      int v2 = theRandom.nextUIntMod(visitOrderLength-1) + 1;
      if (v1 == v2) continue;
      int tmp;
      tmp = visitOrder[v1];
      if (v1 < v2) {
        for (int i = v1; i < v2; i++) visitOrder[i] = visitOrder[i+1];
      }
      else {
        for (int i = v1; i > v2; i--) visitOrder[i] = visitOrder[i-1];
      }
      visitOrder[v2] = tmp;

      score = calcTotalDist();

      #ifdef DEBUG
      if (iterCount % 10000 == 0) cerr << iterCount << " " << theTimer.time() << " " << score << " " << lastScore << " " << bestScore << " " << lastEnded << " " << temperature << endl;
      #endif

      if (score <= lastScore) {
        lastScore = score;
        if (score <= bestScore) {
          bestScore = score;
          bestVisitOrder = visitOrder;
        }
        lastEnded = nowEnded;
      }
      else if (theRandom.nextDouble() < exp((lastScore - score) / temperature)) { // accept
        lastScore = score;
        lastEnded = nowEnded;
      }
      else { // rollback
        tmp = visitOrder[v2];
        if (v2 < v1) {
          for (int i = v2; i < v1; i++) visitOrder[i] = visitOrder[i+1];
        }
        else {
          for (int i = v2; i > v1; i--) visitOrder[i] = visitOrder[i-1];
        }
        visitOrder[v1] = tmp;
      }
    }

    iterCount++;
    temperature *= 1.0 - decayRate;
  }
}

ll calcScore() {
  short t = 0;
  ll score = 0;
  short now = 0;
  short lastSupply = 0;
  vector<short> delivered(V);
  short i = 0;
  for (i = 0; i < visitOrderLength; i++) {
    short next = visitOrder[i];
    /*
    if (delivered[next] >= orderCount[next]) continue; // order fulfilled
    if (lastSupply < order[next][delivered[next]]) { // no order yet
      for (short j = 1; j < route[now][0].size(); j++) {
        t += dist[route[now][0][j-1]][route[now][0][j]]; // move
        if (t > tMax) break; // out of time
        while (delivered[route[now][0][j]] < orderCount[route[now][0][j]]) {
          if (lastSupply >= order[route[now][0][j]][delivered[route[now][0][j]]]) {
            score += (tMax * tMax) - ((t - order[route[now][0][j]][delivered[route[now][0][j]]]) * (t - order[route[now][0][j]][delivered[route[now][0][j]]]));
            delivered[route[now][0][j]]++; // fill an order
          }
          else break;
        }
      }
      t = max(t, order[next][delivered[next]]);
      lastSupply = t;
      now = 0;
    }
    */
    for (short j = 1; j < route[now][next].size(); j++) {
      t += dist[route[now][next][j-1]][route[now][next][j]]; // move
      if (t > tMax) break; // out of time
      if (route[now][next][j] == 0) lastSupply = t; // resupply if arrived at store
      while (delivered[route[now][next][j]] < orderCount[route[now][next][j]]) {
        if (lastSupply >= order[route[now][next][j]][delivered[route[now][next][j]]]) {
          score += (tMax * tMax) - ((t - order[route[now][next][j]][delivered[route[now][next][j]]]) * (t - order[route[now][next][j]][delivered[route[now][next][j]]]));
          delivered[route[now][next][j]]++; // fill an order
        }
        else break;
      }
    }
    if (t > tMax) break; // out of time
    now = next;
  }
  nowEnded = i;
  return score;
}

vector<short> getAnswer() {
  short t = 0;
  ll score = 0;
  short now = 0;
  short lastSupply = 0;
  vector<short> delivered(V);
  vector<short> ans(tMax, -1);
  short i = 0;
  for (i = 0; i < visitOrderLength; i++) {
    short next = visitOrder[i];
    /*
    if (delivered[next] >= orderCount[next]) continue; // order fulfilled
    if (lastSupply < order[next][delivered[next]]) { // no order yet
      for (short j = 1; j < route[now][0].size(); j++) {
        short lastT = t;
        t += dist[route[now][0][j-1]][route[now][0][j]]; // move
        if (t > tMax) break; // out of time
        for (short k = lastT; k < t; k++) ans[k] = route[now][0][j] + 1;
        while (delivered[route[now][0][j]] < orderCount[route[now][0][j]]) {
          if (lastSupply >= order[route[now][0][j]][delivered[route[now][0][j]]]) {
            score += (tMax * tMax) - ((t - order[route[now][0][j]][delivered[route[now][0][j]]]) * (t - order[route[now][0][j]][delivered[route[now][0][j]]]));
            delivered[route[now][0][j]]++; // fill an order
          }
          else break;
        }
      }
      t = max(t, order[next][delivered[next]]);
      lastSupply = t;
      now = 0;
    }
    */
    for (short j = 1; j < route[now][next].size(); j++) {
      short lastT = t;
      t += dist[route[now][next][j-1]][route[now][next][j]]; // move
      if (t > tMax) break; // out of time
      if (route[now][next][j] == 0) lastSupply = t; // resupply if arrived at store
      for (short k = lastT; k < t; k++) ans[k] = route[now][next][j] + 1;
      while (delivered[route[now][next][j]] < orderCount[route[now][next][j]]) {
        if (lastSupply >= order[route[now][next][j]][delivered[route[now][next][j]]]) {
          score += (tMax * tMax) - ((t - order[route[now][next][j]][delivered[route[now][next][j]]]) * (t - order[route[now][next][j]][delivered[route[now][next][j]]]));
          delivered[route[now][next][j]]++; // fill an order
        }
        else break;
      }
    }
    if (t > tMax) break; // out of time
    now = next;
  }
  return ans;
}

void receiveOrder() {
  int newOrderCount;
  cin >> newOrderCount;
  for (int i = 0; i < newOrderCount; i++) {
    int _id, d;
    cin >> _id >> d;
    order[d-1].push_back(tNow);
    orderCount[d-1]++;
    totalOrderCount++;
  }
  int putItemCount;
  cin >> putItemCount;
  for (int i = 0; i < putItemCount; i++) {
    int _id;
    cin >> _id;
  }
}

void makeAction(int command) {
  // make action
  cout << command << endl;

  // update info
  string verdict;
  cin >> verdict;
  if (verdict == "NG") {
    cerr << "Fatal: NG verdict received on t = " << tNow << ", command = " << command << endl;
    exit(0);
  }
  int deliveredCount;
  cin >> deliveredCount;
  for (int i = 0; i < deliveredCount; i++) {
    int _id;
    cin >> _id;
  }

  tNow++;
  if (tNow < tMax) receiveOrder();
  else {
    cerr << "done" << endl;
    exit(0);
  }
}

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

  theTimer.restart();

  cin >> V >> E;
  for (int i = 0; i < E; i++) {
    int u, v, d;
    cin >> u >> v >> d;
    graphAdj[u-1].emplace_back(d, v-1);
    graphAdj[v-1].emplace_back(d, u-1);
  }
  for (int i = 0; i < V; i++) {
    cin >> orderFrequency[i];
  }
  int _tMax;
  cin >> _tMax;

  // receive first order
  receiveOrder();

  // calculate dist
  for (int i = 0; i < V; i++) {
    priority_queue<pair<int, vector<short> >, vector<pair<int, vector<short> > >, greater<pair<int, vector<short> > > > que;
    vector<bool> visited(V);
    que.emplace(0, vector<short>({i}));
    while (!que.empty()) {
      auto now = que.top();
      que.pop();
      int v = now.second[now.second.size()-1];
      if (visited[v]) continue;
      visited[v] = true;
      dist[i][v] = now.first;
      route[i][v] = now.second;
      for (auto &adj: graphAdj[v]) {
        auto next = now;
        next.first += adj.first;
        next.second.push_back(adj.second);
        que.push(next);
      }
    }
  }

  for (int i = 0; i < V; i++) {
    orderCount[i] = order[i].size();
    visitOrderLength += orderCount[i];
  }
  doTSP();
  for (int k = 1; k < 40; k++) {
    for (int i = 0; i < V; i++) visitOrder.push_back(visitOrder[i]);
  }
  visitOrderLength = visitOrder.size();
  bestVisitOrder = visitOrder;
  /*
  ll score = calcScore();
  ll lastScore = score;
  ll bestScore = score;
  lastEnded = nowEnded;

  double temperature = 1.0e8;
  double decayRate = 2.0e-5;

  double timeLimit = 29.900;

  int iterCount = 0;

  while (theTimer.time() < timeLimit) {
    if (theRandom.nextDouble() < 0.5) { // swap
      int v1 = theRandom.nextUIntMod(visitOrderLength);
      int v2 = theRandom.nextUIntMod(visitOrderLength);
      if (v1 == v2 || visitOrder[v1] == visitOrder[v2] || lastEnded < min(v1, v2)) continue;
      swap(visitOrder[v1], visitOrder[v2]);

      score = calcScore();

      #ifdef DEBUG
      if (iterCount % 10000 == 0) cerr << iterCount << " " << theTimer.time() << " " << score << " " << lastScore << " " << bestScore << " " << lastEnded << " " << temperature << endl;
      #endif

      if (score >= lastScore) {
        lastScore = score;
        if (score >= bestScore) {
          bestScore = score;
          bestVisitOrder = visitOrder;
        }
        lastEnded = nowEnded;
      }
      else if (theRandom.nextDouble() < exp((score - lastScore) / temperature)) { // accept
        lastScore = score;
        lastEnded = nowEnded;
      }
      else { // rollback
        swap(visitOrder[v1], visitOrder[v2]);
      }
    }
    else { // insert
      int v1 = theRandom.nextUIntMod(visitOrderLength);
      int v2 = theRandom.nextUIntMod(visitOrderLength);
      if (v1 == v2 || lastEnded < min(v1, v2)) continue;
      int tmp;
      tmp = visitOrder[v1];
      if (v1 < v2) {
        for (int i = v1; i < v2; i++) visitOrder[i] = visitOrder[i+1];
      }
      else {
        for (int i = v1; i > v2; i--) visitOrder[i] = visitOrder[i-1];
      }
      visitOrder[v2] = tmp;

      score = calcScore();

      #ifdef DEBUG
      if (iterCount % 10000 == 0) cerr << iterCount << " " << theTimer.time() << " " << score << " " << lastScore << " " << bestScore << " " << lastEnded << " " << temperature << endl;
      #endif

      if (score >= lastScore) {
        lastScore = score;
        if (score >= bestScore) {
          bestScore = score;
          bestVisitOrder = visitOrder;
        }
        lastEnded = nowEnded;
      }
      else if (theRandom.nextDouble() < exp((score - lastScore) / temperature)) { // accept
        lastScore = score;
        lastEnded = nowEnded;
      }
      else { // rollback
        tmp = visitOrder[v2];
        if (v2 < v1) {
          for (int i = v2; i < v1; i++) visitOrder[i] = visitOrder[i+1];
        }
        else {
          for (int i = v2; i > v1; i--) visitOrder[i] = visitOrder[i-1];
        }
        visitOrder[v1] = tmp;
      }
    }

    iterCount++;
    temperature *= 1.0 - decayRate;
  }

  visitOrder = bestVisitOrder;
  */
  vector<short> ans = getAnswer();
  /*
  cerr << "Final statistics:" << endl;
  cerr << "iterCount   = " << iterCount << endl;
  cerr << "bestScore   = " << bestScore << endl;
  cerr << "temperature = " << temperature << endl;
  cerr << "timeTaken   = " << theTimer.time() << endl;
  */
  for (auto &x: ans) makeAction(x);

  return 0;
}


Measured memory_bytes: 12624