//#define NDEBUG
#include "bits/stdc++.h"
#include <iostream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <array>
#ifdef _MSC_VER
#include <ppl.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#endif

using namespace std;

#define DUMPOUT cerr
#define dump(...) DUMPOUT<<"  ";DUMPOUT<<#__VA_ARGS__<<" :["<<__LINE__<<":"<<__FUNCTION__<<"]"<<endl;DUMPOUT<<"    ";dump_func(__VA_ARGS__)

typedef unsigned uint; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<double, double> pdd; typedef pair<string, string> pss;
template <typename _KTy, typename _Ty> ostream& operator << (ostream& o, const pair<_KTy, _Ty>& m) { o << "{" << m.first << ", " << m.second << "}"; return o; }
template <typename _KTy, typename _Ty> ostream& operator << (ostream& o, const map<_KTy, _Ty>& m) { if (m.empty()) { o << "{ }"; return o; } o << "{" << *m.begin(); for (auto itr = ++m.begin(); itr != m.end(); itr++) { o << ", " << *itr; } o << "}"; return o; }
template <typename _KTy, typename _Ty> ostream& operator << (ostream& o, const unordered_map<_KTy, _Ty>& m) { if (m.empty()) { o << "{ }"; return o; } o << "{" << *m.begin(); for (auto itr = ++m.begin(); itr != m.end(); itr++) { o << ", " << *itr; } o << "}"; return o; }
template <typename _Ty> ostream& operator << (ostream& o, const vector<_Ty>& v) { if (v.empty()) { o << "{ }"; return o; } o << "{" << v.front(); for (auto itr = ++v.begin(); itr != v.end(); itr++) { o << ", " << *itr; } o << "}"; return o; }
template <typename _Ty> ostream& operator << (ostream& o, const set<_Ty>& s) { if (s.empty()) { o << "{ }"; return o; } o << "{" << *(s.begin()); for (auto itr = ++s.begin(); itr != s.end(); itr++) { o << ", " << *itr; } o << "}"; return o; }
template <typename _Ty> ostream& operator << (ostream& o, const unordered_set<_Ty>& s) { if (s.empty()) { o << "{ }"; return o; } o << "{" << *(s.begin()); for (auto itr = ++s.begin(); itr != s.end(); itr++) { o << ", " << *itr; }	o << "}"; return o; }
template <typename _Ty> ostream& operator << (ostream& o, const stack<_Ty>& s) { if (s.empty()) { o << "{ }"; return o; } stack<_Ty> t(s); o << "{" << t.top(); t.pop(); while (!t.empty()) { o << ", " << t.top(); t.pop(); } o << "}";	return o; }
template <typename _Ty> ostream& operator << (ostream& o, const list<_Ty>& l) { if (l.empty()) { o << "{ }"; return o; } o << "{" << l.front(); for (auto itr = ++l.begin(); itr != l.end(); ++itr) { o << ", " << *itr; } o << "}"; return o; }
template <typename _KTy, typename _Ty> istream& operator >> (istream& is, pair<_KTy, _Ty>& m) { is >> m.first >> m.second; return is; }
template <typename _Ty> istream& operator >> (istream& is, vector<_Ty>& v) { for (size_t t = 0; t < v.size(); t++) is >> v[t]; return is; }
namespace aux { // print tuple
  template<typename Ty, unsigned N, unsigned L> struct tp { static void print(ostream& os, const Ty& v) { os << get<N>(v) << ", "; tp<Ty, N + 1, L>::print(os, v); } };
  template<typename Ty, unsigned N> struct tp<Ty, N, N> { static void print(ostream& os, const Ty& v) { os << get<N>(v); } };
}

template<typename... Tys> ostream& operator<<(ostream& os, const tuple<Tys...>& t) { os << "{"; aux::tp<tuple<Tys...>, 0, sizeof...(Tys) - 1>::print(os, t); os << "}"; return os; }

template<typename A, size_t N, typename T> inline void Fill(A(&array)[N], const T &val) { std::fill((T*)array, (T*)(array + N), val); }

void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail> void dump_func(Head&& head, Tail&&... tail) { DUMPOUT << head; if (sizeof...(Tail) == 0) { DUMPOUT << " "; } else { DUMPOUT << ", "; } dump_func(std::move(tail)...); }

#define PI 3.14159265358979323846
#define EPS 1e-8
#define FOR(t,a,n) for(int t=(a);t<(n);++t)
#define REP(t,n)  FOR(t,0,n)
#define all(j) (j).begin(), (j).end()
#define SZ(j) ((int)(j).size())
#define fake false



class Timer {
public:
  double t = 0;
  Timer() {}
  static double time() {
#ifdef _MSC_VER
    return __rdtsc() / 2.8e9;
#else
    unsigned long long a, d;
    __asm__ volatile("rdtsc"
      : "=a"(a), "=d"(d));
    return (d << 32 | a) / 2.8e9;
#endif
  }
  void measure() { t = time() - t; }
  double elapsedMs() { return (time() - t) * 1000.0; }
} timer;

struct Xorshift {
  uint64_t x = 88172645463325252LL;
  unsigned nextUInt() {
    x = x ^ (x << 7);
    return x = x ^ (x >> 9);
  }
  unsigned nextUInt(unsigned mod) {
    x = x ^ (x << 7);
    x = x ^ (x >> 9);
    return x % mod;
  }
  unsigned nextUInt(unsigned l, unsigned r) {
    x = x ^ (x << 7);
    x = x ^ (x >> 9);
    return x % (r - l + 1) + l;
  }
  double nextDouble() {
    return double(nextUInt()) / UINT_MAX;
  }
} rnd;

template<typename T>
void shuffleVector(vector<T>& v, Xorshift& rnd) {
  int n = v.size();
  for (int t = n - 1; t >= 1; t--) {
    int r = rnd.nextUInt(t);
    swap(v[t], v[r]);
  }
}



//constexpr int TMAX = 10000;
//constexpr int TLAST = 9500;
int TMAX;
int TLAST;
constexpr int inf = INT_MAX / 4;

template<typename T>
struct PrimePoint {
  T x, y;
  int c;
  PrimePoint() {}
  PrimePoint(T x, T y, int c) : x(x), y(y), c(c) {}
};

template<typename T>
struct PrimeEdge {
  int u, v;
  T d;
  PrimeEdge() {}
  PrimeEdge(int u, int v, T d) : u(u), v(v), d(d) {}
};

struct PrimeInfo {
  int id;
  int t;
  int dst;
  PrimeInfo() {}
  PrimeInfo(int id, int t, int dst) : id(id), t(t), dst(dst) {}
};

class DisjointSet {
private:
  vector<unsigned> par;
  vector<unsigned> rank;
  vector<unsigned> sz;	// 要素の個数
  size_t set_sz;			// 集合の個数
public:
  DisjointSet() : set_sz(0) {}
  DisjointSet(size_t n) :
    par(n), rank(n, 0), sz(n, 1), set_sz(n) {
    for (size_t i = 0; i < n; i++) par[i] = i;
  }
  size_t set_size() { return set_sz; }
  size_t size(size_t v) { return sz[find(v)]; }
  void makeset() {
    par.push_back(par.size());
    rank.push_back(0);
    sz.push_back(1);
    set_sz++;
  }
  void makeset(size_t n) {
    for (size_t i = 0; i < n; i++) makeset();
  }
  size_t find(size_t x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(size_t x, size_t y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y]) rank[x]++;
    }
    sz[x] += sz[y];
    sz[y] = sz[x];
    set_sz--;
  }
  bool same(size_t x, size_t y) {
    return find(x) == find(y);
  }
  friend ostream& operator<<(ostream& ostr, const DisjointSet& ds) {
    ostr << endl << "parent : " << ds.par << endl << "rank : " << ds.rank << endl << "size : " << ds.sz << endl << "size of set : " << ds.set_sz << endl;
    return ostr;
  }
};

template<typename T>
struct Cmp {
  bool operator()(const PrimeEdge<T>& e1, const PrimeEdge<T>& e2) {
    return e1.d > e2.d;
  }
};

struct TestCase {
  int V, E;
  vector<PrimeEdge<int>> edges;
  vector<PrimeInfo> infos;
  TestCase() {}
  TestCase(istream& is) {
    is >> V >> E;
    for (int t = 0; t < E; t++) {
      int u, v, d;
      is >> u >> v >> d;
      edges.emplace_back(u, v, d);
    }
    //int buf;
    //is >> buf;
    is >> TMAX;
    TLAST = TMAX * 95 / 100;
    for (int t = 1; t <= TMAX; t++) {
      int Nnew;
      is >> Nnew;
      if (!Nnew) continue;
      int newId, dst;
      is >> newId >> dst;
      infos.emplace_back(newId, t, dst);
    }
  }
  TestCase(Xorshift& rnd, int V, int E, int TMAX_, int TPeak) {
    TMAX = TMAX_;
    TLAST = TMAX * 95 / 100;
    this->V = V;
    this->E = E;
    int R = getR();
    auto pts = generateGraph(rnd, R);
    generateInfo(rnd, pts, R, TPeak);
  }
  void toZeroIndex() {
    for (auto& e : edges) {
      e.u--; e.v--;
    }
    for (auto& i : infos) {
      i.dst--; i.id--;
    }
  }
  int getR() {
    int R;
    for (R = 0; R * R <= V; R++);
    return R - 1;
  }
  vector<PrimePoint<double>> generateGraph(Xorshift& rnd, int R) {
    vector<PrimePoint<double>> pts;

    const int maxDegree = 5;
    int r;
    r = V - R * R;
    for (int y = 0; y < R; y++) {
      for (int x = 0; x < R; x++) {
        double ny = y + rnd.nextDouble();
        double nx = x + rnd.nextDouble();
        pts.emplace_back(nx, ny, (x + y) & 1);
      }
    }
    for (int i = 0; i < r; i++) {
      double y = rnd.nextDouble() * R;
      double x = rnd.nextDouble() * R;
      int c = rnd.nextUInt(2);
      pts.emplace_back(x, y, c);
    }
    shuffleVector(pts, rnd);
    // 高速道路生成
    priority_queue<PrimeEdge<double>, vector<PrimeEdge<double>>, Cmp<double>> pq;
    for (int u = 0; u < V - 1; u++) {
      for (int v = u + 1; v < V; v++) {
        double d = sqrt(pow(pts[u].x - pts[v].x, 2) + pow(pts[u].y - pts[v].y, 2));
        pq.emplace(u, v, d);
      }
    }
    vector<vector<int>> G(V);
    vector<PrimeEdge<double>> candidateEdges;
    DisjointSet ds(V);
    while (!pq.empty()) {
      const auto e = pq.top(); pq.pop();
      if (ds.same(e.u, e.v)) {
        candidateEdges.push_back(e);
        continue;
      }
      ds.unite(e.u, e.v);
      edges.emplace_back(e.u + 1, e.v + 1, (int)ceil(e.d * 2));
      G[e.u].push_back(e.v);
      G[e.v].push_back(e.u);
    }
    // 通常道路生成
    for (int i = 0; i < E - V + 1; i++) {
      double mincost = DBL_MAX;
      auto minItr = candidateEdges.end();
      for (auto itr = candidateEdges.begin(); itr != candidateEdges.end(); ++itr) {
        int du = G[itr->u].size();
        int dv = G[itr->v].size();
        if (du == maxDegree || dv == maxDegree) continue;
        int f = (pts[itr->u].c == pts[itr->v].c ? 5 : 1);
        double cost = itr->d * du * dv * f;
        if (cost < mincost) {
          mincost = cost;
          minItr = itr;
        }
      }
      edges.emplace_back(minItr->u + 1, minItr->v + 1, (int)ceil(minItr->d * 4));
      G[minItr->u].push_back(minItr->v);
      G[minItr->v].push_back(minItr->u);
      candidateEdges.erase(minItr);
    }
    shuffleVector(edges, rnd);
    return pts;
  }
  double porder(int t, int TPeak) {
    if (t < TPeak) return double(t) / TPeak;
    if (t < TLAST) return double(TLAST - t) / (TLAST - TPeak);
    return 0;
  }
  void generateInfo(Xorshift& rnd, const vector<PrimePoint<double>> pts, int R, int TPeak) {
    int V = pts.size();
    vector<int> freq(V, 1);
    freq[0] = 0;
    double offset = R * 0.25;
    double cx = offset + rnd.nextDouble() * R * 0.5;
    double cy = offset + rnd.nextDouble() * R * 0.5;
    for (int u = 1; u < V; u++) {
      double d = sqrt(pow(pts[u].x - cx, 2) + pow(pts[u].y - cy, 2));
      if (d <= R * 0.125 * (1 + rnd.nextDouble())) freq[u] = 2;
    }
    vector<int> lot;
    for (int u = 0; u < V; u++) {
      for (int f = 0; f < freq[u]; f++) {
        lot.push_back(u);
      }
    }
    int L = lot.size(), id = 0;
    for (int t = 0; t <= TLAST; t++) {
      double r = rnd.nextDouble();
      if (r > porder(t, TPeak)) continue;
      int u = lot[rnd.nextUInt(L)] + 1;
      infos.emplace_back(++id, t, u);
    }
  }
  string output() {
    ostringstream oss;
    oss << V << " " << E << endl;
    for (const auto& e : edges) {
      oss << e.u << " " << e.v << " " << e.d << endl;
    }
    vector<int> order(TMAX, -1);
    for (const auto& i : infos) {
      order[i.t] = i.id - 1;
    }
    oss << TMAX << endl;
    for (int i = 0; i < TMAX; i++) {
      if (order[i] == -1) {
        oss << 0 << endl;
        continue;
      }
      oss << 1 << endl;
      const auto& info = infos[order[i]];
      oss << info.t << " " << info.dst << endl;
    }
    return oss.str();
  }
};

struct WarshallFloyd {
  int V;
  vector<vector<int>> d;
  vector<vector<int>> next;
  WarshallFloyd() {}
  WarshallFloyd(const TestCase& tc) {
    V = tc.V;
    d.resize(V, vector<int>(V, inf));
    next.resize(V, vector<int>(V));
    for (int i = 0; i < V; i++) {
      d[i][i] = 0;
    }
    for (const PrimeEdge<int>& e : tc.edges) {
      d[e.u][e.v] = d[e.v][e.u] = e.d;
    }
    for (int i = 0; i < V; i++) {
      for (int j = 0; j < V; j++) {
        next[i][j] = j;
      }
    }
    for (int k = 0; k < V; k++) {
      for (int i = 0; i < V; i++) {
        for (int j = 0; j < V; j++) {
          if (d[i][k] + d[k][j] < d[i][j]) {
            d[i][j] = d[i][k] + d[k][j];
            next[i][j] = next[i][k];
          }
        }
      }
    }
  }
  vector<int> getPath(int u, int v) {
    vector<int> ret;
    for (int cur = u; cur != v; cur = next[cur][v]) {
      ret.push_back(cur);
    }
    ret.push_back(v);
    return ret;
  }
  vector<int> getPath(const vector<int>& r) {
    int n = r.size();
    vector<int> path;
    for (int i = 0; i < n - 1; i++) {
      for (int u : getPath(r[i], r[i + 1])) {
        path.push_back(u);
      }
      path.pop_back();
    }
    path.push_back(r[0]);
    return path;
  }
  vector<int> getCommands(const vector<int>& p) {
    vector<int> cmds;
    int n = p.size();
    for (int i = 0; i < n - 1; i++) {
      int u = p[i], v = p[i + 1];
      for (int k = 0; k < d[u][v]; k++) {
        cmds.push_back(v);
      }
    }
    return cmds;
  }
};

struct TSP {
  int V;
  vector<int> iToU;
  vector<vector<int>> d;

  int score;
  vector<int> p;

  TSP(const vector<vector<int>>& G, const vector<int>& us) : iToU(us) {
    V = us.size();
    d.resize(V, vector<int>(V));
    for (int i = 0; i < V; i++) {
      for (int j = i; j < V; j++) {
        d[i][j] = d[j][i] = G[us[i]][us[j]];
      }
    }
    score = 0;
    p.resize(V);
    for (int i = 0; i < V; i++) {
      score += d[i][(i + 1) % V];
      p[i] = i;
    }
  }

  inline int dist(int i1, int i2) {
    return d[i1][i2];
  }

  double twoOptDiff(int idx1, int idx2) {
    int p1 = p[idx1], p2 = p[(idx1 + 1) % V], p3 = p[idx2], p4 = p[(idx2 + 1) % V];
    return dist(p1, p3) + dist(p2, p4) - dist(p1, p2) - dist(p3, p4);
  }

  void solve2optClimbing() {
    while (true) {
      bool update = false;
      for (int i1 = 0; i1 < V - 1; i1++) {
        for (int i2 = i1 + 1; i2 < V; i2++) {
          int diff = twoOptDiff(i1, i2);
          if (diff < 0) {
            reverse(p.begin() + i1 + 1, p.begin() + i2 + 1);
            score += diff;
            //cerr << score << endl;
            update = true;
          }
        }
      }
      if (!update) break;
    }
  }

  double getTemp(double startTemp, double endTemp, int t, int T) {
    return endTemp + (startTemp - endTemp) * (T - t) / T;
  }

  void solve2optSA(int numLoop) {
    double bestScore = DBL_MAX;
    vector<int> bp;
    const unsigned R = (1 << 30), mask = (1 << 30) - 1;
    for (int i = 0; i < numLoop; i++) {
      int i1 = rnd.nextUInt() % V;
      int i2 = rnd.nextUInt() % (V - 1);
      if (i2 >= i1) i2++;
      if (i1 > i2) swap(i1, i2);

      double diff = twoOptDiff(i1, i2);

      double temp = getTemp(3.0, 0.01, i, numLoop);
      double x = -diff / temp;
      double prob = exp(-diff / temp);

      if (R * prob > (rnd.nextUInt() & mask)) {
        reverse(p.begin() + i1 + 1, p.begin() + i2 + 1);
        score += diff;
        if (score < bestScore) {
          bestScore = score;
          bp = p;
        }
      }
    }
    score = bestScore;
    p = bp;
    //cerr << bestScore << endl;
  }

  pair<int, vector<int>> getDistanceAndRoute() {
    vector<int> route;
    for (int i : p) route.push_back(iToU[i]);
    route.push_back(iToU[0]);
    return pair<int, vector<int>>(score, route);
  }
};

struct State {
  TestCase tc;
  WarshallFloyd wf;
  State(const TestCase& tc, const WarshallFloyd& wf) : tc(tc), wf(wf) {}
  vector<int> gather(int t0, int t1) {
    // {0} + [t0, t1) にやってくる注文の位置集合
    set<int> st({ 0 });
    for (auto& info : tc.infos) {
      if (t0 <= info.t && info.t < t1) {
        st.insert(info.dst);
      }
    }
    return vector<int>(st.begin(), st.end());
  }
  vector<int> getAns() {
    vector<int> ans;
    int interval = 10;
    int finish = 0, t0 = 0, t1 = interval;
    while (ans.size() < TMAX) {
      while (ans.size() < t1) ans.push_back(-2);
      auto v1 = gather(t0, t1);
      if (v1.size() > 1) {
        TSP tsp(wf.d, v1);
        tsp.solve2optSA(10000000);
        auto route = tsp.getDistanceAndRoute();
        auto path = wf.getPath(route.second);
        auto cmds = wf.getCommands(path);
        for (int cmd : cmds) ans.push_back(cmd);
        finish = t1 + route.first;
      }
      else {
        finish = t1;
      }
      t0 = t1;
      t1 = max(t1 + interval, finish);
    }
    while (ans.size() > TMAX) ans.pop_back();
    return ans;
  }
};

//#define DEBUG_MODE
#ifdef DEBUG_MODE
int main() {
  timer.measure();

  cin.tie(0);
  ios::sync_with_stdio(false);
  concurrency::parallel_for(1, 101, [&](int i) {
    //for (int i = 1; i <= 100; i++) {
    string input_name = "input/" + to_string(i) + ".txt";
    string output_name = "output/" + to_string(i) + ".txt";
    ifstream in(input_name);
    ofstream out(output_name);
    TestCase tc(in);
    tc.toZeroIndex();
    WarshallFloyd wf(tc);
    State state(tc, wf);
    auto ans = state.getAns();
    for (int i : ans) out << i + 1 << endl;
    in.close();
    out.close();
    cerr << i << ": " << timer.elapsedMs() << endl;
    //}
  });

  return 0;
}
#else
int main() {
  timer.measure();

  cin.tie(0);
  ios::sync_with_stdio(false);

  TestCase tc(cin);
  tc.toZeroIndex();

  WarshallFloyd wf(tc);

  vector<int> us;
  for (int i = 0; i < wf.V; i++)
    us.push_back(i);

  State state(tc, wf);
  auto ans = state.getAns();

  for (int i : ans) cout << i + 1 << endl;

  dump(timer.elapsedMs());

  return 0;
}
#endif


Measured memory_bytes: 5504