// May this submission get accepted!

#pragma GCC optimize ("O3")
#pragma GCC target ("tune=native")
#pragma GCC target ("avx")

#include <bits/stdc++.h>
#include <unordered_set>

constexpr bool DEBUG_MODE = false;
constexpr double TIMELIMIT_FACTOR = 1.0;

// 汎用マクロ
#define ALL_OF(x) (x).begin(), (x).end()
#define REP(i,n) for (long long i=0, i##_len=(n); i<i##_len; i++)
#define RANGE(i,is,ie) for (long long i=(is), i##_end=(ie); i<=i##_end; i++)
#define DSRNG(i,is,ie) for (long long i=(is), i##_end=(ie); i>=i##_end; i--)
#define STEP(i, is, ie, step) for (long long i=(is), i##_end=(ie), i##_step = (step); i<=i##_end; i+=i##_step)
#define UNIQUE(v) do { sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end()); } while (false)
template<class T> bool chmax(T &a, const T &b) {if (a < b) {a = b; return true;} return false; }
template<class T> bool chmin(T &a, const T &b) {if (a > b) {a = b; return true;} return false; }
#define INF 0x7FFFFFFF
#define LINF 0x7FFFFFFFFFFFFFFFLL
#define Yes(q) ((q) ? "Yes" : "No")
#define YES(q) ((q) ? "YES" : "NO")
#define Possible(q) ((q) ? "Possible" : "Impossible")
#define POSSIBLE(q) ((q) ? "POSSIBLE" : "IMPOSSIBLE")
#define DUMP(q) cerr << "[DEBUG] " #q ": " << (q) << " at " __FILE__ ":" << __LINE__ << endl
#define DUMPALL(q) do { cerr << "[DEBUG] " #q ": ["; REP(i, (q).size()) { cerr << (q)[i] << (i == i_len-1 ? "" : ", "); } cerr << "] at " __FILE__ ":" << __LINE__ << endl; } while (false)
template<class T> T gcd(T a, T b) { if (a < b) std::swap(a, b); while (b) std::swap(a %= b, b); return a; }
template<class T> T lcm(const T a, const T b) { return a / gcd(a, b) * b; }

// gcc拡張マクロ
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll

// エイリアス
#define DANCE_ long
#define ROBOT_ unsigned
#define HUMAN_ signed
#define CHOKUDAI_ const
using  ll = DANCE_ HUMAN_ DANCE_;
using ull = DANCE_ ROBOT_ DANCE_;
using cll = DANCE_ DANCE_ CHOKUDAI_;
using  ld = long double;
using namespace std;

// モジュール

// マラソン用モジュール
namespace marathon {
    clock_t start_clock;
    constexpr double time_limit = 29.9 * TIMELIMIT_FACTOR; // 実行時間[s]より0.1ms程度余裕をあける
    constexpr double time_limit_inv = 1.0 / time_limit;
    constexpr double CLOCKS_PER_SEC_INV = 1.0 / CLOCKS_PER_SEC;
    inline double nowtime() { return CLOCKS_PER_SEC_INV * (clock() - start_clock); }
    inline bool intime() { return nowtime() < time_limit; }
    inline double progress() { return nowtime() * time_limit_inv; }
    struct preexec_dummy {
        preexec_dummy() {
            start_clock = clock();
        }
    } preexec_dummy_instance;
}

// XORShift 擬似乱数発生器
uint32_t xor128(void){
    static uint32_t x = 123456789;
    static uint32_t y = 362436069;
    static uint32_t z = 521288629;
    static uint32_t w = 88675123; 
    uint32_t t;

    t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));  
}
inline double rand_uniform(void) { return (double)xor128() / 0x100000000LL; }
template <typename T>
inline T rand_range(T min, T max) { return min + xor128() % (max - min + 1); }
inline bool rand_prob(double p) { return rand_uniform() < p; }

// 辺
struct edge {

    int src, dst, dist;

    edge(): dst(-1), dist(0) {}
    edge(int u, int v, int d) : src(u), dst(v), dist(d) {}

};

// 無向グラフ
struct undirected_graph {

    
    int vertex_num, edge_num;
    vector<edge> el; // 辺リスト
    vector<vector<edge>> gl; // 隣接リスト
    vector<vector<int>> gm; // 隣接行列
    vector<vector<int>> dm; // 距離行列
    vector<vector<int>> xm; // xm[i][j] := i -> j の最短経路における i の次の点

    undirected_graph() :
        vertex_num(0), edge_num(0),
        el(), gl(), gm() {}
    undirected_graph(const vector<edge> &_el) : el(_el)
    {
        vertex_num = 1 + accumulate(ALL_OF(el), 0, [](int ac, edge &e) { return max({ac, e.src, e.dst}); });
        edge_num = el.size();
        gl = vector<vector<edge>>(vertex_num);
        gm = vector<vector<int>>(vertex_num, vector<int>(vertex_num, INF));
        xm = vector<vector<int>>(vertex_num, vector<int>(vertex_num, -1));
        for (edge &e : el) {
            gm[e.src][e.dst] = gm[e.dst][e.src] = e.dist;
            gl[e.src].emplace_back(e);
            gl[e.dst].emplace_back(e.dst, e.src, e.dist);
            xm[e.src][e.dst] = e.dst;
            xm[e.dst][e.src] = e.src;
        }
        
        // Warshall-Floyd O(|E|^3)
        dm = gm;
        REP(k, vertex_num) REP(i, vertex_num) REP(j, vertex_num) {
            if (dm[i][k] < INF && dm[k][j] < INF) {
                if (chmin(dm[i][j], dm[i][k] + dm[k][j])) {
                    xm[i][j] = xm[i][k];
                }
            }
        }
    }

    inline int distance(const int u, const int v) const {
        assert(0 <= u && u < vertex_num);
        assert(0 <= v && v < vertex_num);
        return dm[u][v];
    }

    // to は含まれるが from は含まれない。注意
    vector<int> route(const int from, const int to) const {
        assert(0 <= from && from < vertex_num);
        assert(0 <= to   && to   < vertex_num);
        vector<int> r; r.reserve(vertex_num / 5);
        for (int x = from; x != to; ) {
            r.push_back(x = xm[x][to]);
        }
        return r;
    }

};

// 注文
struct order {
    int id, t0, dst;
    order() : id(-1), t0(INF), dst(-1) {}
    order(int i, int t, int u) : id(i), t0(t), dst(u) {}
};

// 注文データ
struct order_data {
    vector<order> o;
    vector<int> ot0;
    vector<vector<order>> odst;
    order_data() : o() {}
    order_data(const vector<order> &_ol, int v) : o(_ol), ot0(_ol.size()), odst(v) {
        sort(ALL_OF(o), [](order &o, order &p) {
            return o.t0 < p.t0 || (o.t0 == p.t0 && o.id < p.id);
        });
        REP(i, o.size()) {
            ot0[i] = o[i].t0;
        }
        for (const order &oi : o) {
            odst[oi.dst].emplace_back(oi);
        }
    }
    inline int count() const { return o.size(); }
};

// 入力
struct input_data {

    undirected_graph g;
    int tmax = 10000;
    order_data o;

    input_data() : g() {}
    input_data(istream &ist) {

        // 空間情報
        int v, e; ist >> v >> e;
        vector<edge> el;
        REP(i, e) {
            int u, v, d;
            ist >> u >> v >> d;
            u--; v--; // 0-indexed
            el.emplace_back(u, v, d);
        }
        g = undirected_graph(el);

        // 時間と注文データ
        ist >> tmax; // assert(tmax == 10000);
        vector<order> ol;
        REP(t0, tmax) {
            int nnew; ist >> nnew;
            REP(j, nnew) {
                int new_id, dst; ist >> new_id >> dst;
                new_id--; // 0-indexed
                dst--; // 0-indexed
                ol.emplace_back(new_id, t0, dst);
            }
        }
        o = order_data(ol, v);

    }

};
input_data inp;

struct schedule {

    vector<int> rank;

    schedule() : rank(inp.o.count()) {
        iota(ALL_OF(rank), 0);
    }

    // {score, output}
    pair<ll, vector<int>> simulate() {
        
        vector<int> ans; ans.reserve(inp.tmax);

        vector<int> rankinv(rank.size());
        REP(i, rank.size()) rankinv[rank[i]] = i;

        ll score = 0;
        ll basic_term = (ll)inp.tmax * inp.tmax;

        int lastload = -1;
        while (ans.size() < inp.tmax) {

            int nowtime = ans.size();
        
            // choosing orders to go for
            auto itr = upper_bound(ALL_OF(inp.o.ot0), lastload);
            auto jtr = upper_bound(ALL_OF(inp.o.ot0), nowtime);
            int trn = jtr - itr;
            if (trn == 0) {
                ans.push_back(-1);
                continue;
            }
            vector<int> vs(trn);
            iota(ALL_OF(vs), itr - inp.o.ot0.begin());
            sort(ALL_OF(vs), [&](int a, int b) {
                return rankinv[a] < rankinv[b];
            });

            // conbining the routes in one
            vs.push_back(-1);
            vector<int> q;
            int x = 0;
            for (int i : vs) {
                int y = i < 0 ? 0 : inp.o.o[i].dst;
                auto r = inp.g.route(x, y);
                copy(ALL_OF(r), back_inserter(q));
                x = y;
            }

            // going on the route
            int i = 0;
            for (int j : q) {
                if (ans.size() >= inp.tmax) break;
                REP(t, inp.g.gm[i][j]) {
                    ans.push_back(j);
                }
                if (ans.size() <= inp.tmax) {
                    for (order &o : inp.o.odst[j]) {
                        if (lastload < o.t0 && o.t0 <= nowtime) {
                            ll wt = (ll)ans.size() - o.t0;
                            score = basic_term + wt * wt;
                        }
                    }
                }
                i = j;
            }

        }

        ans.resize(inp.tmax, -1);
        return make_pair(score, ans);

    }

    void shuffle() {
        int v = rank.size();
        REP(i, v-1) {
            swap(rank[i], rank[rand_range<int>(i, v-1)]);
        }
    }

    void mutate() {
        int i = xor128() % rank.size();
        int j = xor128() % (rank.size() - 1);
        if (i <= j) j++;
        swap(rank[i], rank[j]);
    }

};

// 処理内容
int main() {
    
    // インタラクティブ問題では除去した方がいいかも
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    inp = input_data(cin);

    schedule s0;
    using sim_data = decltype(s0.simulate());
    sim_data best_sim = s0.simulate();
    auto sim_comp = [](sim_data &a, sim_data &b) {
        return a.first > b.first;
    };

    schedule s = s0;
    ll epoch = 0;
    
    for (double t = 0; (t = marathon::progress()) <= 0.99; epoch++) {

        schedule s1 = s;
        if (t < 0.1) {
            s1.shuffle();
        } else {
            s1.mutate();
        }

        sim_data sim = s1.simulate();

        if (sim_comp(sim, best_sim)) {
            best_sim = move(sim);
            s = move(s1);
        }
        
    }

    if (DEBUG_MODE) {
        DUMP(epoch);
        DUMP(best_sim.first);
    }
    for (int i : best_sim.second) {
        cout << (i < 0 ? -1 : i+1) << endl;
    }
    
}

Measured memory_bytes: 4868