// B問題と同じTSP解法

#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;
}

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) {
	}
};

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

#endif



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

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

	Graph ret(N);
	REP(j, 0, M) {
		int a, b, c;
		ist >> 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) {
		auto orders = readOrdersOneTurn(ist, t);
		for (const Order& order : orders) {
			ret.push_back(order);
		}
	}
	return ret;
}

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

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


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);
}

#ifndef __TSP_H__
#define __TSP_H__

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

class TSPOracle {
	std::vector<int> state;
	int score;
	int estim_score;

	const int size;
	const Matrix<int> dist_mat;

	struct Memo {
		int l;
		int r;
	} memo;

public:
	TSPOracle(const Matrix<int>& dist_mat);
	int estimate();
	void transition();
	int getScore() const;
	std::vector<int> get() const;

private:
	int calc() const;
};

std::vector<int> solveTSP(const Matrix<int>& dist_mat);

#endif

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

TSPOracle::TSPOracle(const Matrix<int>& dist_mat)
	: size(dist_mat.size()), dist_mat(dist_mat) {

	REP(i, 0, size) {
		state.push_back(i);
	}
	state.push_back(0);
	score = calc();
}

int TSPOracle::estimate() {
	int l;
	int r;
	do {
		l = rnd(size) + 1;
		r = rnd(size) + 1;
	} while (l == r);
	if (l > r) std::swap(l, r);

	memo.l = l;
	memo.r = r;

	int u0 = state[l - 1];
	int u1 = state[l];
	int v0 = state[r - 1];
	int v1 = state[r];

	int delta = 0;
	delta -= dist_mat[u0][u1] + dist_mat[v0][v1];
	delta += dist_mat[u0][v0] + dist_mat[u1][v1];
	
	estim_score = score + delta;
	return -delta;
}

void TSPOracle::transition() {
	std::reverse(state.begin() + memo.l, state.begin() + memo.r);
	score = estim_score;
}

int TSPOracle::getScore() const {
	return score;
}

std::vector<int> TSPOracle::get() const {
	std::vector<int> ret(state);
	ret.erase(ret.begin());
	return ret;
}

int TSPOracle::calc() const {
	int sum = 0;
	REP(i, 0, size) {
		int from = state[i];
		int to = state[i + 1];
		sum += dist_mat[from][to];
	}
	return sum;
}

std::vector<int> solveTSP(const Matrix<int>& dist_mat) {
	Timer timer;

	// 最適化
	TSPOracle oracle(dist_mat);
	constexpr int time_limit = 25000000;
	constexpr double tmp_start = 1e4;
	constexpr double tmp_finish = 0.02;
	double tmp = tmp_start;

	int z = 0;
	timer.set(time_limit);
	while (z % 512 != 0 || !timer.elapsed()) {
		++z;
		if (z % 4096 == 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 << ' ' << oracle.getScore() << std::endl;
#endif
		}

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

		if (accepted) {
			oracle.transition();
		}
	}

	std::cerr << oracle.getScore() << std::endl;
	auto state = oracle.get();
	
	return state;
}

#ifndef __PROBLEM_A_H__
#define __PROBLEM_A_H__

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

void problemA();
std::vector<Command> solveASimple(const Graph& graph, int t_max, const std::vector<Order>& orders);
std::vector<Command> solveA(const Graph& graph, int t_max, const std::vector<Order>& orders);


class OracleA {
	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:
	OracleA(int t_max, const Graph& graph, const std::vector<Order>& orders, const Matrix<int> dist_mat);
	Score step();
	void undo();
	void addVertex(int aidx, int pos, int v);
	void eraseVertex(int aidx, int pos);
	void stretchRestTime(int aidx, int delta);
	State get() const;
	Score getScore() const;

private:
	Score calc() const;
};


#endif
#ifdef ONLY_MY_ENVIR
#include "ProblemA.h"
#include "Random.h"
#include "Timer.h"
#include "TSP.h"
#endif

#ifdef ONLY_MY_ENVIR

std::ifstream input_stream("ain.txt");
std::ofstream output_stream("aout.txt");

#define cin input_stream
#define cout output_stream

#else

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

#endif

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

std::vector<Command> solveASimple(const Graph& graph, int t_max, const std::vector<Order>& orders) {
	auto pair = findShortestPaths(graph);
	Matrix<int> dist_mat = pair.first;
	Matrix<Path> path_mat = pair.second;

	/* 巡回ルートを決める */
	auto route = solveTSP(dist_mat);

	int t_required = 0;
	std::vector<int> path_opt;		// 隣接点のみで構成されるパス
	int v_curr = 0;
	for (int v : route) {
		t_required += dist_mat[v_curr][v];
		for (int to : path_mat[v_curr][v]) {
			path_opt.push_back(to);
		}
		v_curr = v;
	}

	/* 行動を決定 */
	int times = t_max / t_required;
	int rest = t_max % t_required;

	std::vector<Command> commands;
	REP(z, 0, rest) {
		commands.push_back(-1);
	}

	REP(z, 0, times) {
		int v_curr = 0;
		for (int v : path_opt) {
			int dist = dist_mat[v_curr][v];
			REP(x, 0, dist) {
				commands.push_back(v);
			}
			v_curr = v;
		}
	}
	return commands;
}

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;

	// 最適化
	OracleA 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;
}

/*-------------------------------*/
/*---------   OracleA   ---------*/
/*-------------------------------*/

OracleA::OracleA(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 OracleA::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 OracleA::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 OracleA::addVertex(int aidx, int pos, int v) {
	Route& route = state[aidx].second;
	route.insert(route.begin() + pos, v);
	used[aidx][v] = true;
}

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

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

OracleA::State OracleA::get() const {
	return state;
}

Score OracleA::getScore() const {
	return score;
}

Score OracleA::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;
}
#ifndef __MAIN_H__
#define __MAIN_H__

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

#endif



#ifdef ONLY_MY_ENVIR
#include "Main.h"
#include "ProblemA.h"
#include "ProblemB.h"
#endif

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

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






Measured memory_bytes: 35584