There are n railway stations in Berland. They are connected to each other by n-1 railway sections. The railway network is connected, i.e. can be represented as an undirected tree.

You have a map of that network, so for each railway section you know which stations it connects.

Each of the n-1 sections has some integer value of the scenery beauty. However, these values are not marked on the map and you don't know them. All these values are from 1 to 10^6 inclusive.

You asked m passengers some questions: the j-th one told you three values:

  * his departure station a_j; 
  * his arrival station b_j; 
  * minimum scenery beauty along the path from a_j to b_j (the train is moving along the shortest path from a_j to b_j). 



You are planning to update the map and set some value f_i on each railway section — the scenery beauty. The passengers' answers should be consistent with these values.

Print any valid set of values f_1, f_2, ..., f_{n-1}, which the passengers' answer is consistent with or report that it doesn't exist.

Input

The first line contains a single integer n (2 ≤ n ≤ 5000) — the number of railway stations in Berland.

The next n-1 lines contain descriptions of the railway sections: the i-th section description is two integers x_i and y_i (1 ≤ x_i, y_i ≤ n, x_i ≠ y_i), where x_i and y_i are the indices of the stations which are connected by the i-th railway section. All the railway sections are bidirected. Each station can be reached from any other station by the railway.

The next line contains a single integer m (1 ≤ m ≤ 5000) — the number of passengers which were asked questions. Then m lines follow, the j-th line contains three integers a_j, b_j and g_j (1 ≤ a_j, b_j ≤ n; a_j ≠ b_j; 1 ≤ g_j ≤ 10^6) — the departure station, the arrival station and the minimum scenery beauty along his path.

Output

If there is no answer then print a single integer -1.

Otherwise, print n-1 integers f_1, f_2, ..., f_{n-1} (1 ≤ f_i ≤ 10^6), where f_i is some valid scenery beauty along the i-th railway section.

If there are multiple answers, you can print any of them.

Examples

Input


4
1 2
3 2
3 4
2
1 2 5
1 3 3


Output


5 3 5


Input


6
1 2
1 6
3 1
1 5
4 1
4
6 1 3
3 4 1
6 5 2
1 2 5


Output


5 3 1 2 1 


Input


6
1 2
1 6
3 1
1 5
4 1
4
6 1 1
3 4 3
6 5 3
1 2 4


Output


-1

Source: codeforces | Difficulty: HARD
Tags: Graph traversal

Constructive algorithms

Sorting

Greedy algorithms

Tree algorithms


Solutions:
import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__
from collections import deque
n = int(input())
G = [[] for i in range(n)]
edges = []
for i in range(n - 1):
	(a, b) = map(int, input().split())
	(a, b) = (a - 1, b - 1)
	G[a].append(b)
	G[b].append(a)
	edges.append((a, b))
dep = [0] * n
par = [0] * n

def bfs(root):
	que = deque()
	que.append((-1, root, 0))
	while que:
		(p, v, d) = que.pop()
		dep[v] = d
		par[v] = p
		for to in G[v]:
			if to != p:
				que.append((v, to, d + 1))
bfs(0)
num = [1] * n

def lca(a, b, g):
	cnt = 0
	if dep[a] < dep[b]:
		(a, b) = (b, a)
	while dep[a] > dep[b]:
		if num[a] <= g:
			num[a] = g
			cnt += 1
		a = par[a]
	while a != b:
		if num[a] <= g:
			num[a] = g
			cnt += 1
		if num[b] <= g:
			num[b] = g
			cnt += 1
		a = par[a]
		b = par[b]
	return cnt > 0
q = int(input())
query = []
for i in range(q):
	(a, b, g) = map(int, input().split())
	(a, b) = (a - 1, b - 1)
	query.append((g, a, b))
query.sort(reverse=True)
for (g, a, b) in query:
	if not lca(a, b, g):
		print(-1)
		exit()
ans = []
for (a, b) in edges:
	if dep[a] < dep[b]:
		(a, b) = (b, a)
	ans.append(num[a])
print(*ans)


import os
import sys
from io import BytesIO, IOBase

def dfsPre(par, graph, tin, tout):
	n = len(graph)
	(visited, finished) = ([False] * n, [False] * n)
	stack = [1]
	t = 0
	while stack:
		start = stack[-1]
		if not visited[start]:
			visited[start] = True
			t += 1
			tin[start] = t
			for child in graph[start]:
				if not visited[child]:
					stack.append(child)
					par[child] = start
		else:
			stack.pop()
			t += 1
			tout[start] = t

def parent(tin, tout, u, v):
	return tin[u] <= tin[v] and tout[v] <= tout[u]

def dfs(par, tin, tout, adj, u, v, c):
	while not parent(tin, tout, u, v):
		adj[u][par[u]] = max(adj[u][par[u]], c)
		u = par[u]

def dfs1(par, tin, tout, adj, u, v):
	ans = 10000000
	while not parent(tin, tout, u, v):
		ans = min(ans, adj[u][par[u]])
		u = par[u]
	return ans

def main():
	n = int(input())
	edges = [[int(x) for x in input().split()] for i in range(n - 1)]
	m = int(input())
	qur = [[int(x) for x in input().split()] for i in range(m)]
	graph = [[] for i in range(n + 1)]
	adj = [[1 for j in range(n + 1)] for i in range(n + 1)]
	par = [-1] * (n + 1)
	tin = [0] * (n + 1)
	tout = [0] * (n + 1)
	for x in edges:
		graph[x[0]].append(x[1])
		graph[x[1]].append(x[0])
	dfsPre(par, graph, tin, tout)
	chk = {}
	for x in qur:
		(u, v, c) = (x[0], x[1], x[2])
		if u > v:
			(u, v) = (v, u)
		fl = False
		try:
			j = chk[u * (n + 1) + v]
			if j != c:
				print(-1)
				fl = True
		except:
			chk[u * (n + 1) + v] = c
			dfs(par, tin, tout, adj, u, v, c)
			dfs(par, tin, tout, adj, v, u, c)
		if fl:
			exit(0)
	for i in range(1, n + 1):
		for j in range(i + 1, n + 1):
			adj[i][j] = adj[j][i] = max(adj[i][j], adj[j][i])
	for (x, y) in chk.items():
		(u, v) = (x // (n + 1), x % (n + 1))
		if min(dfs1(par, tin, tout, adj, v, u), dfs1(par, tin, tout, adj, u, v)) != y:
			print(-1)
			exit(0)
	for x in edges:
		print(adj[x[0]][x[1]], end=' ')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import sys

class RangeMinQuery:

	def __init__(self, data):
		self._data = [list(data)]
		n = len(self._data[0])
		w = 1
		while 2 * w <= n:
			prev = self._data[-1]
			self._data.append([min(prev[j], prev[j + w]) for j in range(n - 2 * w + 1)])
			w *= 2

	def query(self, begin, end):
		assert begin < end
		depth = (end - begin).bit_length() - 1
		return min(self._data[depth][begin], self._data[depth][end - (1 << depth)])

class LCA:

	def __init__(self, graph, root=1):
		self.eulerTour = []
		self.preorder = [None] * len(graph)
		self.postorder = [None] * len(graph)
		self.depth = [None] * len(graph)
		self.parent = [None] * len(graph)
		stack = [root]
		self.depth[root] = 0
		self.parent[root] = None
		while stack:
			node = stack.pop()
			self.eulerTour.append(node)
			if self.preorder[node] is None:
				self.preorder[node] = len(self.eulerTour) - 1
				for nbr in graph[node]:
					if self.preorder[nbr] is None:
						self.depth[nbr] = self.depth[node] + 1
						self.parent[nbr] = node
						stack.append(node)
						stack.append(nbr)
			self.postorder[node] = len(self.eulerTour) - 1
		self.rmq = RangeMinQuery((self.preorder[node] for node in self.eulerTour))
		if False:
			assert self.depth[1] == 0
			assert self.parent[1] == None
			for node in range(1, len(graph)):
				assert self.preorder[node] == self.eulerTour.index(node)
				assert self.postorder[node] == max((i for (i, x) in enumerate(self.eulerTour) if x == node))
			for i in range(len(self.rmq._data)):
				for j in range(i + 1, len(self.rmq._data) + 1):
					assert min(self.rmq._data[0][i:j]) == self.rmq.query(i, j)
			for u in range(1, N + 1):
				for v in range(1, N + 1):
					assert self.lca(u, v) == self.lca(v, u)
					lca = self.lca(u, v)
					assert self.isAncestor(lca, u)
					assert self.isAncestor(lca, v)
					path = self.path(u, v)
					assert len(path) == self.dist(u, v) + 1
					for (x, y) in zip(path, path[1:]):
						assert y in graph[x]
					assert len(set(path)) == len(path)

	def lca(self, u, v):
		a = self.preorder[u]
		b = self.preorder[v]
		if a > b:
			(a, b) = (b, a)
		return self.eulerTour[self.rmq.query(a, b + 1)]

	def dist(self, u, v):
		return self.depth[u] + self.depth[v] - 2 * self.depth[self.lca(u, v)]

	def isAncestor(self, ancestor, v):
		return self.preorder[ancestor] <= self.preorder[v] and self.postorder[v] <= self.postorder[ancestor]

	def path(self, u, v):
		uPath = []
		while not self.isAncestor(u, v):
			uPath.append(u)
			u = self.parent[u]
		lca = u
		assert self.isAncestor(u, v)
		vPath = []
		while v != lca:
			vPath.append(v)
			v = self.parent[v]
		ret = uPath + [lca] + vPath[::-1]
		return ret

def solve(N, edges, passengers):
	graph = [[] for i in range(N + 1)]
	for e in edges:
		graph[e[0]].append(e[1])
		graph[e[1]].append(e[0])
	tree = LCA(graph)
	scores = [[1 for j in range(N + 1)] for i in range(N + 1)]
	for (a, b, score) in passengers:
		path = tree.path(a, b)
		for (u, v) in zip(path, path[1:]):
			scores[u][v] = max(scores[u][v], score)
			scores[v][u] = max(scores[v][u], score)
	for (a, b, score) in passengers:
		ans = float('inf')
		path = tree.path(a, b)
		for (u, v) in zip(path, path[1:]):
			ans = min(ans, scores[u][v])
		if ans != score:
			return -1
	return ' '.join((str(scores[e[0]][e[1]]) for e in edges))
if False:
	N = 5000
	edges = list(zip(range(N - 1), range(1, N)))
	assert len(edges) == N - 1
	passengers = [(0, p, N - p) for p in range(1, N)]
	solve(N, edges, passengers)
	exit(0)
input = sys.stdin.readline
N = int(input())
edges = [[int(x) for x in input().split()] for i in range(N - 1)]
P = int(input())
passengers = [[int(x) for x in input().split()] for i in range(P)]
ans = solve(N, edges, passengers)
print(ans)


import math
import sys
input = sys.stdin.readline
n = int(input())
g = [[] for _ in range(n)]
for i in range(n - 1):
	(x, y) = map(lambda i: int(i) - 1, input().split())
	g[x].append((y, i))
	g[y].append((x, i))
par = [-1] * n
parEdge = [-1] * n
dep = [0] * n
stack = [0]
par[0] = 0
while len(stack) > 0:
	cur = stack.pop()
	for (node, edge) in g[cur]:
		if par[node] == -1:
			dep[node] = 1 + dep[cur]
			(par[node], parEdge[node]) = (cur, edge)
			stack.append(node)
paths = []
m = int(input())
for i in range(m):
	(a, b, f) = map(int, input().split())
	paths.append((f, a - 1, b - 1))
paths.sort(reverse=True)
value = [-1] * (n - 1)
for (f, a, b) in paths:
	if dep[a] > dep[b]:
		(a, b) = (b, a)
	while dep[b] != dep[a]:
		if value[parEdge[b]] == -1:
			value[parEdge[b]] = f
		b = par[b]
	while a != b:
		if value[parEdge[a]] == -1:
			value[parEdge[a]] = f
		if value[parEdge[b]] == -1:
			value[parEdge[b]] = f
		(a, b) = (par[a], par[b])
for i in range(n - 1):
	if value[i] == -1:
		value[i] = 1
for (f, a, b) in paths:
	if dep[a] > dep[b]:
		(a, b) = (b, a)
	ans = 100000000
	while dep[b] != dep[a]:
		ans = min(ans, value[parEdge[b]])
		b = par[b]
	while a != b:
		ans = min(ans, value[parEdge[a]], value[parEdge[b]])
		(a, b) = (par[a], par[b])
	if ans != f:
		print(-1)
		exit(0)
print(' '.join(map(str, value)))


import copy
n = int(input())
g = [[] for i in range(n)]
depth = [0 for i in range(n)]
parent = [-2 for i in range(n)]
parent[0] = -1
beauty = [1 for i in range(n)]
Edges = []

def chk(f, t):
	_min = 1145141919810
	while f != t:
		if depth[f] < depth[t]:
			(f, t) = (t, f)
		_min = min(beauty[f], _min)
		f = parent[f]
	return _min

def dfs():
	callstack = [0]
	while len(callstack):
		c = callstack.pop()
		for i in g[c]:
			if parent[c] == i:
				continue
			parent[i] = c
			depth[i] = depth[c] + 1
			callstack.append(i)

def update(f, t, w):
	while f != t:
		if depth[f] < depth[t]:
			(f, t) = (t, f)
		beauty[f] = max(beauty[f], w)
		f = parent[f]
for i in range(n - 1):
	(fr, to) = (int(i) - 1 for i in input().split(' '))
	g[fr].append(to)
	g[to].append(fr)
	Edges.append((fr, to))
dfs()
g = []
m = int(input())
for i in range(m):
	(fr, to, we) = (int(i) for i in input().split(' '))
	fr -= 1
	to -= 1
	g.append((fr, to, we))
	update(fr, to, we)
for (a, b, c) in g:
	if chk(a, b) != c:
		print(-1)
		exit(0)
for (a, b) in Edges:
	if parent[a] == b:
		print(beauty[a], end=' ')
	else:
		print(beauty[b], end=' ')


import sys
input = sys.stdin.readline
from operator import itemgetter
n = int(input())
EDGE = [sorted(map(int, input().split())) for i in range(n - 1)]
E = [[] for i in range(n + 1)]
D = dict()
for i in range(n - 1):
	(x, y) = EDGE[i]
	D[(x << 13) + y] = i
	D[(y << 13) + x] = i
	E[x].append(y)
	E[y].append(x)
m = int(input())
Q = sorted([tuple(map(int, input().split())) for i in range(m)], key=itemgetter(2), reverse=True)

def dfs(x, y, n, w):
	USE = [-1] * (n + 1)
	NOW = [x]
	while NOW:
		n = NOW.pop()
		if n == y:
			break
		for to in E[n]:
			if USE[to] == -1:
				USE[to] = n
				NOW.append(to)
	change = 0
	while y != x:
		p = D[(y << 13) + USE[y]]
		if ANS[p] <= w:
			change += 1
			ANS[p] = w
		y = USE[y]
	if change == 0:
		print(-1)
		sys.exit()
ANS = [1] * (n - 1)
for (a, b, q) in Q:
	dfs(a, b, n, q)
	flag = 1
print(*ANS)


import sys
sys.setrecursionlimit(5233)
n = int(input())
G = [[] for i in range(n + 1)]
dep = [0 for i in range(n + 1)]
par = [-1 for i in range(n + 1)]
x = [0 for i in range(n + 1)]
y = [0 for i in range(n + 1)]
for i in range(n - 1):
	(x[i], y[i]) = map(int, input().split())
	G[x[i]].append(y[i])
	G[y[i]].append(x[i])
m = int(input())
a = [0 for i in range(m + 1)]
b = [0 for i in range(m + 1)]
g = [[] for i in range(m + 1)]
ans = [0 for i in range(n + 1)]

def bfs():
	q = [1]
	par[1] = -2
	front = 0
	while front < len(q):
		u = q[front]
		front += 1
		for v in G[u]:
			if par[v] == -1:
				par[v] = u
				dep[v] = dep[u] + 1
				q.append(v)

def lca(u, v, w):
	while dep[u] > dep[v]:
		ans[u] = max(ans[u], w)
		u = par[u]
	while dep[v] > dep[u]:
		ans[v] = max(ans[v], w)
		v = par[v]
	while u != v:
		ans[u] = max(ans[u], w)
		ans[v] = max(ans[v], w)
		u = par[u]
		v = par[v]

def check(u, v, w):
	while dep[u] > dep[v]:
		if ans[u] == w:
			return True
		u = par[u]
	while dep[v] > dep[u]:
		if ans[v] == w:
			return True
		v = par[v]
	while u != v:
		if ans[u] == w:
			return True
		if ans[v] == w:
			return True
		u = par[u]
		v = par[v]
	return False
bfs()
for i in range(m):
	(a[i], b[i], g[i]) = map(int, input().split())
	lca(a[i], b[i], g[i])
f = True
for i in range(m):
	if check(a[i], b[i], g[i]) == False:
		f = False
		print(-1)
		break
if f == True:
	for i in range(n - 1):
		if dep[x[i]] > dep[y[i]]:
			print(max(1, ans[x[i]]), end=' ')
		else:
			print(max(1, ans[y[i]]), end=' ')


n = int(input())
e = [[] for _ in range(n + 1)]
for i in range(n - 1):
	(u, v) = map(int, input().split())
	e[u].append((v, i))
	e[v].append((u, i))
p = [(-1, -1) for _ in range(n + 1)]
p[1] = (-2, -1)
h = [0 for _ in range(n + 1)]
q = [1]
front = 0
while front < len(q):
	u = q[front]
	front += 1
	for v in e[u]:
		if p[v[0]][0] == -1:
			p[v[0]] = (u, v[1])
			h[v[0]] = h[u] + 1
			q.append(v[0])
m = int(input())
q = [() for _ in range(m)]
for i in range(m):
	q[i] = tuple(list(map(int, input().split())))
q.sort(key=lambda u: u[2], reverse=True)
f = [0 for _ in range(n)]
for i in range(m):
	(u, v, c) = (q[i][0], q[i][1], q[i][2])
	ok = False
	while h[u] > h[v]:
		if not f[p[u][1]] > c:
			ok = True
			f[p[u][1]] = c
		u = p[u][0]
	while h[v] > h[u]:
		if not f[p[v][1]] > c:
			ok = True
			f[p[v][1]] = c
		v = p[v][0]
	while u != v:
		if not f[p[u][1]] > c:
			ok = True
			f[p[u][1]] = c
		if not f[p[v][1]] > c:
			ok = True
			f[p[v][1]] = c
		u = p[u][0]
		v = p[v][0]
	if not ok:
		print(-1)
		exit()
for i in range(n - 1):
	print(max(f[i], 1), end=' ')


import sys, math, itertools
from collections import Counter, deque, defaultdict
from bisect import bisect_left, bisect_right
from heapq import heappop, heappush, heapify
mod = 10 ** 9 + 7
INF = float('inf')

def inp():
	return int(sys.stdin.readline())

def inpl():
	return list(map(int, sys.stdin.readline().split()))

def err():
	print('-1')
	exit()
n = inp()
g = [[] for _ in range(n)]
d = []
for i in range(n - 1):
	(a, b) = inpl()
	(a, b) = (a - 1, b - 1)
	g[a].append(b)
	g[b].append(a)
	if a > b:
		(a, b) = (b, a)
	d.append([a, b])
bea = [[-1] * n for _ in range(n)]
cnt = [0] * (10 ** 6 + 10)
m = inp()
pas = [inpl() for _ in range(m)]
pas.sort(key=lambda x: x[2])
root = []
for (i, (a, b, c)) in enumerate(pas):
	(a, b) = (a - 1, b - 1)
	pre = [-1] * n
	q = deque([a])
	f = True
	while q and f:
		nv = q.popleft()
		for v in g[nv]:
			if v == pre[nv]:
				continue
			pre[v] = nv
			if v == b:
				ro = [v]
				while v != a:
					(s, t) = (v, pre[v])
					if s > t:
						(s, t) = (t, s)
					bea[s][t] = c
					ro.append(pre[v])
					v = pre[v]
				root.append(ro[::-1])
				f = False
			q.append(v)
for (i, (a, b, c)) in enumerate(pas):
	(a, b) = (a - 1, b - 1)
	bad = True
	for j in range(len(root[i]) - 1):
		(s, t) = (root[i][j], root[i][j + 1])
		if s > t:
			(s, t) = (t, s)
		if bea[s][t] == c:
			bad = False
			break
	if bad:
		err()
res = []
for i in range(n - 1):
	(a, b) = d[i]
	now = bea[a][b]
	if now == -1:
		now = 1
	res.append(now)
print(*res)


from collections import defaultdict

def rootTree(graph, N):
	parent = [None] * N
	parentEdge = [None] * N
	depth = [None] * N
	parent[0] = float('inf')
	parentEdge[0] = float('inf')
	depth[0] = 0
	stack = [0]
	while stack:
		node = stack.pop()
		for (k, edgeId) in graph[node].items():
			if parent[k] is None:
				parent[k] = node
				parentEdge[k] = edgeId
				depth[k] = depth[node] + 1
				stack.append(k)
	return (parent, parentEdge, depth)

def getLCAEdges(parent, parentEdge, depth, source, dest):
	node1 = source
	node2 = dest
	d1 = depth[node1]
	d2 = depth[node2]
	while d1 > d2:
		yield parentEdge[node1]
		node1 = parent[node1]
		d1 -= 1
	while d1 < d2:
		yield parentEdge[node2]
		node2 = parent[node2]
		d2 -= 1
	assert d1 == d2
	while node1 != node2:
		yield parentEdge[node1]
		node1 = parent[node1]
		yield parentEdge[node2]
		node2 = parent[node2]
	assert node1 == node2

def solve(N, edges, passengers):
	graph = defaultdict(lambda : defaultdict(int))
	for (edgeId, e) in enumerate(edges):
		graph[e[0]][e[1]] = edgeId
		graph[e[1]][e[0]] = edgeId
	(parent, parentEdge, depth) = rootTree(graph, N)
	passengers.sort(key=lambda t: t[2], reverse=True)
	scores = [None] * (N - 1)
	for (a, b, score) in passengers:
		numEdges = 0
		for edgeId in getLCAEdges(parent, parentEdge, depth, a, b):
			if scores[edgeId] is None:
				numEdges += 1
				scores[edgeId] = score
			else:
				score2 = scores[edgeId]
				assert score2 >= score
				if score2 == score:
					numEdges += 1
		if numEdges == 0:
			return -1
	return ' '.join((str(score) if score is not None else '1' for score in scores))
if False:
	N = 5000
	edges = list(zip(range(N - 1), range(1, N)))
	passengers = [(0, p, N - p) for p in range(1, N)]
	print(solve(N, edges, passengers))
	exit(0)
N = int(input())
edges = []
for edgeId in range(N - 1):
	(x, y) = map(int, input().split())
	edges.append((x - 1, y - 1))
P = int(input())
passengers = []
for p in range(P):
	(a, b, score) = map(int, input().split())
	passengers.append((a - 1, b - 1, score))
ans = solve(N, edges, passengers)
print(ans)


from collections import deque

def main():
	n = int(input())
	neighbours = [set() for _ in range(n + 1)]
	sections = []
	for i in range(n - 1):
		(x, y) = map(int, input().split())
		sections.append((x, y))
		neighbours[x].add((y, i))
		neighbours[y].add((x, i))
	rootpaths = [[] for _ in range(n + 1)]
	q = deque()
	q.append(1)
	parents = [None] * (n + 1)
	depth = [0] * (n + 1)
	while q:
		i = q.popleft()
		for (s, j) in neighbours[i]:
			if s != 1 and (not parents[s]):
				depth[s] = depth[i] + 1
				parents[s] = (i, j)
				q.append(s)

	def path(x, y):
		if depth[x] < depth[y]:
			(x, y) = (y, x)
		res = []
		while depth[x] > depth[y]:
			(x, s) = parents[x]
			res.append(s)
		while x != y:
			(x, s) = parents[x]
			res.append(s)
			(y, s) = parents[y]
			res.append(s)
		return res
	m = int(input())
	routes = []
	secset = [False] * (n - 1)
	secval = [int(1000000.0)] * (n - 1)
	for _ in range(m):
		(a, b, g) = map(int, input().split())
		routes.append((g, path(a, b)))
	routes.sort(reverse=True)
	for (v, pp) in routes:
		valid = False
		for p in pp:
			if not secset[p] or secval[p] == v:
				valid = True
				secset[p] = True
				secval[p] = v
		if not valid:
			print(-1)
			return
	print(' '.join(map(str, secval)))
main()


import sys
from operator import itemgetter
readline = sys.stdin.readline

def parorder(Edge, p):
	N = len(Edge)
	par = [0] * N
	par[p] = -1
	stack = [p]
	order = []
	visited = set([p])
	ast = stack.append
	apo = order.append
	Ei = [None] * N
	while stack:
		vn = stack.pop()
		apo(vn)
		for (vf, num) in Edge[vn]:
			if vf in visited:
				continue
			Ei[vf] = num
			visited.add(vf)
			par[vf] = vn
			ast(vf)
	return (par, order, Ei)

def lca(u, v):
	if dist[u] > dist[v]:
		(u, v) = (v, u)
	ddif = dist[v] - dist[u]
	for i in range(ddif.bit_length()):
		if 1 << i & ddif:
			v = D[i][v]
	if u != v:
		for cnt in range(dist[u].bit_length() - 1, -1, -1):
			if D[cnt][u] != D[cnt][v]:
				u = D[cnt][u]
				v = D[cnt][v]
		u = P[u]
	return u

def update(ou, ov, x):
	luv = lca(ou, ov)
	(u, v) = (ou, ov)
	distu = dist[u] - dist[luv]
	for i in range(distu.bit_length()):
		if 1 << i & distu:
			data[i][u] = max(data[i][u], x)
			u = D[i][u]
	distv = dist[v] - dist[luv]
	for i in range(distv.bit_length()):
		if 1 << i & distv:
			data[i][v] = max(data[i][v], x)
			v = D[i][v]

def query(u, v):
	res = inf
	if dist[u] > dist[v]:
		(u, v) = (v, u)
	ddif = dist[v] - dist[u]
	for i in range(ddif.bit_length()):
		if 1 << i & ddif:
			res = min(res, Dmin[i][v])
			v = D[i][v]
	if u != v:
		for cnt in range(dist[u].bit_length() - 1, -1, -1):
			if D[cnt][u] != D[cnt][v]:
				res = min(res, Dmin[cnt][u], Dmin[cnt][v])
				u = D[cnt][u]
				v = D[cnt][v]
		res = min(res, path[u], path[v])
	return res
N = int(readline())
Edge = [[] for _ in range(N)]
for num in range(N - 1):
	(a, b) = map(int, readline().split())
	a -= 1
	b -= 1
	Edge[a].append((b, num))
	Edge[b].append((a, num))
root = 0
(P, L, Einv) = parorder(Edge, root)
P[root] = None
D = [P[:]]
dep = N.bit_length()
for _ in range(dep):
	ret = [None] * N
	for i in range(N):
		k = D[-1][i]
		if k is not None:
			ret[i] = D[-1][k]
	D.append(ret)
dist = [0] * N
for l in L[1:]:
	dist[l] = 1 + dist[P[l]]
mini = 0
data = [[mini] * N for _ in range(dep)]
Q = int(readline())
qu = []
for _ in range(Q):
	(a, b, c) = map(int, readline().split())
	update(a - 1, b - 1, c)
	qu.append((a - 1, b - 1, c))
path = [1] * N
for l in L[::-1]:
	ret = [mini] * dep
	ret[dep - 1] = data[dep - 1][l]
	for idx in range(dep - 2, -1, -1):
		ret[idx] = max(ret[idx + 1], data[idx][l])
	path[l] = ret[0]
	for i in range(dep - 1):
		if D[i][l] is None:
			break
		data[i][D[i][l]] = max(data[i][D[i][l]], ret[i + 1])
inf = 10 ** 6
for i in range(N):
	if path[i] == mini:
		path[i] = inf
Dmin = [path[:]]
for d in range(dep):
	res = [inf] * N
	for u in range(N):
		if D[d][u] is not None:
			res[u] = min(Dmin[-1][u], Dmin[-1][D[d][u]])
	Dmin.append(res)
for (a, b, c) in qu:
	if c != query(a, b):
		print(-1)
		break
else:
	ans = [inf] * (N - 1)
	for i in range(N):
		if i != root:
			ans[Einv[i]] = path[i]
	print(*ans)


from collections import deque
from operator import itemgetter
import sys
input = sys.stdin.readline

def dfs(tree, root):
	par = {root: -1}
	st1 = deque([root])
	while st1:
		v = st1.pop()
		for nxt_v in tree[v]:
			if nxt_v in par:
				continue
			else:
				par[nxt_v] = v
				st1.append(nxt_v)
	return par

class LowestCommonAncestor:

	def __init__(self, tree, root):
		self.n = len(tree)
		self.depth = [0] * self.n
		self.log_size = self.n.bit_length()
		self.parent = [[-1] * self.n for i in range(self.log_size)]
		q = deque([(root, -1, 0)])
		while q:
			(v, par, dist) = q.pop()
			self.parent[0][v] = par
			self.depth[v] = dist
			for child_v in tree[v]:
				if child_v != par:
					self.depth[child_v] = dist + 1
					q.append((child_v, v, dist + 1))
		for k in range(1, self.log_size):
			for v in range(self.n):
				self.parent[k][v] = self.parent[k - 1][self.parent[k - 1][v]]

	def lca(self, u, v):
		if self.depth[u] > self.depth[v]:
			(u, v) = (v, u)
		for k in range(self.log_size):
			if self.depth[v] - self.depth[u] >> k & 1:
				v = self.parent[k][v]
		if u == v:
			return u
		for k in reversed(range(self.log_size)):
			if self.parent[k][u] != self.parent[k][v]:
				u = self.parent[k][u]
				v = self.parent[k][v]
		return self.parent[0][u]
n = int(input())
info = [list(map(int, input().split())) for i in range(n - 1)]
m = int(input())
query = [list(map(int, input().split())) for i in range(m)]
tree = [[] for i in range(n)]
edge = {}
for i in range(n - 1):
	(a, b) = info[i]
	a -= 1
	b -= 1
	if a > b:
		(a, b) = (b, a)
	tree[a].append(b)
	tree[b].append(a)
	edge[a * 10000 + b] = i
root = 0
lca = LowestCommonAncestor(tree, root)
par = dfs(tree, root)
ans = [0] * (n - 1)
query = sorted(query, key=itemgetter(2))
for (a, b, g) in query:
	a -= 1
	b -= 1
	ab = lca.lca(a, b)
	set_ = set()
	while True:
		if a == ab:
			break
		ind = edge[min(a, par[a]) * 10000 + max(a, par[a])]
		ans[ind] = g
		a = par[a]
	while True:
		if b == ab:
			break
		ind = edge[min(b, par[b]) * 10000 + max(b, par[b])]
		ans[ind] = g
		b = par[b]
	for i in set_:
		ans[i] = g
for (a, b, g) in query:
	a -= 1
	b -= 1
	ab = lca.lca(a, b)
	res = 10 ** 10
	while True:
		if a == ab:
			break
		ind = edge[min(a, par[a]) * 10000 + max(a, par[a])]
		res = min(res, ans[ind])
		a = par[a]
	while True:
		if b == ab:
			break
		ind = edge[min(b, par[b]) * 10000 + max(b, par[b])]
		res = min(res, ans[ind])
		b = par[b]
	if res != g:
		print(-1)
		exit()
for i in range(n - 1):
	if ans[i] == 0:
		ans[i] = 10 ** 6
print(*ans)