// 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<int>> odst;
    order_data() : o() {}
    order_data(const vector<order> &_ol, int v) : o(_ol), ot0(_ol.size()), odst(v) {
        sort(ALL_OF(o), [](const order &o, const order &p) {
            return o.t0 < p.t0 || (!(o.t0 < p.t0) && o.id < p.id);
        });
        REP(i, o.size()) {
            ot0[i] = o[i].t0;
            odst[o[i].dst].emplace_back(i);
        }
    }
    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<pair<int, int>>> simulate() const {
        
        vector<int> fns(rank.size(), false);
        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;
        int loaded = 0;
        int achived = 0;
        int curr = 0, goal = 0;
        // {dst, until}
        // 直前の行動が plan.back().first で、現在時刻 t がplan.back().secondで求められる
        vector<pair<int, int>> plan = {{0, 0}};
        plan.reserve(inp.tmax);
        while (plan.back().second <= inp.tmax) {

            int tnow = plan.back().second;
            
            if (curr == 0) {
                lastload = tnow;
                loaded = upper_bound(ALL_OF(inp.o.ot0), lastload) - inp.o.ot0.begin();
            } else {
                for (const int &i : inp.o.odst[curr]) {
                    if (!fns[i] && inp.o.o[i].t0 <= lastload) {
                        ll wt = tnow - inp.o.o[i].t0;
                        score += basic_term - wt * wt;
                        achived++;
                        fns[i] = true;
                    }
                }
            }

            if (tnow == inp.tmax) break;

            if (loaded == achived) {
                if (curr == 0) {
                    if (plan.back().first == -1) {
                        plan.back().second++;
                    } else {
                        plan.emplace_back(-1, tnow + 1);
                    }
                    continue;
                } else {
                    goal = 0;
                }
            } else {
                int cand = 0, crank = INF;
                REP(i, loaded) {
                    const int &dst = inp.o.o[i].dst;
                    if (!fns[i] && chmin(crank, inp.g.distance(dst, curr) * (1 + rankinv[i]))) {
                        cand = dst;
                    }
                }
                goal = cand;
            }

            int dest = inp.g.xm[curr][goal];
            plan.emplace_back(dest, tnow + inp.g.gm[curr][dest]);
            curr = dest;

        }

        return make_pair(score, plan);

    }

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

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

    void mutate_range() {
        
        int i = xor128() % rank.size();
        int j = xor128() % (rank.size() - 1);
        if (i <= j) j++;
        if (i > j) swap(i, j);

        vector<int> temp; temp.reserve(j - i + 1);
        copy(rank.begin() + i, rank.begin() + j + 1, back_inserter(temp));
        rank.erase(rank.begin() + i, rank.begin() + j + 1);

        int k = xor128() % (rank.size() + 1);
        rank.insert(rank.begin() + k, ALL_OF(temp));

    }

};

// 処理内容
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;

    vector<pair<ll, ll>> history = {{0, best_sim.first}};
    vector<pair<ll, ll>> history_best = {{0, best_sim.first}};
    
    for (double t = 0; (t = marathon::progress()) <= 0.99; epoch++) {

        schedule s1 = s;
        // if (rand_prob(1.0 - t)) {
            // 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) {
            history.emplace_back(epoch + 1, sim.first);
            history_best.emplace_back(epoch + 1, best_sim.first);
        }
        
    }

    if (DEBUG_MODE) {
        DUMP(epoch);
        DUMP(best_sim.first);
        ofstream ofs("history.txt");
        ofs << history.size() << endl;
        for (const auto &p : history) {
            ll x, y; tie(x, y) = p;
            ofs << x << " " << y << endl;
        }
        for (const auto &p : history_best) {
            ll x, y; tie(x, y) = p;
            ofs << x << " " << y << endl;
        }
        ofs.close();
    }

    vector<int> ans; ans.reserve(inp.tmax);
    int ti = 0;
    for (auto &p : best_sim.second) {
        REP(i, p.second - ti) {
            if (ans.size() < inp.tmax) {
                ans.push_back(p.first);
            } else {
                break;
            }
        }
        ti = p.second;
        if (ans.size() >= inp.tmax) break;
    }
    ans.resize(inp.tmax, -1);
    
    for (int i : ans) {
        cout << (i < 0 ? -1 : i+1) << endl;
    }
    
}


Measured memory_bytes: 4700