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

constexpr int INF = 1e9;
constexpr int STORE = 0;

inline int RandTerm(int term) { return rand() % term; }

inline int RandMinTerm(int min, int term) { return min + rand() % (term - min); }

struct Order {
  int t, n, id, dst;
  bool is_ordered, is_put, is_achieved;
};

istream& operator>>(istream& is, Order& order) {
  is >> order.n;
  if (order.n) {
    is >> order.id >> order.dst;
    order.dst--;
  }
  return is;
}

struct Command {
  int raw;
};

ostream& operator<<(ostream& os, const Command& command) {
  os << command.raw + (command.raw != -1);
  return os;
}

struct Position {
  int u, v, du, dv;
};

struct Graph {
  int n;
  vector<vector<int>> adjacency_matrix, distance_matrix, next_node_matrix;

  Graph(int n)
      : n(n),
        adjacency_matrix(n, vector<int>(n, INF)),
        distance_matrix(n, vector<int>(n, INF)),
        next_node_matrix(n, vector<int>(n)) {
    for (int i = 0; i < n; i++) distance_matrix[i][i] = 0;
    for (auto& e : next_node_matrix) iota(e.begin(), e.end(), 0);
  }

  void AddEdge(int u, int v, int d) {
    adjacency_matrix[u][v] = adjacency_matrix[v][u] = d;
    distance_matrix[u][v] = distance_matrix[v][u] = d;
  }

  void Preprocess() {
    // Warshall-Floyd algorithm
    for (int k = 0; k < n; k++) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (distance_matrix[i][k] + distance_matrix[k][j] < distance_matrix[i][j]) {
            distance_matrix[i][j] = distance_matrix[i][k] + distance_matrix[k][j];
            next_node_matrix[i][j] = next_node_matrix[i][k];
          }
        }
      }
    }
  }

  int Distance(int i, int j) { return distance_matrix[i][j]; }

  int Distance(const Position& p, int i) { return min(distance_matrix[p.u][i] + p.du, distance_matrix[p.v][i] + p.dv); }

  Command CalculateCommand(const Position& position, const int destination_node) {
    if (position.du == 0 || position.dv == 0) {
      int i = position.du == 0 ? position.u : position.v;
      if (i == destination_node) return Command{-1};
      int j = next_node_matrix[i][destination_node];
      return Command{j};
    }
    int du = position.du + distance_matrix[position.u][destination_node];
    int dv = position.dv + distance_matrix[position.v][destination_node];
    return Command{du <= dv ? position.u : position.v};
  }

  bool SimulateCommand(Position& position, const Command& command) {
    if (command.raw == -1) return true;
    if (position.u == command.raw) {
      if (position.du == 0) return false;
      position.du--;
      position.dv++;
      return true;
    }
    if (position.v == command.raw) {
      if (position.dv == 0) return false;
      position.du++;
      position.dv--;
      return true;
    }
    if (position.du == 0) {
      if (adjacency_matrix[position.u][command.raw] == INF) return false;
      position = {position.u, command.raw, 1, adjacency_matrix[position.u][command.raw] - 1};
      return true;
    }
    if (position.dv == 0) {
      if (adjacency_matrix[position.v][command.raw] == INF) return false;
      position = {position.v, command.raw, 1, adjacency_matrix[position.v][command.raw] - 1};
      return true;
    }
    return false;
  }
};

int main() {
  // setup
  srand(0);

  // input
  int V, E, T;
  cin >> V >> E;
  Graph graph(V);
  for (int i = 0; i < E; i++) {
    int u, v, d;
    cin >> u >> v >> d;
    graph.AddEdge(u - 1, v - 1, d);
  }
  vector<int> f(V);
  int f_sum = 0;
  for (auto& e : f) {
    cin >> e;
    f_sum += e;
  }
  cin >> T;

  // solve
  graph.Preprocess();

  int distance_median;
  {
    vector<int> d(V);
    for (int i = 0; i < V; i++) d[i] = graph.Distance(STORE, i);
    sort(d.begin(), d.end());
    distance_median = d[V / 2];
  }

  int ordered_count = 0, put_count = 0, max_put_count = 0, achieved_count = 0;
  vector<Order> orders(T);
  Position position{STORE, STORE, 0, 0};

  vector<int> route;

  for (int t = 0; t < T; t++) {
    // input
    Order order;
    cin >> order;
    if (order.n) {
      order.t = t;
      order.is_ordered = true;
      orders[order.id - 1] = order;
      ordered_count++;
    }

    int n_put;
    cin >> n_put;
    vector<int> put_ids(n_put);
    for (auto& e : put_ids) cin >> e;
    for (auto e : put_ids) {
      orders[e - 1].is_ordered = false;
      orders[e - 1].is_put = true;
    }
    ordered_count -= n_put;
    put_count += n_put;
    max_put_count = max(max_put_count, put_count);

    // solve
    bool should_update_route = false;

    if (order.n) {
      auto it = find(route.begin(), route.end(), order.dst);
      if (it != route.end() &&
          find_if(orders.begin(), orders.end(), [t, it, &graph, distance_median, &f](const Order& e) {
            return e.is_put && e.dst == *it && graph.Distance(STORE, e.dst) <= distance_median && f[e.dst] < 2;
          }) == orders.end()) {
        route.erase(it);
      }
    }

    if (n_put > 0) {
      for (auto e : put_ids) {
        if (find(route.begin(), route.end(), orders[e - 1].dst) != route.end()) continue;
        route.insert(route.begin() + RandTerm(route.size() + 1), orders[e - 1].dst);
        should_update_route = true;
      }
    }

    if (should_update_route) {
      // auto route_partition = route.end();
      // if (t < int(0.95 * T)) route_partition = partition(route.begin(), route.end(), [&f](auto e) { return f[e] < 2;
      // });

      // traveling salesman problem
      int min_cost = 0;
      min_cost += graph.Distance(STORE, route.front());
      min_cost += graph.Distance(route.back(), STORE);
      for (int i = 0; i + 1 < route.size(); i++) min_cost += graph.Distance(route[i], route[i + 1]);

      for (int iteration = 0; iteration < (int)3e7; iteration++) {
        int l = RandTerm(route.size());
        int r = RandMinTerm(l + 1, route.size() + 1);

        // int m = route_partition - route.begin();
        // if (l < m && m < r) continue;

        int next_cost = min_cost;
        if (l == 0) {
          next_cost -= graph.Distance(STORE, route[l]);
          next_cost += graph.Distance(STORE, route[r - 1]);
        } else {
          next_cost -= graph.Distance(route[l - 1], route[l]);
          next_cost += graph.Distance(route[l - 1], route[r - 1]);
        }
        if (r == route.size()) {
          next_cost -= graph.Distance(route[r - 1], STORE);
          next_cost += graph.Distance(route[l], STORE);
        } else {
          next_cost -= graph.Distance(route[r - 1], route[r]);
          next_cost += graph.Distance(route[l], route[r]);
        }

        if (next_cost < min_cost) {
          min_cost = next_cost;
          reverse(route.begin() + l, route.begin() + r);
        }
      }
    }

    // output
    Command command{-1};
    int destination = route.empty() ? STORE : route.front();

    if (ordered_count > 0 && t + graph.Distance(position, STORE) >= int(0.95 * T)) {
      destination = STORE;
    }

    command = graph.CalculateCommand(position, destination);
    graph.SimulateCommand(position, command);

    cout << command << endl;

    // input
    string verdict;
    cin >> verdict;
    if (verdict == "NG") break;

    int n_archive;
    cin >> n_archive;
    vector<int> archive_ids(n_archive);
    for (auto& e : archive_ids) cin >> e;
    for (auto e : archive_ids) {
      orders[e - 1].is_put = false;
      orders[e - 1].is_achieved = true;

      auto it = find(route.begin(), route.end(), orders[e - 1].dst);
      if (it != route.end()) route.erase(it);
    }
    put_count -= n_archive;
    achieved_count += n_archive;
  }
}


Measured memory_bytes: 3284