// 2HC2019_A.cpp
#include<bits/stdc++.h>

using namespace std;

#define FOR(i, a, b) for(int i=(int)(a); i<(int)(b); i++)
#define RFOR(i, a, b) for(int i=(int)(b)-1; i>=(int)(a); i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)

#define RDTSC(X) asm volatile ("rdtsc; shlq $32,%%rdx; orq %%rdx,%%rax" : "=a" (X) :: "%rdx")
#define CPUFREQ (3.4e9)

struct Order{
  int id, dst, t;
  bool operator < (const Order& r) const {return t < r.t;}
};

template<class T> vector<T> subvector(vector<T>& v, int pos = 0, int n = INT_MAX){
  int l = min(n, (int)v.size()-pos);
  return vector<T>(v.begin()+pos, v.begin()+pos+l);
}

class OptimizeRoute{
  int V, E, Tmax;
  vector< vector< pair<int, int> > > G;
  vector<Order> orders;
  vector< vector<int> > distances;
  vector< vector< vector<int> > > spathes;

  vector<int> cur, best;
  long long score, bscore = 0;

  int radius;
  double rate;
  int threshold;

  unsigned long long tsc0, tsc;
  random_device r;
  mt19937 mt;

public:
  pair< vector<int>, vector<int>> dijkstra(int r, const vector< vector< pair<int, int> > >& G){
    int n = G.size();

    priority_queue< pair<int, int> > PQ;
    vector<bool> visited(n, false);
    vector<int> d(n, INT_MAX), p(n, -1);

    d[r] = 0;
    PQ.push(make_pair(0, r));

    while(PQ.size()){
      pair<int, int> f = PQ.top(); PQ.pop();
      int u = f.second;

      visited[u] = true;

      if(d[u] < f.first*(-1)) continue;

      for(auto e: G[u]){
        int v = e.first;
        if(visited[v]) continue;
        if(d[v] > d[u] + e.second){
          d[v] = d[u] + e.second;
          p[v] = u;
          PQ.push(make_pair(d[v]*(-1), v));
        }
      }
    }

    return {d, p};
  }

  vector<int> spath(int t, const vector<int>& p){
    vector<int> ret;
    while(t != -1){
      ret.push_back(t);
      t = p[t];
    }
    reverse(ret.begin(), ret.end());
    return ret;
  }

  void init(){
    RDTSC(tsc0);
    mt = mt19937(r());

    distances = vector< vector<int> >(V, vector<int>(V, INT_MAX));
    spathes = vector< vector< vector<int> > >(V, vector< vector<int> >(V));
    REP(i, V){
      auto tmp = dijkstra(i, G);
      distances[i] = tmp.first;
      REP(j, V) spathes[i][j] = spath(j, tmp.second);
    }

    radius = INT_MAX;
  }

  vector<int> deliver_all(set<Order>& sorders, int t){
    vector<int> ret;

    int cnode = 0;
    while(not sorders.empty()){
      vector<Order> vorders(sorders.begin(), sorders.end());
      sort(vorders.begin(), vorders.end(), [&](const Order& l, const Order& r){return distances[cnode][l.dst] < distances[cnode][r.dst];});
      REP(i, vorders.size()) if(t+(int)ret.size()+distances[cnode][vorders[i].dst] - vorders[i].t > threshold){swap(vorders[0], vorders[i]); break;}
      if(cnode != 0 && distances[cnode][vorders[0].dst] > distances[cnode][0]*rate) break;
      vector<int> path = spathes[cnode][vorders[0].dst];
      set<Order> erased;
      REP(i, path.size()-1){
        REP(j, distances[path[i]][path[i+1]]) ret.push_back(path[i+1]);
        for(auto& o: sorders) if(o.dst == path[i+1]) erased.insert(o), score += t+(int)ret.size() < Tmax ? Tmax*Tmax - (t+ret.size()-o.t)*(t+ret.size()-o.t) : 0;
      }
      cnode = vorders[0].dst;
      for(auto& o: erased) sorders.erase(o);
    }

    vector<int> path = spathes[cnode][0];
    set<Order> erased;
    REP(i, path.size()-1){
      REP(j, distances[path[i]][path[i+1]]) ret.push_back(path[i+1]);
      for(auto& o: sorders) if(o.dst == path[i+1]) erased.insert(o), score += t+(int)ret.size() < Tmax ? Tmax*Tmax - (t+ret.size()-o.t)*(t+ret.size()-o.t) : 0;
    }
    cnode = 0;
    for(auto& o: erased) sorders.erase(o);

    return ret;
  }

public:
  vector<int> solve(int V_in, int E_in, const vector< vector< pair<int, int> > >& G_in, int Tmax_in, const vector<Order>& orders_in){
    V = V_in, E = E_in, G = G_in, Tmax = Tmax_in, orders = orders_in;

    init();

    set<double> rates = {0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 4, 8, 16};
    set<int> thresholds = {100, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000};
    for(auto r: rates) for(auto t: thresholds){
        rate = r;
        threshold = t;
        cur.clear();
        score = 0;

        set<Order> sorders;
        REP(t, Tmax){
          if(orders[t].id != -1 && distances[0][orders[t].dst] < radius) sorders.insert(orders[t]);
          if(not sorders.empty() && orders[t+1].id == -1){
            vector<int> moves = deliver_all(sorders, t);
            REP(tt, moves.size()) cur.push_back(moves[tt]);
            FOR(tt, 1, moves.size()) if(t+tt < Tmax && orders[t+tt].id != -1 && distances[0][orders[t+tt].dst] < radius) sorders.insert(orders[t+tt]);
            t += moves.size()-1;
          }else cur.push_back(-1);
        }

        if(score > bscore) best = cur, bscore = score, cerr << rate << " " << threshold << " " << bscore << endl;
      }
    cerr << endl;

    return subvector(best, 0, Tmax);
  }
};

int main(){
  int V, E; cin >> V >> E;
  vector< vector< pair<int, int> > > G(V);
  REP(i, E){
    int u, v, d; cin >> u >> v >> d;
    G[u-1].push_back({v-1, d});
    G[v-1].push_back({u-1, d});
  }
  int Tmax; cin >> Tmax;
  vector<Order> orders(Tmax, {-1, -1, -1});
  REP(t, Tmax){
    int Nnew; cin >> Nnew;
    REP(i, Nnew){
      int id, dst; cin >> id >> dst;
      orders[t] = {id, dst-1, t};
    }
  }

  OptimizeRoute oroute;
  vector<int> ret = oroute.solve(V, E, G, Tmax, orders);

  REP(i, Tmax) cout << (ret[i]!=-1 ? ret[i]+1 : -1) << endl;

  return 0;
}


Measured memory_bytes: 23808