#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<numeric>
#include<functional>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_set>
#include<unordered_map>
#include<random>
#include<array>
#include<cassert>
#include<ctime>
#include<memory>
#include <chrono>
using namespace std;
#define INF (1<<29)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(v) v.begin(),v.end()
#define uniq(v) v.erase(unique(all(v)),v.end())




template<class T>
class IntervalHeap {
	std::vector<T> data;
	template<int b, class C>
	void heapup(C cmp, int k = -1) {
		if (k == -1)k = (1 + size()) / 2 - 1;
		int p;
		while (k) {
			p = (k - 1) / 2;
			if (!cmp(data[2 * k + b], data[2 * p + b]))break;
			std::swap(data[2 * k + b], data[2 * p + b]);
			k = p;
		}
	}
	template<int b, class C>
	void heapdown(C cmp) {
		int x, k = 0;
		while (1) {
			x = 2 * k + 1;
			if (size() <= 2 * x + b)break;
			if (2 * (x + 1) + b < size() && cmp(data[2 * (x + 1) + b], data[2 * x + b]))x++;
			if (!cmp(data[2 * x + b], data[2 * k + b]))break;
			std::swap(data[2 * x + b], data[2 * k + b]);
			if (2 * x + 1 < size() && data[2 * x + 1] < data[2 * x])
				std::swap(data[2 * x + 1], data[2 * x]);
			k = x;
		}
	}
public:
	int size()const { return data.size(); }
	void push(T v) {
		if (size() & 1) {
			data.push_back(v);
			if (data[size() - 2] > data[size() - 1]) {
				std::swap(data[size() - 2], data[size() - 1]);
				heapup<0>(std::less<T>());
			}
			else heapup<1>(std::greater<T>());
		}
		else {
			data.push_back(v);
			if (2 < size()) {
				int k = (1 + size()) / 2 - 1;
				int p = (k - 1) / 2;
				if (data[2 * p] > data[2 * k])heapup<0>(std::less<T>());
				else if (data[2 * p + 1] < data[2 * k]) {
					std::swap(data[2 * p + 1], data[2 * k]);
					heapup<1>(std::greater<T>(), p);
				}
			}
		}
	}
	T min()const { return data.front(); }
	T max()const { return 1 < size() ? data[1] : data[0]; }
	void deleteMin() {
		data[0] = data[size() - 1];
		data.pop_back();
		heapdown<0>(std::less<T>());
	}
	void deleteMax() {
		if (size() == 1) {
			data.pop_back();
			return;
		}
		data[1] = data[size() - 1];
		data.pop_back();
		heapdown<1>(std::greater<T>());
	}
	void print()const {
		for (int i = 0; i < data.size(); i += 2) {
			cout << '(' << data[i];
			if (i + 1 < size())cout << ',' << data[i + 1];
			cout << ')';
			int k = i / 2 + 1;
			if (k + 1 == ((k + 1) & -(k + 1)))cout << endl;
		}cout << endl;
	}
};




std::random_device seed_gen;
std::mt19937 engine(seed_gen());



int dist[400][400];
int nxt_to[400][400];
int edge[400][400];

vector<vector<pair<int, int>>> order;

int lastTumi = -1;
vector<int> ordered_time[400];
tuple<int, int, int> cur;
set<int> donthave, having;


pair<int, int> dist_to(int u, int v, int d, int dst) { // on edge u-v dist d
	if (d == 0) {
		if (u == dst)return make_pair(0, -2);
		return make_pair(dist[u][dst], nxt_to[u][dst]);
	}
	else if (d + dist[u][dst] < edge[u][v] - d + dist[v][dst]) {
		return make_pair(d + dist[u][dst], u);
	}
	else {
		return make_pair(edge[u][v] - d + dist[v][dst], v);
	}
}

tuple<int, int, int> move(const tuple<int, int, int> & cur, int dst) {
	if (dst == -2)return cur;
	int u, v, d;
	tie(u, v, d) = cur;
	if (u == dst) {
		d--;
		if (d == 0)return make_tuple(u, -1, 0);
		else return make_tuple(u, v, d);
	}
	else if (v == dst) {
		d++;
		if (d == edge[u][v])return make_tuple(v, -1, 0);
		else return make_tuple(u, v, d);
	}
	else {
		//assert(d == 0);
		if (edge[u][dst] > 1)return make_tuple(u, dst, 1);
		else return make_tuple(dst, -1, 0);
	}
}



vector<int> chokudai_search(int ti, const set<int> & ss, int W) {
	vector<pair<int, int>> path;


	//int pena = 1200 * 10000;
	constexpr int pena = 33000;

	struct State {
		State() { memset(vis, 0, sizeof(vis)); vis[0] = 1; }
		uint64_t vis[7];
		int64_t score = 0;
		int pos = 0;
		int pathid = -1;
		int64_t time = 0;
		int64_t cmp = 0;
		//bool operator<(const State& s) const { return score > s.score; }
		//bool operator<(const State& s) const { return cmp > s.cmp; }
		bool operator<(const State& s) const { return cmp < s.cmp; }
		bool operator>(const State& s) const { return cmp > s.cmp; }
	};
	IntervalHeap<State> heap[401];

	int best_v = 0;
	int64_t best_s = 0;

	int V = ss.size();
	vector<int> vv(ss.begin(), ss.end());
	vector<int> dd(400, 0);
	for (int a : vv) {
		for (int t : ordered_time[a]) {
			int dif = ti - t;
			dd[a] += dif * dif * 5;
		}
	}

	heap[0].push(State());
	path.reserve(W * V * V);

	chrono::system_clock::time_point start = chrono::system_clock::now();

	rep(ite, W) {
		//cerr << ite << endl;
		rep (i, V) {
			if (heap[i].size() == 0)continue;
			while (heap[i].size() > W)heap[i].deleteMin();
			const State s = heap[i].max();	
			heap[i].deleteMax();
			for (int j : vv) if ((s.vis[j / 64] >> (j % 64) & 1) == 0) {
				State t = s;
				t.vis[j / 64] |= 1LL << (j % 64);
				t.pos = j;
				t.score += 10000 * 10000;
				//int dif = ti - ordered_time[j][0];
				//t.score += dif * dif * 5;
				t.score += dd[j];
				t.score -= dist[s.pos][j] * pena;

				t.pathid = path.size();

				t.time += dist[s.pos][j];
				path.emplace_back(s.pathid, j);

				t.cmp = t.score - t.time * t.time * pena;
				heap[i + 1].push(t);
				/*if (t.score - dist[s.pos][j] * pena > best_s) {
					best_s = t.score - dist[s.pos][j] * pena;
					best_v = t.pathid;
				}*/
				t.time += dist[0][j];
				t.cmp = t.score - t.time * t.time * pena;
				if (t.cmp > best_s) {
					best_s = t.cmp;
					best_v = t.pathid;
				}
			}
		}
	}
	vector<int> ret;
	int id = best_v;
	ret.push_back(0);
	while (id >= 0) {
		ret.push_back(path[id].second);
		id = path[id].first;
	}

	reverse(ret.begin(), ret.end());
	//cerr << ret.size() << endl;

	return ret;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);


	// recieve |V| and |E|
	int V, E; std::cin >> V >> E;
	rep(u, V)rep(v, V)dist[u][v] = INF;
	memset(nxt_to, -1, sizeof(nxt_to));
	memset(edge, -1, sizeof(edge));

	for (int i = 0; i < E; i++) {
		// recieve edges
		int u, v, d; std::cin >> u >> v >> d;
		u--; v--;
		dist[u][v] = dist[v][u] = d;
		edge[u][v] = d;
		edge[v][u] = d;
	}
	rep(i, V)dist[i][i] = 0;
	rep(k, V)rep(i, V)rep(j, V)
		dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);

	rep(i, V) {
		rep(j, V)if (edge[i][j] != -1) {
			rep(k, V) {
				if (edge[i][j] + dist[j][k] == dist[i][k]) {
					nxt_to[i][k] = j;
				}
			}
		}
	}
	/*rep(i,V) {
		rep(j, V)fprintf(stderr, "%3d ", dist[i][j]);
		fprintf(stderr, "\n");
	}*/

	vector<int> vers;
	int vi = 0;
	//return 0;

	chrono::system_clock::time_point start = chrono::system_clock::now();

	int Tmax; std::cin >> Tmax;
	order.resize(Tmax);

	cur = make_tuple(0, -1, 0);
	bool flag = false;

	// recieve info
	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;
			order[i].emplace_back(new_id, dst);
		}
	}

	long long score = 0;

	for (int i = 0; i < Tmax; i++) {
		//std::cout << -1 << std::endl;

		for (auto p : order[i]) {
			int new_id, dst;
			tie(new_id, dst) = p;
			ordered_time[dst - 1].push_back(i);
			donthave.insert(dst - 1);
		}

		if (get<2>(cur) == 0 && get<0>(cur) == 0) {
			lastTumi = i;
			having.insert(all(donthave));
			donthave.clear();
			flag = false;

			if (having.size()) {
				chrono::system_clock::time_point now = chrono::system_clock::now();
				int width = 200;
				if (now - start > chrono::seconds(20))width = 100;
				vers = chokudai_search(i, having, width);
				vi = 0;
				//cerr << "    "<<i << endl;
			}
		}


		if (vers.empty()) {
			cout << -1 << endl;
		}
		else if (get<0>(cur) == vers[vi] && get<2>(cur) == 0) {
			vi = (vi + 1) % vers.size();
			int u, v, d;
			tie(u, v, d) = cur;
			auto p = dist_to(u, v, d, vers[vi]);

			cout << p.second + 1 << endl;
			cur = move(cur, p.second);
		}
		else {
			int u, v, d;
			tie(u, v, d) = cur;
			auto p = dist_to(u, v, d, vers[vi]);

			cout << p.second + 1 << endl;
			cur = move(cur, p.second);
		}


		if (get<2>(cur) == 0) {
			int u = get<0>(cur);
			while (ordered_time[u].size() && ordered_time[u].front() <= lastTumi) {
				score += Tmax * Tmax - (i + 1 - ordered_time[u][0]) * (i + 1 - ordered_time[u][0]);
				ordered_time[u].erase(ordered_time[u].begin());
				flag = true;
			}
			having.erase(u);
		}
	}

	cerr << score << endl;
	chrono::system_clock::time_point end = chrono::system_clock::now();
	chrono::seconds seconds = chrono::duration_cast<chrono::seconds>(end - start);
	//cerr << seconds.count() << endl;

	return 0;
}

Measured memory_bytes: 107076