#![allow(unused_imports)]
#![allow(non_snake_case, unused)]

use std::cmp::*;
use std::collections::*;
use std::ops::*;
use std::fmt;

macro_rules! eprint {
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = write!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! eprintln {
	() => { eprintln!(""); };
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = writeln!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! dbg {
	($v:expr) => {{
		let val = $v;
		eprintln!("[{}:{}] {} = {:?}", file!(), line!(), stringify!($v), val);
		val
	}}
}

macro_rules! mat {
	($($e:expr),*) => { Vec::from(vec![$($e),*]) };
	($($e:expr,)*) => { Vec::from(vec![$($e),*]) };
	($e:expr; $d:expr) => { Vec::from(vec![$e; $d]) };
	($e:expr; $d:expr $(; $ds:expr)+) => { Vec::from(vec![mat![$e $(; $ds)*]; $d]) };
}

macro_rules! ok {
	($a:ident$([$i:expr])*.$f:ident()$(@$t:ident)*) => {
		$a$([$i])*.$f($($t),*)
	};
	($a:ident$([$i:expr])*.$f:ident($e:expr$(,$es:expr)*)$(@$t:ident)*) => { {
		let t = $e;
		ok!($a$([$i])*.$f($($es),*)$(@$t)*@t)
	} };
}

pub fn readln() -> String {
	let mut line = String::new();
	::std::io::stdin().read_line(&mut line).unwrap_or_else(|e| panic!("{}", e));
	line
}

macro_rules! read {
	($($t:tt),*; $n:expr) => {{
		let stdin = ::std::io::stdin();
		let ret = ::std::io::BufRead::lines(stdin.lock()).take($n).map(|line| {
			let line = line.unwrap();
			let mut it = line.split_whitespace();
			_read!(it; $($t),*)
		}).collect::<Vec<_>>();
		ret
	}};
	($($t:tt),*) => {{
		let line = readln();
		let mut it = line.split_whitespace();
		_read!(it; $($t),*)
	}};
}

macro_rules! _read {
	($it:ident; [char]) => {
		_read!($it; String).chars().collect::<Vec<_>>()
	};
	($it:ident; [u8]) => {
		Vec::from(_read!($it; String).into_bytes())
	};
	($it:ident; usize1) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1
	};
	($it:ident; [usize1]) => {
		$it.map(|s| s.parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1).collect::<Vec<_>>()
	};
	($it:ident; [$t:ty]) => {
		$it.map(|s| s.parse::<$t>().unwrap_or_else(|e| panic!("{}", e))).collect::<Vec<_>>()
	};
	($it:ident; $t:ty) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<$t>().unwrap_or_else(|e| panic!("{}", e))
	};
	($it:ident; $($t:tt),+) => {
		($(_read!($it; $t)),*)
	};
}

pub fn main() {
	let _ = ::std::thread::Builder::new().name("run".to_string()).stack_size(32 * 1024 * 1024).spawn(run).unwrap().join();
}

const TIME_LIMIT: f64 = 29.0;
const MOD: u32 = 1_000_000_007;

fn get_time() -> f64 {
	static mut STIME: f64 = -1.0;
	let t = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap();
	let ms = t.as_secs() as f64 + t.subsec_nanos() as f64 * 1e-9;
	unsafe {
		if STIME < 0.0 {
			STIME = ms;
		}
		ms - STIME
	}
}

pub struct XorShift {
	pub x: [u32; 4]
}

impl XorShift {
	pub fn new(mut seed: u32) -> XorShift {
		let mut x = [0; 4];
		for i in 0..4 {
			seed = 1812433253u32.wrapping_mul(seed ^ (seed >> 30)).wrapping_add(i as u32);
			x[i] = seed;
		}
		XorShift { x: x }
	}
	pub fn next32(&mut self) -> usize {
		let t = self.x[0] ^ (self.x[0] << 11);
		for i in 0..3 { self.x[i] = self.x[i + 1] }
		self.x[3] = self.x[3] ^ (self.x[3] >> 19) ^ t ^ (t >> 8);
		self.x[3] as usize
	}
	/// [0, n)
	pub fn next(&mut self, n: usize) -> usize {
		loop {
			let t = self.next32();
			let r = t % n;
			if (t - r).checked_add(n).is_some() {
				return r;
			}
		}
	}
}

struct Input {
	V: usize,
	E: usize,
	T: usize,
	edge: Vec<Vec<(usize,usize)>>,
	order: Vec<(usize,usize)>,
	closest: Vec<Vec<usize>>,
	dist: Vec<Vec<i64>>,
	prev: Vec<Vec<usize>>,
}

impl Input {
	fn new(V: usize, E: usize, T: usize, edge: Vec<Vec<(usize,usize)>>, order: Vec<(usize,usize)>) -> Self {
		Input {
			V: V,
			E: E,
			T: T,
			edge: edge,
			order: order,
			closest: vec![vec![1000000000;V];V],
			dist: vec![vec![]; V],
			prev: vec![vec![]; V],
		}
	}

	fn calc_closest(&mut self) {
		let mut g = vec![vec![1000000000;self.V];self.V];
		for i in 0..self.V{
			g[i][i] = 0;
		}
		for i in 0..self.V {
			for &e in &self.edge[i] {
				let s = i;
				let t = e.0;
				let d = e.1;
				g[s][t] = d;
				g[t][s] = d;
			}
		}
		for k in 0..self.V {
			for i in 0..self.V {
				for j in 0..self.V {
					g[i][j] = std::cmp::min(g[i][j], g[i][k] + g[k][j]);
				}
			}
		}
		self.closest = g;
	}

	fn dij(&mut self) {
		for i in 0..self.V{
			let (dist, prev) = dijkstra(i, &self.edge);
			self.dist[i] = dist;
			self.prev[i] = prev;
		}
	}

	fn print_closest(&self) {
		for i in 0..self.V {
			for j in 0..self.V {
				eprint!("{} ", self.closest[i][j]);
			}
			eprintln!();
		}
	}
}

fn find_closest(cur: usize, list: &[usize], input: &Input) -> (usize, usize){
	let mut ret = 1000000000;
	let mut idx = input.V;
	for &i in list{
		let dist = input.closest[cur][i];
		if dist < ret {
			ret = dist;
			idx = i;
		}
	}
	(idx, ret)
}

fn calc_TSP(v: &HashSet<usize>, input: &Input) -> (usize, Vec<usize>) {
	let mut cur = 0;
    let mut list = vec![];
	let mut route = vec![];
    for &i in v.iter() {
        list.push(i);
    }
    let mut dist = 0;
    for i in 1..input.V {
		if list.len()==0 {break;}
        let (idx, ret) = find_closest(cur, &list, &input);
		let mut tmp = idx;
		let mut seen = vec![];
		seen.push(idx);
		loop {
			let target = input.prev[cur][tmp];
			seen.push(target);
			if target==cur {break;}
			tmp = target;
		}
        dist += ret;
        cur = idx;
		route.push(cur);
        let mut nlist = vec![];
        for &j in &list {
			let mut flag = true;
			for &k in &seen{
				if k==j {flag = false;}
			}
            if flag {nlist.push(j);}
        }
        list = nlist;
    }
	dist += find_closest(cur, &[0], &input).1;
	route.push(0);
    // println!("{}", dist);
	(dist, route)
}

fn dijkstra(start: usize, edge: &Vec<Vec<(usize,usize)>>) -> (Vec<i64>, Vec<usize>){
    let n = edge.len() as usize;
    let mut dist = vec![1000000000 as i64;n]; //初期値は最大距離
    dist[start] = 0;
	let mut prev = vec![n;n];
    let mut heap = BinaryHeap::new();
    heap.push((0, start));
    while let Some((pop_cost, v)) = heap.pop() {
        let cur_cost = -pop_cost;
        if dist[v] < cur_cost {continue;} //これがないと遅い
        for &(next, cost) in edge[v].iter(){
            let next_cost = cur_cost + cost as i64;
			if dist[next] > next_cost {
				dist[next] = next_cost;
				prev[next] = v;
				heap.push((-next_cost, next));
			}
        }
    }
    (dist, prev)
}

fn print_path(s: usize, t: usize, input: &Input, count: &mut usize){
	if *count >= input.T {return;}
	let dist = input.dist[s].clone();
	let prev = input.prev[s].clone();
	let mut list = VecDeque::new();
	let mut cur = t;
	list.push_front(cur);
	loop {
		let target = prev[cur];
		list.push_front(target);
		if target==s {break;}
		cur = target;
	}
	cur = s;
	for i in 1..list.len() {
		let target = list[i];
		let dist = input.closest[cur][target];
		for j in 0..dist {
			println!("{}", target+1);
			*count += 1;
			if *count >= input.T {return;}
		}
		cur = target;
	}
}

fn print_route(route: &[usize], input: &Input, count: usize) {
	let mut cur = 0;
	let mut c = count;
	for &i in route {
		let target = i;
		print_path(cur, target, &input, &mut c);
		cur = target;
	}
}

fn print_stay() {
	println!("{}", -1);
}

// 2-optで、経路長を短くする
fn improve_TSP(route: Vec<usize>, input: &Input, cur_step: usize) -> Vec<usize> {
	let mut nroute = route.clone();
	let mut rng = XorShift::new(583290);
	let mut log = vec![0.0;131072];
	let mut count = 0;
	let mut swap = 0;
	let mut rem = 0.0;
	let K = 0.1;
	for i in 0..log.len() {
		log[i] = ((i as f64 + 0.5)/log.len() as f64).log2();
	}
	let start_time = get_time();

	let mut tl = TIME_LIMIT * cur_step as f64 / input.T as f64 - start_time;
	if tl==0.0 {tl=TIME_LIMIT/20.0;}
	loop {
		if (count & 127) == 0 {
			let t = get_time()-start_time;
			if t >= tl {break;}
			rem = (tl as f64 - t as f64) * K / tl as f64;
		}
		count += 1;
		let r1 = rng.next(nroute.len()-1);
		let r2 = rng.next(nroute.len()-1);
		if r1>=r2 {continue;}
		let s1 = nroute[r1];
		let s2 = nroute[r1+1];
		let t1 = nroute[r2];
		let t2 = nroute[r2+1];
		// println!("{} {} {} {}", s1, s2, t1, t2);
		if s1==t1 || s1==t2 || s2==t1 || s2==t2 {continue;}
		let prev_cost = input.closest[s1][s2] + input.closest[t1][t2];
		let after_cost = input.closest[s1][t1] + input.closest[s2][t2];
		let gain = (prev_cost as f64 - after_cost as f64)/ prev_cost as f64;
		if gain < log[rng.next(log.len())] * rem {
			continue;
		}
		swap+=1;
		// eprintln!("{} {}", prev_cost, after_cost);
		let mut troute = vec![];
		for i in 0..r1+1 {
			troute.push(nroute[i]);
		}
		for i in (r1+1..r2+1).rev(){
			troute.push(nroute[i]);
		}
		for i in r2+1..nroute.len() {
			troute.push(nroute[i]);
		}
		// eprintln!("prev_dist {} after_dist {}", route_dist(&nroute, &input), route_dist(&troute, &input));
		nroute = troute.clone();
	}
	// eprintln!("swap {}", swap);
	nroute
}

fn route_dist(route: &[usize], input: &Input) -> usize {
	let mut cur = 0;
	let mut res = 0;
	for i in 0..route.len() {
		res += input.closest[cur][route[i]];
		cur = route[i];
	}
	res
}

// TODO: いい感じに分割
fn split_list(input: &Input, group_num: usize) -> (Vec<usize>, f64){
	let mut ret = vec![0; input.V];
	let mut seen = vec![false; input.V];
	for idx in 0..group_num-1 {
		let mut farest = 0;
		let mut ma = 0;
		for i in 1..input.V {
			if seen[i] {continue;}
			if input.closest[0][i]>ma{
				ma = input.closest[0][i];
				farest = i;
			}
		}
		let mut dist_list = vec![];
		for i in 1..input.V{
			if seen[i] {continue;}
			dist_list.push((input.closest[farest][i], i));
		}
		dist_list.sort();
		for i in 0..(input.V/group_num-1) {
			ret[dist_list[i].1] = idx+1;
			seen[dist_list[i].1] = true;
		}
	}
	let mut dist_sum = 0;
	for i in 0..group_num {
		let mut set = HashSet::new();
		for j in 1..input.V {
			if ret[j]==i {
				set.insert(j);
			}
		}
		let val = calc_optimal_route_dist(&set, &input);
		dist_sum += val;
		eprintln!("group_num {} group_dist {}", group_num, calc_optimal_route_dist(&set, &input));
	}
	(ret, dist_sum as f64 / group_num as f64)
}

fn calc_optimal_route_dist(set: &HashSet<usize>, input: &Input) -> usize{
	let (mut tmp_dist, tmp_route) = calc_TSP(&set, &input);
	let mut tmp_nroute = improve_TSP(tmp_route, &input, 0);
	tmp_dist = route_dist(&tmp_nroute, &input);
	tmp_dist
}

fn solve(input: &Input){
	let ITEM_STEP = 200;
	let mut next_time = ITEM_STEP;
	let mut sum = 0;
	let mut wait_time = next_time;
	let mut group_num = 1;
	let mut group = vec![];
	loop{
		let (tmp_group, mean_dist) = split_list(&input, group_num);
		if mean_dist <= 500.0 {
			group = tmp_group;
			break;
		}
		group_num += 1;
	}
	let mut set = vec![HashSet::new(); group_num];
	let mut idx = 0;
	let mut i = 0;
	let mut diff = input.T;
	let mut turn = 0;
	loop {
		if i>=input.T {break;}
		if i!=next_time{
			if i<=wait_time{
				print_stay();
			}
			let order = input.order[i];
			if order.1 != input.V {
				set[group[order.1]].insert(order.1);
			}
			i += 1;
		}
		else{
			if set[turn].len()<=2 { // 注文がほぼないときは処理をしない
				next_time = i + ITEM_STEP;
				wait_time = i + ITEM_STEP;
				continue;
			}
			let (mut tmp_dist, tmp_route) = calc_TSP(&set[turn], &input);
			let mut tmp_nroute = improve_TSP(tmp_route, &input, i);
			tmp_dist = route_dist(&tmp_nroute, &input);
			// eprintln!("turn {} tmp_dist {}", turn, i);
			next_time = i + tmp_dist;
			print_route(&tmp_nroute, &input, i);
			i += 1;
			set[turn] = HashSet::new();
			turn = (turn+1)%group_num;
			idx += 1;
		}
	}
	let order_num = input.order.iter().filter(|x| x.1!=input.V).collect::<Vec<&(usize,usize)>>().len();
	eprintln!("V {} E {}", input.V, input.E);
	eprintln!("idx {} order {}", idx, order_num);
}

fn read_inputs() -> Input {
	let (V,E) = read!(usize,usize);
	let uvd = read!([usize];E);
	let T = read!(usize);
	let mut order = vec![(V,V);T];
	for i in 0..T {
		let N = read!(usize);
		if N==0 {continue;}
		let info = read!(usize,usize);
		order[i] = (info.0-1, info.1-1);
	}
	let mut edge = vec![vec![];V];
	for i in 0..E {
		let s = uvd[i][0]-1;
		let t = uvd[i][1]-1;
		let d = uvd[i][2];
		edge[s].push((t,d));
		edge[t].push((s,d));
	}
	let input = Input::new(V,E,T,edge,order);
	input
}

fn run() {
	let mut input = read_inputs();
	input.calc_closest();
	input.dij();
	// input.print_closest();
    solve(&input);
}

Measured memory_bytes: 20628