#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> Path;

const int INF = (1<<28);
const ll INFL = (1LL<<60);
const double MAX_TIME = 29.75;
const bool TIME_LIMIT_ON = true;

const int MNN = 400;            // MAX_NODE_NUM
const double INI_TEMP = 100;
const int SKIP_NUM = 1;

const double MAX_RATIO = 4;
const double TOTAL_TIME_WEIGHT = 3.8;

ll SCORE = 0;
clock_t START, END;

bool timeCheck() {
  clock_t NOW_TIME = clock();
  return (double)(NOW_TIME - START)/CLOCKS_PER_SEC < MAX_TIME;
}


class Edge{
public:
  int from, to, cost;

  Edge() : cost(INF) {}
  Edge(const Edge &e) : from(e.getFrom()), to(e.getTo()), cost(e.getCost()) {}
  Edge(int s, int t, int d) : from(s), to(t), cost(d) {}

  int getFrom() const {
    return from;
  }
  int getTo() const {
    return to;
  }
  int getCost() const {
    return cost;
  }
};

class Graph {
public:
  int N, M, M2;
  vector<vector<Edge>> edges;
  vector<vector<Edge>> edges2;
  vector<vector<int>> dists;
  vector<vector<Path>> paths;
  vector<set<int>> clusters;
  vector<int> labels;

  Graph() {}
  Graph(const Graph &g) : N(g.getN()), M(g.getM()), M2(g.getM()),
                          edges(g.getEdges()), edges2(g.getEdges2()),
                          dists(g.getDists()), paths(g.getPaths()),
                          clusters(g.getClusters()), labels(g.getLabels()) {}
  Graph(int _N, int _M) : N(_N), M(_M), M2(_M),
                          edges(N, vector<Edge>(N, Edge())),
                          dists(N, vector<int>(N, INF)),
                          paths(N, vector<vector<int>>(N)), labels(N) {}

  void input() {
    for (int i = 0; i < M; i++) {
      int s, t, d;
      scanf("%d %d %d", &s, &t, &d);
      s--; t--;
      edges[s][t] = Edge(s, t, d);
      edges[t][s] = Edge(t, s, d);
    }
  }

  void init() {
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        if (edges[i][j].cost == INF) continue;
        dists[i][j] = dists[j][i] = edges[i][j].cost;

        Path p1, p2;
        p1.push_back(i); p1.push_back(j);
        p2.push_back(j); p2.push_back(i);
        paths[i][j] = p1;
        paths[j][i] = p2;
      }
      dists[i][i] = 0;
      paths[i][i] = Path(1, i);
    }
    for (int k = 0; k < N; k++) {
      for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
          int tmp = dists[i][k] + dists[k][j];
          if (tmp < dists[i][j]) {
            dists[i][j] = tmp;

            Path path = paths[i][k];
            path.insert(path.end(), paths[k][j].begin()+1, paths[k][j].end());
            paths[i][j] = path;
          }
        }
      }
    }
  }

  bool remove(int a, int b) {
    if (edges2[a][b].cost == INF) return false;
    edges2[a][b] = Edge();
    edges2[b][a] = Edge();
    M2 = M2 - 1;
    return true;
  }

  vector<int> getCentroids(int C = 1) {
    vector<int> res;

    int mn = INF, center_node = 0;
    for (int i = 0; i < N; i++) {
      int sum = 0;
      for (int j = 0; j < N; j++) {
        sum += dists[i][j] * dists[i][j];
      }
      if (sum < mn) {
        mn = sum;
        center_node = i;
      }
    }
    res.push_back(center_node);

    for (int c = 0; c < 4*C; c++) {
      int mx = 0, next = 0;
      for (int i = 0; i < N; i++) {
        int sum = 0;
        for (int j = 0; j < res.size(); j++) {
          sum += dists[res[j]][i];
        }
        if (sum > mx) {
          mx = sum;
          next = i;
        }
      }
      // cerr << next << endl;
      res.push_back(next);
    }
    reverse(res.begin(), res.end());
    res.pop_back();
    return res;
  }

  void makeClusters(int C = 1) {
    vector<int> cents = getCentroids(C);
    clusters.resize(cents.size());
    for (int i = 0; i < N; i++) {
      int mn = INF, l = -1;
      for (int c = 0; c < cents.size(); c++) {
        if (dists[i][cents[c]] < mn) {
          mn = dists[i][cents[c]];
          l = c;
        }
      }
      labels[i] = l;
      clusters[l].insert(i);
    }
  }

  void output() {
    cout << N << " " << M2 << '\n';
    for (int i = 0; i < N; i++) {
      for (int j = i+1; j < N; j++) {
        if (edges2[i][j].cost != INF) {
          cout << i+1 << " " << j+1 << " " << edges2[i][j].cost << '\n';
        }
      }
    }
  }

  int getN() const {
    return N;
  }
  int getM() const {
    return M;
  }
  vector<vector<Edge>> getEdges() const {
    return edges;
  }
  vector<vector<Edge>> getEdges2() const {
    return edges2;
  }
  vector<vector<int>> getDists() const {
    return dists;
  }
  vector<vector<Path>> getPaths() const {
    return paths;
  }
  vector<set<int>> getClusters() const {
    return clusters;
  }
  vector<int> getLabels() const {
    return labels;
  }
};


class Order {
public:
  int ID, DST;
  int t;

  Order() {}
  Order(const Order &o) : ID(o.getID()), DST(o.getDST()), t(o.getT()) {}
  Order(int _ID, int _DST, int _t) : ID(_ID), DST(_DST), t(_t) {}

  int getID() const {
    return ID;
  }
  int getDST() const {
    return DST;
  }
  int getT() const {
    return t;
  }
};

class OrderList {
public:
  int T;
  vector<Order> list;

  OrderList() {}
  OrderList(const OrderList &ol) : T(ol.getT()), list(ol.getList()) {}
  OrderList(int _T) : T(_T), list(T) {}
  void input() {
    for (int t = 0; t < T; t++) {
      int n; scanf("%d", &n);
      int id, dst;
      if (n == 0) {
        id = dst = INF;
      } else {
        scanf("%d %d", &id, &dst);
        dst--;
      }
      list[t] = Order(id, dst, t);
    }
  }
  void init() {}

  int getT() const {
    return T;
  }
  vector<Order> getList() const {
    return list;
  }
};



class Solver {
public:
  double MAX_ITER = 1000;
  double RATIO;
  int MAX_Iter;                   // 温度変更回数(600?)
  Graph G;
  OrderList ol;
  Path ans;

  int time;
  vector<ll> pow2;

  Solver(Graph _G, OrderList _ol) : time(0), G(_G), ol(_ol), pow2(ol.T+1) {
    int x = 300;
    MAX_ITER /= (double)(G.N+x) / (MNN+x);
    // cerr << "MAX_ITER: " << MAX_ITER << '\n';
    MAX_Iter = ceil(MAX_ITER * G.N / MNN);

    RATIO = MAX_RATIO * (G.N - MNN/2) / (MNN/2) + 1.0;

    for (int i = 0; i < ol.T+1; i++) pow2[i] = pow(i, 2);
  }

  double exchange_probability(double diff, double temp){
    return exp(-diff / temp);
  }

  double calc_temperature(int iteration){
    return (double)INI_TEMP - pow(INI_TEMP, double(iteration)/MAX_Iter);
  }

  // TODO : 最適化
  vector<int> init_order(vector<vector<Order>> orders) {
    int now = 0;
    vector<int> dest_order;
    vector<bool> go(G.N, false);
    for (int i = 0; i < G.N; i++) {
      go[i] = !orders[i].empty();
    }
    for (int i = 0; i < G.N; i++) {
      int mn = INF, next = -1;
      for (int j = 0; j < G.N; j++) {
        if (go[j] && G.dists[now][j] < mn) {
          mn = G.dists[now][j];
          next = j;
        }
      }
      if (next == -1) break;
      go[next] = false;
      dest_order.push_back(next);
      now = next;
    }
    return dest_order;
  }

  // TODO : 高速化
  Path make_path(int s, vector<int> dest_order, int t) {
    int now = s, next = dest_order[0];
    Path path(1, s);
    if (t != -1) dest_order.push_back(t);

    for (int i = 0; i < dest_order.size(); i++) {
      next = dest_order[i];

      Path now_to_next = G.paths[now][next];
      for (int j = 1; j < now_to_next.size(); j++) {
        next = now_to_next[j];
        path.push_back(next);
      }
      now = next;
    }
    return path;
  }

  // TODO : 高速化
  pair<ll, ll> evaluate_path(Path path, vector<vector<Order>> orders) {
    ll score = 0, ori_score = 0;
    int len = path.size();
    int t = time, pre_t = time;

    // 目的地に届けた注文
    for (int i = 1; i < len; i++) {
      int from = path[i-1], to = path[i];
      t += G.dists[from][to];
      if (t >= ol.T) {
        t = ol.T-1;
        break;
      }
      if (to == 0) {
        for (int ti = pre_t+1; ti <= t; ti++) {
          int dest = ol.list[ti].DST;
          if (dest != INF) {
            orders[dest].push_back(ol.list[ti]);
          }
        }
        pre_t = t;
        continue;
      }
      for (int j = 0; j < orders[to].size(); j++) {
        ori_score += pow2[ol.T] - pow2[t - orders[to][j].t];

        score += pow2[ol.T] - pow2[t - orders[to][j].t];
      }
      orders[to].clear();
    }

    // かかった時間の評価
    ll total_time = t - time;
    score -= pow(total_time, TOTAL_TIME_WEIGHT);

    return make_pair(score, ori_score);
  }

  // TODO : 高速化、温度による許容の部分
  Path search_path(vector<vector<Order>> orders, int s, int t) {
    // 初期値の決定
    vector<int> dest_order = init_order(orders);

    ll parcel_num = 0;
    for (int i = 0; i < G.N; i++) {
      parcel_num += orders[i].size();
    }

    // simulated annealing
    Path res_path;
    if (!dest_order.empty()) {
      res_path = make_path(s, dest_order, t);
    } else {
      return res_path;
    }
    pair<ll, ll> score_oriscore = evaluate_path(res_path, orders);

    ll pre_score = score_oriscore.first;
    ll ori_score = score_oriscore.second;

    ll max_score = pre_score;
    // cerr << "first score: " << ori_score << '\n';

    if (TIME_LIMIT_ON && !timeCheck()) {
      cerr << "=========== time over ===========" << '\n';
      return res_path;
    }

    random_device seed;
    mt19937 mt(seed());
    uniform_real_distribution<> rand01(0.0, 1.0);

    int N = dest_order.size();  // 最大ノード数(<=400)以下
    for (int iter = 0; iter < MAX_Iter; iter++) {
      double temp = calc_temperature(iter+1);

      int NUM = ceil((double)N / RATIO);
      for (int c = 0; c < NUM-1; c++) {
        uniform_int_distribution<> rand0X(0, N-2);
        int i = rand0X(mt);
        uniform_int_distribution<> randXN(i+1, N-1);
        int j = randXN(mt);
        // cerr << "(i, j) = (" << i << ", " << j << ")\n";
        vector<int> new_order = dest_order;
        if (rand01(mt) <= 0.5) {
          swap(new_order[i], new_order[j]);
        } else {
          reverse(new_order.begin()+i, new_order.begin()+j+1);
        }

        Path new_path = make_path(s, new_order, t);
        score_oriscore = evaluate_path(new_path, orders);
        ll new_score = score_oriscore.first;
        ll pre_ori   = score_oriscore.second;

        ll diff = new_score - pre_score;
        if (diff > 0) {
          // cerr << "pre_score: " << pre_score << ", new_score: " << new_score << '\n';
          dest_order = new_order;
          pre_score = new_score;
          if (new_score > max_score) {
            max_score = new_score;
            res_path = new_path;
            ori_score = pre_ori;
            // cerr << "max_score: " << max_score << '\n';
          }
        } else if (diff < 0) {
          double prob = exchange_probability(-diff, temp * parcel_num*ol.T*100);
// if (parcel_num > 600) cerr << "parcel_num: " << parcel_num << ", temp: " << temp << ", prob: " << prob << '\n';
          if (prob > rand01(mt)) {
            dest_order = new_order;
            pre_score = new_score;
          }
        }
      }
    }
    // cerr << "last score : " << ori_score << '\n';
    return res_path;
  }

  void execute(Path path, vector<Order> &ordlist, vector<Order> &waitinglist) {
    int len = path.size();
    int now_node = path[0];
    for (int i = 1; i < len; i++) {
      int next_node = path[i];
      int dt = G.edges[now_node][next_node].cost;
      for (int t = time; t < min(time+dt, ol.T-1); t++) {
        ans.push_back(next_node+1);
        Order ord = ol.list[t+1];
        if (ord.ID != INF) {
          waitinglist.push_back(ord);
        }
      }
      time += dt;

      if (next_node == 0) {
        ordlist.insert(ordlist.end(), waitinglist.begin(), waitinglist.end());
        waitinglist.clear();
      } else {
        for (int j = ordlist.size()-1; j >= 0; j--) {
          if (ordlist[j].DST == next_node) {
            ordlist.erase(ordlist.begin() + j);
          }
        }
      }
      now_node = next_node;
    }
  }


  // vector<Order> execute(Path path, vector<Order> ordlist, bool print) {
  //   vector<Order> waiting_orders;
  //   int len = path.size();
  //   int now_node = path[0];
  //   int ex_time = time;
  //   for (int i = 1; i < len; i++) {
  //     int next_node = path[i];
  //     int dt = G.edges[now_node][next_node].cost;
  //     for (int t = ex_time; t < min(ex_time+dt, ol.T); t++) {
  //       if (print) {
  //         ans.push_back(next_node+1);
  //         time++;
  //       }
  //       Order ord = ol.list[t+1];
  //       if (ord.ID != INF) {
  //         waiting_orders.push_back(ord);
  //       }
  //     }
  //     ex_time += dt;

  //     if (next_node == 0) {
  //       for (int j = 0; j < waiting_orders.size(); j++) {
  //         ordlist.push_back(waiting_orders[j]);
  //       }
  //       waiting_orders.clear();
  //     } else {
  //       for (int j = ordlist.size()-1; j >= 0; j--) {
  //         if (ordlist[j].DST == next_node) {
  //           if (ordlist.size() == 1) {
  //             ordlist.clear();
  //           } else {
  //             iter_swap(ordlist.begin() + j, ordlist.end() - 1);
  //             ordlist.pop_back();
  //             // ordlist.erase(ordlist.begin() + j);
  //           }
  //         }
  //       }
  //     }
  //     now_node = next_node;
  //   }
  //   return ordlist;
  // }

  void solve(int C = 4) {
    vector<Order> ordlist, waitinglist;
    int start = 0;
    while (time < ol.T) {
      while (ordlist.size() < SKIP_NUM && time < ol.T) {
        Order ord = ol.list[time];
        if (ord.ID != INF) ordlist.push_back(ord);
        ans.push_back(-1);
        time++;
      }
      if (ordlist.empty()) break;

      vector<int> count(C, 0);
      for (int i = 0; i < ordlist.size(); i++) {
        Order ord = ordlist[i];
        count[G.labels[ord.DST]]++;
      }
      int c = 0, mx = 0;
      for (int i = 0; i < C; i++) {
        if (count[i] > mx) {
          mx = count[i];
          c = i;
        }
      }
      // cerr << "c: " << c << endl;
      vector<vector<Order>> orders(G.N);
      for (int i = 0; i < ordlist.size(); i++) {
        Order ord = ordlist[i];
        if (G.labels[ord.DST] == c) {
          orders[ord.DST].push_back(ord);
        }
      }
      cerr << "time: " << time << endl;
      cerr << "list num: " << ordlist.size() << endl;
      cerr << "wait num: " << waitinglist.size() << endl;

      Path path = search_path(orders, 0, 0);
      execute(path, ordlist, waitinglist);

      start = path[path.size()-1];
      if (start != 0 && ordlist.empty()) {
        execute(G.paths[start][0], ordlist, waitinglist);
        start = 0;
      }

      cerr << '\n';
    }
    cerr << "    score = " << SCORE << '\n';
    cerr << "est_score = " << 30*SCORE << '\n';
  }

  // void solve(int C = 4) {
  //   vector<Order> ordlist;
  //   while (time < ol.T) {
  //     while (ordlist.size() < SKIP_NUM && time < ol.T) {
  //       Order ord = ol.list[time];
  //       if (ord.ID != INF) ordlist.push_back(ord);
  //       ans.push_back(-1);
  //       time++;
  //     }
  //     if (ordlist.empty()) break;

  //     vector<int> count(C, 0);
  //     for (int i = 0; i < ordlist.size(); i++) {
  //       Order ord = ordlist[i];
  //       count[G.labels[ord.DST]]++;
  //     }
  //     int c = 0, mx = 0;
  //     for (int i = 0; i < C; i++) {
  //       if (count[i] > mx) c = i;
  //     }
  //     // cerr << "c: " << c << endl;
  //     vector<vector<Order>> orders(G.N);
  //     for (int i = 0; i < ordlist.size(); i++) {
  //       Order ord = ordlist[i];
  //       if (G.labels[ord.DST] == c) {
  //         orders[ord.DST].push_back(ord);
  //       }
  //     }

  //     Path result_path = search_path(orders, 0, 0);
  //     assert(!result_path.empty());
  //     ordlist = execute(result_path, ordlist, true);
  //   }
  //   cerr << "rest num: " << ordlist.size() << endl;
  //   // cerr << "    score = " << SCORE << '\n';
  //   // cerr << "est_score = " << 30*SCORE << '\n';
  // }

  void output() {
    int sz = ans.size();
    if (sz < ol.T) {
      for (int i = 0; i < sz; i++) cout << ans[i] << '\n';
      for (int i = 0; i < ol.T-sz; i++) cout << -1 << '\n';
    } else {
      for (int i = 0; i < ol.T; i++) cout << ans[i] << '\n';
    }
  }
};


/* ==================== main ==================== */
int main() {
  START = clock();

  int N, M; scanf("%d %d", &N, &M);
  Graph G(N, M);
  G.input();
  G.init();

  int T; scanf("%d", &T);
  OrderList ol(T);
  ol.input();
  ol.init();

  int C = 1;
  Solver sl(G, ol);
  sl.G.makeClusters(C);
  sl.solve(4*C);
  sl.output();

  END = clock();
  cerr << "time: " << (double)(END - START)/CLOCKS_PER_SEC << '\n';
  return 0;
}


Measured memory_bytes: 64768