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

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

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<vector<int>> clusters;

  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()) {}
  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)) {}

  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;
  }

  int cluster() {
    random_device seed;
    mt19937 mt(seed());
    uniform_int_distribution<> randN(0, N-1);

    int mn = INF, center = 0;
    for (int i = 0; i < N; i++) {
      int sum = 0;
      for (int j = 0; j < N; j++) {
        sum += dists[i][j];
      }
      if (sum < mn) {
        mn = sum;
        center = i;
      }
    }
    return center;
  }

  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<vector<int>> getClusters() const {
    return clusters;
  }
};


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:
  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;
  double MAX_ITER = 580;
  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, now);
    dest_order.push_back(t);

    vector<bool> visited(G.N, false);
    for (int i = 0; i < dest_order.size(); i++) {
      next = dest_order[i];
      if (visited[next]) continue;
      visited[next] = true;

      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);
        visited[next] = true;
      }
      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(), t = time;

    // 目的地に届けた注文
    for (int i = 1; i < len; i++) {
      int from = path[i-1], to = path[i];
      t += G.dists[from][to];
      if (to == 0) break;
      if (t >= ol.T) {
        t = ol.T-1;
        break;
      }
      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);

    // 残した注文
    for (int i = 0; i < G.N; i++) {
      for (int j = 0; j < orders[i].size(); j++) {
        score -= 4LL*pow(t - orders[i][j].t, 2);
      }
    }
    return make_pair(score, ori_score);
  }

  // TODO : 高速化、温度による許容の部分
  Path search_path(vector<Order> ordlist) {
    vector<vector<Order>> orders(G.N);
    for (int i = 0; i < ordlist.size(); i++) {
      Order ord = ordlist[i];
      orders[ord.DST].push_back(ord);
    }

    // 初期値の決定
    vector<int> dest_order = init_order(orders);

    // simulated annealing ???
    Path res_path = make_path(0, dest_order, 0);
    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 << "parcel num : " << ordlist.size() << '\n';
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(0, new_order, 0);
        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/INI_TEMP*ol.T*10);
// cerr << "temp: " << temp << ", prob: " << prob << '\n';
          if (prob > rand01(mt)) {
            dest_order = new_order;
            pre_score = new_score;
          }
        }
      }
    }
cerr << "last score : " << ori_score << '\n';
cerr << "max score  : " << (ll)ordlist.size() * ol.T * ol.T << '\n';
// cerr << "diff score : " << -((ll)ordlist.size() * ol.T * ol.T - ori_score) << '\n';
SCORE += ori_score;
    return res_path;
  }

  vector<Order> execute(Path path, vector<Order> ordlist) {
    vector<bool> visited(G.N, false);
    vector<Order> new_ordlist;
    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); t++) {
        ans.push_back(next_node+1);
        Order ord = ol.list[t+1];
        if (ord.ID != INF) new_ordlist.push_back(ord);
      }
      time += dt;

      visited[next_node] = true;
      now_node = next_node;

      // 途中で店舗に戻った場合
      if (now_node == 0) break;
    }

    // old_orderlistのチェック
    for (int i = 0; i < ordlist.size(); i++) {
      if (!visited[ordlist[i].DST]) {
        new_ordlist.push_back(ordlist[i]);
      }
    }
    return new_ordlist;
  }

  void solve() {
    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;
      Path path = search_path(ordlist);
      ordlist = execute(path, ordlist);
      cerr << '\n';
    }
    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();

  Solver sl(G, ol);
  sl.solve();
  sl.output();

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


Measured memory_bytes: 64768