#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>

#define rep(i, m, n) for(int i=int(m);i<int(n);i++)
#define all(c) begin(c),end(c)

template<typename T1, typename T2>
inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
using Int = long long int;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x)  cerr << #x << " = " << (x) << endl
#define MOD 1000000007

const double TL = 25.0;

unsigned int rnd(void) {
    static unsigned int y = 13333;
    y = y ^ (y << 13);
    y = y ^ (y >> 17);
    return y = y ^ (y << 5);
}


//edit
class UnionFind {
    vector<int> p;//p[i]はiの属する組織
public:
    UnionFind(int n) {
        p = vector<int>(n);
        for (int i = 0; i < n; i++) {
            p[i] = i;
        }
        return;
    }

/* xの属する集合を返す */
    int find(int x) {
        if (p[x] == x) return x;
        return p[x] = find(p[x]);
    }

/* yにxを統合する */
    void unite(int x, int y) {
        p[find(x)] = p[find(y)];
    }

/* xとyが属する集合が同じかを判定する */
    bool same(int x, int y) {
        return find(x) == find(y);
    }

};

class Graph {
public:
    int V;
    vector<vector<pair<int, int>>> adjacency_list;
    vector<vector<int>> adjacency_matrix;
    vector<vector<pair<int, int>>> shortest_paths;

    Graph(int V) : V(V), adjacency_list(V), adjacency_matrix(V, vector<int>(V, -1)),
                   shortest_paths(V, vector<pair<int, int>>(V, pair<int, int>(INF, -1))) {

        for (int i = 0; i < V; ++i) {
            adjacency_matrix[i][i] = shortest_paths[i][i].first = 0;
        }
    }

    void add_edge(int v1, int v2, int cost) {
        adjacency_list[v1].push_back({v2, cost});
        adjacency_list[v2].push_back({v1, cost});
        adjacency_matrix[v1][v2] = adjacency_matrix[v2][v1] = shortest_paths[v1][v2].first = shortest_paths[v2][v1].first = cost;
        shortest_paths[v1][v2].second = v2;
        shortest_paths[v2][v1].second = v1;
    }

    void compute_shortest_paths() {
        for (int k = 0; k < V; ++k) {
            for (int i = 0; i < V; ++i) {
                for (int j = 0; j < V; ++j) {
//                    shortest_paths[i][j] = min(shortest_paths[i][j], shortest_paths[i][k] + shortest_paths[k][j]);
                    if (shortest_paths[i][k].second != -1 && shortest_paths[k][j].second != -1 &&
                        shortest_paths[i][j].first > shortest_paths[i][k].first + shortest_paths[k][j].first) {
                        shortest_paths[i][j].first = shortest_paths[i][k].first + shortest_paths[k][j].first;
                        shortest_paths[i][j].second = shortest_paths[i][k].second;
                    }
                }
            }
        }
    }

};

class Moving {
public:
    queue<int> dests; //目的地のqueue
    Graph G;
    int from = 1, to = 1;
    int dist = 0; //fromからどれだけ離れているか

    Moving(Graph G) : G(G) {

    }

    void add_dest(int v) {
        dests.push(v);
    }

    void add_dests(vector<int> vs) {
        for (auto e : vs) {
            dests.push(e);
        }
    }

    //目的地に移動しつつ、クエリを出力
    void move_dest() {
        if (from != to) {
            if (dist < G.adjacency_matrix[from][to]) {
                cout << to << endl;
                dist++;
            } else {
                cout << -1 << endl;
            }

            if (dist == G.adjacency_matrix[from][to]) {
                dist = 0;
                from = to;
                while (!dests.empty() && from == dests.front()) {
                    dests.pop();
                }

                if (!dests.empty()) {
                    to = G.shortest_paths[from][dests.front()].second;
                } else {
                    to = from;
                }
            }
        } else {
            while (!dests.empty() && from == dests.front()) {
                dests.pop();
            }

            if (dests.empty()) {
                cout << -1 << endl;
            } else {
                to = G.shortest_paths[from][dests.front()].second;
                move_dest();
            }
        }

    }
};

class Solve {
public:
    int V, E;

    void solve() {
        std::cin >> V >> E;
//        std::vector<std::vector<std::pair<int, int>>> G(V + 1);
        Graph G(V + 1);

        for (int i = 0; i < E; i++) {
            // recieve edges
            int u, v, d;
            std::cin >> u >> v >> d;
            G.add_edge(u, v, d);
        }
        G.compute_shortest_paths();
        Moving moving(G);


        int Tmax;
        std::cin >> Tmax;

        // recieve info
        auto compute_best_path = [this, &G](vector<int> &vs, double time, double Ts, double Te) {
            // vs.front()とvs.back()を固定して焼きなましを行う
            clock_t pre_begin = clock();
            if (vs.size() <= 3) return;

            UnionFind uf(V + 1);
            vector<vector<int>> treeone(V + 1);
            vector<pair<int, pair<int, int>>> edges;
            for (int i = 0; i < vs.size(); ++i) {
                for (int j = i + 1; j < vs.size(); ++j) {
                    edges.push_back(make_pair(G.shortest_paths[vs[i]][vs[j]].first, make_pair(vs[i], vs[j])));
                }
            }
            sort(all(edges));
            for (auto e : edges) {
                if (!uf.same(e.second.first, e.second.second)) {
                    treeone[e.second.first].push_back(e.second.second);
                    treeone[e.second.second].push_back(e.second.first);
                    uf.unite(e.second.first, e.second.second);
                }
            }

            vector<int> best_state;
            {
                stack<int> st;
                vector<bool> used(V + 1, false);
                st.push(1);
                used[1] = true;
                while (!st.empty()) {
                    int top = st.top();
                    best_state.push_back(top);
                    st.pop();
                    for (auto e : treeone[top]) {
                        if (!used[e]) {
                            st.push(e);
                            used[e] = true;
                        }
                    }
                }
                best_state.push_back(1);
            }


            Int best_score = 0;
            for (int i = 1; i < vs.size(); ++i) {
                best_score += G.shortest_paths[best_state[i - 1]][best_state[i]].first;
            }
            Int cur_score = best_score;
            vector<int> cur_state = vs;

            double pre_time = 1. * (clock() - pre_begin) / CLOCKS_PER_SEC;
            time -= pre_time;
            clock_t begin_time = clock();
            while (true) {
                clock_t current_time = clock();
                double elapsed_time = 1. * (current_time - begin_time) / CLOCKS_PER_SEC;
                if (elapsed_time > time) break;

                int x = rnd() % (vs.size() - 2) + 1;
                int y = rnd() % (vs.size() - 2) + 1;
                if (x == y) {
                    x = rnd() % (vs.size() - 2) + 1;
                    y = rnd() % (vs.size() - 2) + 1;
                }
                if (x > y) swap(x, y);

                reverse(cur_state.begin() + x, cur_state.begin() + y + 1);
                Int new_score = 0;
                for (int i = 1; i < cur_state.size(); ++i) {
                    new_score += G.shortest_paths[cur_state[i - 1]][cur_state[i]].first;
                }

                Int diff_score = new_score - cur_score;
                if (diff_score < 0) {
                    cur_score = new_score;
                } else {
                    double Tc = (Te - Ts) * (elapsed_time / time) + Ts;
                    double P = exp(-diff_score / Tc);
                    Int R = 1000000;
                    if (rnd() % R < P * R) {
                        cur_score = new_score;
                    } else {
                        reverse(cur_state.begin() + x, cur_state.begin() + y + 1);
                    }
                }

                if (cur_score < best_score) {
                    best_score = cur_score;
                    best_state = cur_state;
                }
            }

            vs = best_state;
        };


        vector<int> visit;
        for (int i = 0; i < Tmax; i++) {
            int Nnew;
            std::cin >> Nnew;
            for (int j = 0; j < Nnew; j++) {
                int new_id, dst;
                std::cin >> new_id >> dst;
                visit.push_back(dst);
            }
            if (visit.size() && moving.dests.empty()) {
                int sz = visit.size();
                sort(all(visit));
                visit.erase(unique(all(visit)), visit.end());
                visit.insert(visit.begin(), 1);
                visit.push_back(1);
                compute_best_path(visit, 1. * TL * sz / 5000, 2e3, 1e-10);
                moving.add_dests(visit);
                visit.erase(visit.begin(), visit.end());
//                cerr << i << endl;
            }
//            if(moving.dests.empty()){
//                moving.add_dests(neri);
//            }

            moving.move_dest();
//            if (moving.dist == 0 && moving.from == 1) {
//                cerr << i << endl;
//            }
        }
    }
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    Solve().solve();


    return 0;
}


Measured memory_bytes: 9040