// とりあえず完成

#ifndef TIMER_H
#define TIMER_H

#include <cstdint>

#ifdef ONLY_MY_ENVIR

#include <chrono>
class Timer {
	const std::chrono::time_point<std::chrono::system_clock> start;
	int64_t limit_microsec = 0;

public:
	Timer();
	void set(int64_t time_microsec);
	bool elapsed() const;
	int64_t getMicrosec() const;
};

#else

class Timer {
	static const uint64_t ClocksPerMicrosec;
	const uint64_t start_clocks;
	uint64_t limit_clocks;

	uint64_t getClocks() const;
public:
	Timer();
	void set(int64_t time_microsec);
	bool elapsed() const;
	int64_t getMicrosec() const;
};

#endif

#endif

#ifdef ONLY_MY_ENVIR
#include "Timer.h"
#endif

#ifdef ONLY_MY_ENVIR

using namespace std::chrono;

Timer::Timer()
	: start(system_clock::now()) {
}

void Timer::set(int64_t time_microsec) {
	limit_microsec += time_microsec;
}

bool Timer::elapsed() const {
	return getMicrosec() >= limit_microsec;
}

int64_t Timer::getMicrosec() const {
	return duration_cast<microseconds>(system_clock::now() - start).count();
}

#else

const uint64_t Timer::ClocksPerMicrosec = 2790;

uint64_t Timer::getClocks() const {
	unsigned int lo, hi;
	__asm__ volatile ("rdtsc" : "=a" (lo), "=d" (hi));
	return ((uint64_t)hi << 32) | lo;
}

Timer::Timer() 
	: start_clocks(getClocks()), limit_clocks(start_clocks) {
}

void Timer::set(int64_t time_microsec) {
	limit_clocks += time_microsec * ClocksPerMicrosec;
}

bool Timer::elapsed() const {
	return getClocks() >= limit_clocks;
}

int64_t Timer::getMicrosec() const {
	return (getClocks() - start_clocks) / ClocksPerMicrosec;
}

#endif
#ifndef RANDOM_H
#define RANDOM_H

#include <cstdint>

uint32_t rnd();
uint32_t rnd(uint32_t max);

#endif
#ifdef ONLY_MY_ENVIR
#include "Random.h"
#endif

uint32_t rnd() {
	static uint32_t val = 3141592653ul;
	val ^= val << 13;
	val ^= val >> 17;
	val ^= val << 15;
	return val;
}

uint32_t rnd(uint32_t max) {
	return rnd() % max;
}

#ifndef __GLOBAL_H__
#define __GLOBAL_H__

#define _CRT_SECURE_NO_WARNINGS
#define _SCL_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <utility>
#include <algorithm>
#include <functional>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <limits>
#include <numeric>
#include <valarray>
#include <fstream>
#include <array>
#include <random>
#include <unordered_set>
#include <unordered_map>

#define REP(i, a, n) for(int i = (a), i##_max_ = (n); i < i##_max_; ++i)
#define REM(i, a, n) for(int i = (int)(n) - 1, i##min_ = (a); i >= i##min_; --i)

template <class T, class TCompatible, size_t N>
void Fill(T(&dest)[N], const TCompatible& val) {
	fill(dest, dest + N, val);
}

template <class T, class TCompatible, size_t M, size_t N>
void Fill(T(&dest)[M][N], const TCompatible& val) {
	for (int i = 0; i < M; ++i) {
		Fill(dest[i], val);
	}
}

template <class T>
T read(std::istream& ist) {
	T buffer;
	ist >> buffer;
	return buffer;
}

#endif


#ifndef __MAIN_H__
#define __MAIN_H__

#ifdef ONLY_MY_ENVIR
#include "Global.h"
#include "Random.h"
#endif

#ifdef ONLY_MY_ENVIR

std::ifstream input_stream("in.txt");
std::ofstream output_stream("out.txt");

#define cin input_stream
#define cout output_stream

#else

using std::cin;
using std::cout;

#endif

using Edge = std::pair<int, int>;
using Graph = std::vector<std::vector<Edge>>;
using Command = int;
using Path = std::vector<int>;
using Score = int64_t;

template <class T>
using Matrix = std::vector<std::vector<T>>;

struct Order {
	int t;
	int id;
	int v;

	Order() = default;
	Order(int t, int id, int v) 
		: t(t), id(id), v(v) {
	}
};

class Annealer {
	using Route = std::vector<int>;
	using State = std::vector<std::pair<int, Route>>;	// (休みターン数, 巡回路)

	const int ActionCount = 30;
	State state;
	std::vector<std::vector<bool>> used;

	Score score;
	Score prev_score;

	const int t_max;
	const Graph graph;
	const std::vector<Order> orders;
	const Matrix<int> dist_mat;

	struct Memo {
		enum class Type {
			AddVertex,
			EraseVertex,
			StretchRestTime
		};

		Type type;
		int aidx;
		int pos;
		int v;
		int delta;
	} memo;

public:
	Annealer(int t_max, const Graph& graph, const std::vector<Order>& orders, const Matrix<int> dist_mat)
		: t_max(t_max), graph(graph), orders(orders), dist_mat(dist_mat),
		state(ActionCount), used(ActionCount, std::vector<bool>(graph.size())) {

		score = calc();
	}

	Score step() {
		prev_score = score;
		const int N = graph.size();

		int aidx = rnd(state.size());
		if (rnd(2)) {
			// 経路を変更する
			Route& route = state[aidx].second;
			int length = route.size();
			if (rnd(2)) {
				// 頂点を追加
				int pos = rnd(length + 1);
				int v_prev = pos == 0 ? 0 : route[pos - 1];
				int degree = graph[v_prev].size();
				int v = graph[v_prev][rnd(degree)].first;
				if (used[aidx][v]) return 0;

				memo.type = Memo::Type::AddVertex;
				memo.aidx = aidx;
				memo.pos = pos;
				addVertex(aidx, pos, v);
			} else {
				// 頂点を削除
				if (length == 0) return 0;
				int pos = rnd(length);

				memo.type = Memo::Type::EraseVertex;
				memo.aidx = aidx;
				memo.pos = pos;
				memo.v = route[pos];
				eraseVertex(aidx, pos);
			}
		} else {
			// 休みを伸縮させる
			memo.type = Memo::Type::StretchRestTime;
			memo.aidx = aidx;
			if (rnd(2)) {
				memo.delta = 1;
				stretchRestTime(aidx, 1);
			} else {
				if (state[aidx].first == 0) return 0;

				memo.delta = -1;
				stretchRestTime(aidx, -1);
			}
		}

		score = calc();
		return score - prev_score;
	}

	void undo() {
		switch (memo.type) {
		case Memo::Type::AddVertex:
			eraseVertex(memo.aidx, memo.pos);
			break;
		case Memo::Type::EraseVertex:
			addVertex(memo.aidx, memo.pos, memo.v);
			break;
		case Memo::Type::StretchRestTime:
			stretchRestTime(memo.aidx, -memo.delta);
			break;
		}
		score = prev_score;
	}

	void addVertex(int aidx, int pos, int v) {
		Route& route = state[aidx].second;
		route.insert(route.begin() + pos, v);
		used[aidx][v] = true;
	}

	void eraseVertex(int aidx, int pos) {
		Route& route = state[aidx].second;
		int v = route[pos];
		used[aidx][v] = false;
		route.erase(route.begin() + pos);
	}

	void stretchRestTime(int aidx, int delta) {
		state[aidx].first += delta;
	}

	State get() const {
		return state;
	}

	Score getScore() const {
		return score;
	}

private:
	Score calc() const {
		// order を 区別するのに id ではなく orders に対する添字を使っていることに注意
		const int N = graph.size();
		std::vector<std::vector<int>> tasks(N);
		int tpos = 0;		// orders に対する添字; [0, tpos_loaded) 番目のタスクが生じている
		int t = 0;			// 現在時刻
		int t_last = 0;		// 最後に行動した時刻

		// 荷物を車に積む (タスクの増加)
		auto update = [this, &tpos, &t, &tasks]() -> void {
			while (tpos < orders.size() && orders[tpos].t <= t) {
				int v = orders[tpos].v;
				tasks[v].push_back(tpos);
				++tpos;
			}
		};

		Score score = 0;
		for (const auto& action : state) {
			// 休みターン数を消化
			t += action.first;
			update();			// 休みと巡回は交互なので、更新タイミングはここだけで良い
			
			// 経路をたどる
			const Route& route = action.second;
			int v_curr = 0;
			for (auto v : route) {
				t += dist_mat[v_curr][v];
				t_last = t;

				// 頂点を訪れる
				for (int tpos : tasks[v]) {
					int64_t t_opt = orders[tpos].t;
					int64_t t_diff = t - t_opt;
					Score delta = int64_t(t_max) * t_max - t_diff * t_diff;
					score += delta;
				}

				// 完了したタスクは消去
				tasks[v].clear();
				v_curr = v;
			}
			t += dist_mat[v_curr][0];
		}

		constexpr Score penalty = 1e15;
		constexpr int reserve = 400;
		int t_excess = std::max(0, std::max(t_last, t - reserve) - t_max);
		score -= t_excess * penalty;
		return score;
	}
};

void problemA();
std::vector<Command> solveA(const Graph& graph, int t_max, const std::vector<Order>& orders);
std::pair<Matrix<int>, Matrix<Path>> findShortestPaths(const Graph& graph);
Graph readGraph(std::istream& ist);
std::vector<Order> readOrders(std::istream& ist, int t_max);
void write(std::ostream& ost, Command command);

#endif

#ifdef ONLY_MY_ENVIR
#include "Main.h"
#include "Timer.h"
#endif

/* V <= 400, E <= 800, D <= 114 */

int main() {
	problemA();
	return 0;
}

void problemA() {
	Graph graph = readGraph(cin);
	int t_max = read<int>(cin);
	auto orders = readOrders(cin, t_max);
	auto commands = solveA(graph, t_max, orders);
	for (Command c : commands) {
		write(cout, c);
	}
	return;
}

std::vector<Command> solveA(const Graph& graph, int t_max, const std::vector<Order>& orders) {
	Timer timer;

	// 最短路の前計算
	auto pair = findShortestPaths(graph);
	Matrix<int> dist_mat = pair.first;
	Matrix<Path> path_mat = pair.second;

	// 最適化
	Annealer annealer(t_max, graph, orders, dist_mat);
	constexpr int time_limit = 29900000;
	constexpr double tmp_start = 1e9;
	constexpr double tmp_finish = 1e5;
	double tmp = tmp_start;

	int z = 0;
	timer.set(time_limit);
	while (!timer.elapsed()) {
		++z;
		if (z % 256 == 0) {
			double ratio = double(timer.getMicrosec()) / time_limit;
			tmp = tmp_start * std::pow(tmp_finish / tmp_start, ratio);
#if ONLY_MY_ENVIR
			std::cerr << tmp << ' ' << annealer.getScore() << std::endl;
#endif
		}

		Score delta = annealer.step();
		bool accepted = delta >= 0
			|| -delta <= 8 * tmp && rnd() < std::exp(delta / tmp) * (1ll << 32);

		if (!accepted) {
			annealer.undo();
		}
	}

	std::cerr << annealer.getScore() << std::endl;
	auto state = annealer.get();

	// 復元
	std::vector<Command> ret;
	for (const auto& action : state) {
		// 休み
		REP(z, 0, action.first) {
			ret.push_back(-1);
		}

		// 経路を巡る
		std::vector<int> route = action.second;
		route.push_back(0);		// 終点を追加

		int start = 0;
		for (int goal : route) {
			// start -> goal に移動する
			int from = start;
			for (int to : path_mat[start][goal]) {
				REP(z, 0, dist_mat[from][to]) {		// 意味的には dist_mat を使うのは微妙
					ret.push_back(to);
				}
				from = to;
			}
			start = goal;
		}
	}

	while (ret.size() < t_max) {
		ret.push_back(-1);
	}

	while (ret.size() > t_max) {
		ret.pop_back();
	}

	return ret;
}

std::pair<Matrix<int>, Matrix<Path>> findShortestPaths(const Graph& graph) {
	auto subFunc = [](const Graph& graph, int start) -> std::pair<std::vector<int>, std::vector<Path>> {
		const int N = graph.size();
		const int inf = 1e9;
		using State = std::tuple<int, int, int>;
		std::priority_queue<State, std::vector<State>, std::greater<State>> que;

		std::vector<int> dists(N, inf);
		std::vector<int> prevs(N, -1);
		que.push(State(0, start, -1));
		while (!que.empty()) {
			auto p = que.top(); que.pop();
			int dist = std::get<0>(p);
			int from = std::get<1>(p);
			int prev = std::get<2>(p);
			if (dists[from] != inf) continue;
			dists[from] = dist;
			prevs[from] = prev;
			for (auto e : graph[from]) {
				int to = e.first;
				int cost = e.second;
				que.push(State(dist + cost, to, from));
			}
		}

		std::vector<Path> paths;
		REP(i, 0, N) {
			Path path;
			int curr = i;
			while (curr != start) {
				path.push_back(curr);
				curr = prevs[curr];
			}
			std::reverse(path.begin(), path.end());
			paths.emplace_back(std::move(path));
		}
		return std::make_pair(dists, paths);
	};

	const int N = graph.size();
	Matrix<int> dist_mat;
	Matrix<Path> path_mat;

	REP(start, 0, N) {
		auto pair = subFunc(graph, start);
		dist_mat.emplace_back(std::move(pair.first));
		path_mat.emplace_back(std::move(pair.second));
	}

	return std::make_pair(dist_mat, path_mat);
}

Graph readGraph(std::istream& ist) {
	int N, M;
	ist >> N >> M;

	Graph ret(N);
	REP(j, 0, M) {
		int a, b, c;
		cin >> a >> b >> c;
		--a; --b;
		ret[a].push_back(Edge(b, c));
		ret[b].push_back(Edge(a, c));
	}

	return ret;
}

std::vector<Order> readOrders(std::istream& ist, int t_max) {
	std::vector<Order> ret;
	REP(t, 0, t_max) {
		int k;
		cin >> k;
		REP(i, 0, k) {
			int id, v;
			cin >> id >> v;
			--v;
			ret.push_back(Order(t, id, v));
		}
	}
	return ret;
}

void write(std::ostream& ost, Command command) {
	if (command == -1) {
		ost << -1 << std::endl;
	} else {
		ost << command + 1 << std::endl;
	}
}



Measured memory_bytes: 36420