#include <bits/stdc++.h>

using namespace std;

constexpr int Inf = 1e8;

int tsp_ord;

struct Edge
{
  int src, dst;
  long long weight;
  Edge(int src, int dst, long long weight)
      : src(src), dst(dst), weight(weight) {}

  bool operator<(const Edge &e) const { return weight > e.weight; }
};

using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;

auto input_graph()
{
  int n, m;
  cin >> n >> m;
  Graph g(n);
  for (int i = 0; i < m; ++i)
  {
    int u, v;
    long long cost;
    cin >> u >> v >> cost;
    u--, v--;
    g[u].emplace_back(u, v, cost);
    g[v].emplace_back(v, u, cost);
  }
  vector<int> f(n);
  for (int i = 0; i < n; ++i)
  {
    cin >> f[i];
  }
  return g;
}

auto prim(const Graph &g, int s)
{
  int n = g.size();
  Edges tree;
  long long total = 0;
  std::vector<int> visited(n, 0);
  std::priority_queue<Edge> q;
  q.emplace(-1, s, 0);
  while (!q.empty())
  {
    Edge e = q.top();
    q.pop();
    if (visited[e.dst])
      continue;
    if (e.src != -1)
      tree.push_back(e);
    total += e.weight;
    visited[e.dst] = true;
    for (auto f : g[e.dst])
    {
      if (!visited[f.dst])
        q.push(f);
    }
  }
  return std::pair<long long, Edges>(total, tree);
}

auto make_tour(const Edges &es)
{
  int n = es.size() + 1;
  Graph g(n);
  vector<int> tour;
  vector<bool> visited(n);
  for (const auto &e : es)
  {
    g[e.src].push_back(e);
  }
  stack<int> st;
  st.push(0);
  while (!st.empty())
  {
    int now = st.top();
    st.pop();
    visited[now] = true;
    tour.push_back(now);
    for (const auto &e : g[now])
    {
      if (visited[e.dst])
        continue;
      else
        st.push(e.dst);
    }
  }
  return tour;
}

struct Pos
{
  int u, v;
  int d_u, d_v;
};

void potential_method(const Graph &g, const vector<int> &tour)
{
  int n = g.size();
  vector<vector<int>> dist(n, vector<int>(n, Inf));
  vector<vector<int>> edge(n, vector<int>(n, Inf));
  for (int i = 0; i < n; ++i)
  {
    dist[i][i] = 0;
    for (const auto &e : g[i])
    {
      dist[e.src][e.dst] = e.weight;
      edge[e.src][e.dst] = e.weight;
    }
  }
  // warshall-floyd
  for (int k = 0; k < n; ++k)
  {
    for (int i = 0; i < n; ++i)
    {
      for (int j = 0; j < n; ++j)
      {
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
      }
    }
  }
  int T_max;
  cin >> T_max;
  int count = 0;
  int target = tour[count % n];
  vector<int> potential(n);
  potential = dist[target];
  vector<int> order(T_max);
  vector<bool> order_list(T_max);
  Pos now;
  now.u = now.v = 0;
  now.d_u = now.d_v = 0;
  bool opt = false;
  auto target_list = [&](int now) {
    vector<pair<int, int>> tsp;
    vector<bool> visited(n, 0);
    for (bool flag = 1; flag;)
    {
      visited[now] = true;
      int ret = 0, d_min = Inf;
      flag = 0;
      int x = 0;
      for (int j = 0; j < T_max; ++j)
      {
        if (order_list[j] && !visited[order[j]])
        {
          if (d_min > dist[order[j]][now])
          {
            d_min = dist[order[j]][now];
            ret = order[j];
          }
          flag = 1;
        }
      }
      tsp.emplace_back(now, ret);
      now = ret;
    }
    int N = tsp.size();
    for (int i = 0; i < N; ++i)
    {
      for (int j = i + 1; j < min(N, N); ++j)
      {
        if (dist[tsp[i].first][tsp[i].second] + dist[tsp[j].first][tsp[j].second] > dist[tsp[i].first][tsp[j].first] + dist[tsp[i].second][tsp[j].second])
        {
          swap(tsp[i].second, tsp[j].first);
          for (int k = i + 1; k < j; ++k)
          {
            swap(tsp[k].first, tsp[k].second);
          }
          for (int k = 1; k < N; ++k)
          {
            if (i + k > j - k)
              break;
            swap(tsp[i + k], tsp[j - k]);
            //swap(tsp[i+k].first,tsp[i+k].second);
            //if(i+k==j-k)break;
            //swap(tsp[j-k].first,tsp[j-k].second);
          }
        }
      }
    }
    vector<int> ret(n, 0);
    for (int i = 0; i < N; ++i)
    {
      ret[tsp[i].first] = tsp[i].second;
    }
    return ret;
  };
  vector<int> targets;
  for (int i = 0; i < T_max; ++i)
  {
    int n_order;
    cin >> n_order;
    for (int j = 0; j < n_order; ++j)
    {
      int id, dst;
      cin >> id >> dst;
      order[id] = dst - 1;
    }
    int n_put;
    cin >> n_put;
    if (n_put)
    {
      for (int j = 0; j < n_put; ++j)
      {
        int put_id;
        cin >> put_id;
        order_list[put_id] = true;
      }
      if (i > T_max - tsp_ord)
      {
        opt = true;
        targets = target_list(0);
      }
    }
    //cout<<n<<endl;
    ////////////////////////////////////// potential 法 /////////////////////////////////////////
    int ret = -1;
    // 頂点上にいる場合
    if (now.u == now.v)
    {
      double min_potential_div = 0;
      for (auto e : g[now.u])
      {
        if (min_potential_div > double(potential[e.dst] - potential[now.u]) / edge[now.u][e.dst])
        {
          min_potential_div = double(potential[e.dst] - potential[now.u]) / edge[now.u][e.dst];
          ret = e.dst;
        }
      }
    }
    // 辺上にいる場合
    else
    {
      if (potential[now.u] + now.d_u < potential[now.v] + now.d_v)
      {
        ret = now.u;
      }
      else
      {
        ret = now.v;
      }
    }

    if (ret != -1)
      cout << ret + 1 << endl;
    else
      cout << -1 << endl;

    // 現在位置の更新
    if (ret != -1)
    {
      // 頂点上にいる場合
      if (now.u == now.v)
      {
        now.v = ret;
        now.d_u = 1;
        now.d_v = dist[now.u][now.v] - now.d_u;
        if (now.d_v == 0)
        {
          now.u = now.v;
          now.d_u = 0;
        }
      }
      // 辺上にいる場合
      else
      {
        if (ret == now.u)
        {
          now.d_u--;
          now.d_v++;
          if (now.d_u == 0)
          {
            now.v = now.u;
            now.d_v = 0;
          }
        }
        if (ret == now.v)
        {
          now.d_u++;
          now.d_v--;
          if (now.d_v == 0)
          {
            now.u = now.v;
            now.d_u = 0;
          }
        }
      }
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////

    string judge;
    cin >> judge;
    if (judge == "NG")
      return;
    int n_achieve;
    cin >> n_achieve;
    for (int j = 0; j < n_achieve; ++j)
    {
      int achieve_id;
      cin >> achieve_id;
      if (order_list[achieve_id])
      {
        order_list[achieve_id] = false;
      }
    }
    if (now.u == now.v && now.u == target)
    {
      if (opt)
      {
        target = targets[target];
        potential = dist[target];
        continue;
      }
      if (i + dist[target][0] > T_max - tsp_ord)
      {
        target = 0;
        potential = dist[target];
        continue;
      }
      vector<bool> customer(n, false);
      for (int j = 0; j < T_max; ++j)
      {
        if (order_list[j])
        {
          customer[order[j]] = true;
        }
      }
      // target の更新
      customer[0] = true;
      for (int j = 1; j <= n; ++j)
      {
        if (customer[tour[(count + j) % n]])
        {
          count += j;
          target = tour[count % n];
          break;
        }
      }
      //target = tour[++count % n];
      potential = dist[target];
      //
    }
  }
  int rest = 0;
  for (auto f : order_list)
  {
    if (f)
      rest++;
  }
  cout << rest << endl;
}

void solve()
{
  // input graph
  auto graph = input_graph();

  // construct min_cost_tree
  auto min_tree = prim(graph, 0);
  tsp_ord = 2 * min_tree.first;
  //cout<<min_tree.first<<endl;

  auto tour = make_tour(min_tree.second);
  //cout<<tour.size()<<endl;
  /*
  for (auto x : tour)
  {
    cout << x << endl;
  }
  */

  potential_method(graph, tour);
}

int main()
{
  solve();
}


Measured memory_bytes: 2512