Ashish has a tree consisting of $n$ nodes numbered $1$ to $n$ rooted at node $1$. The $i$-th node in the tree has a cost $a_i$, and binary digit $b_i$ is written in it. He wants to have binary digit $c_i$ written in the $i$-th node in the end.

To achieve this, he can perform the following operation any number of times:   Select any $k$ nodes from the subtree of any node $u$, and shuffle the digits in these nodes as he wishes, incurring a cost of $k \cdot a_u$. Here, he can choose $k$ ranging from $1$ to the size of the subtree of $u$. 

He wants to perform the operations in such a way that every node finally has the digit corresponding to its target.

Help him find the minimum total cost he needs to spend so that after all the operations, every node $u$ has digit $c_u$ written in it, or determine that it is impossible.


-----Input-----

First line contains a single integer $n$ $(1 \le n \le 2 \cdot 10^5)$ denoting the number of nodes in the tree.

$i$-th line of the next $n$ lines contains 3 space-separated integers $a_i$, $b_i$, $c_i$ $(1 \leq a_i \leq 10^9, 0 \leq b_i, c_i \leq 1)$  — the cost of the $i$-th node, its initial digit and its goal digit.

Each of the next $n - 1$ lines contain two integers $u$, $v$ $(1 \leq u, v \leq n, \text{ } u \ne v)$, meaning that there is an edge between nodes $u$ and $v$ in the tree.


-----Output-----

Print the minimum total cost to make every node reach its target digit, and $-1$ if it is impossible.


-----Examples-----
Input
5
1 0 1
20 1 0
300 0 1
4000 0 0
50000 1 0
1 2
2 3
2 4
1 5

Output
4
Input
5
10000 0 1
2000 1 0
300 0 1
40 0 0
1 1 0
1 2
2 3
2 4
1 5

Output
24000
Input
2
109 0 1
205 0 1
1 2

Output
-1


-----Note-----

The tree corresponding to samples $1$ and $2$ are: [Image]

In sample $1$, we can choose node $1$ and $k = 4$ for a cost of $4 \cdot 1$ = $4$ and select nodes ${1, 2, 3, 5}$, shuffle their digits and get the desired digits in every node.

In sample $2$, we can choose node $1$ and $k = 2$ for a cost of $10000 \cdot 2$, select nodes ${1, 5}$ and exchange their digits, and similarly, choose node $2$ and $k = 2$ for a cost of $2000 \cdot 2$, select nodes ${2, 3}$ and exchange their digits to get the desired digits in every node.

In sample $3$, it is impossible to get the desired digits, because there is no node with digit $1$ initially.

Source: codeforces | Difficulty: HARD
Tags: Tree algorithms

Dynamic programming

Graph traversal

Greedy algorithms


Solutions:
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
import sys
from collections import deque

def main():
	n = int(input())
	(Cost, Fr, To) = ([], [], [])
	for _ in range(n):
		(cost, fr, to) = map(int, input().split())
		Cost.append(cost)
		Fr.append(fr)
		To.append(to)
	if sum(Fr) != sum(To):
		return -1
	if n == 1:
		return 0
	Edges = [[] for _ in range(n)]
	for _ in range(n - 1):
		(u, v) = map(lambda x: int(x) - 1, input().split())
		Edges[u].append(v)
		Edges[v].append(u)
	Chi = [[] for _ in range(n)]
	Par = [-1] * n
	Depth = [0] * n
	q = deque()
	q.append(0)
	while q:
		fr = q.popleft()
		for to in Edges[fr]:
			if to == Par[fr]:
				continue
			Chi[fr].append(to)
			Par[to] = fr
			Cost[to] = min(Cost[to], Cost[fr])
			Depth[to] = Depth[fr] + 1
			q.append(to)
	d = max(Depth)
	D = [[] for _ in range(d + 1)]
	for i in range(n):
		depth = Depth[i]
		D[depth].append(i)
	(ToOne, ToZero) = ([0] * n, [0] * n)
	ans = 0
	for i in range(d + 1)[::-1]:
		for par in D[i]:
			(a, b, cost) = (Fr[par], To[par], Cost[par])
			if a == 0 and b == 1:
				ToOne[par] += 1
			elif a == 1 and b == 0:
				ToZero[par] += 1
			for chi in Edges[par]:
				if chi == Par[par]:
					continue
				ToOne[par] += ToOne[chi]
				ToZero[par] += ToZero[chi]
			change = min(ToOne[par], ToZero[par])
			ans += change * cost * 2
			ToOne[par] -= change
			ToZero[par] -= change
			v = Par[par]
	return ans
print(main())


import sys
input = sys.stdin.readline
from collections import deque
n = int(input())
cost = []
p = [-1] * n
y = []
for i in range(n):
	(a, b, c) = map(int, input().split())
	cost.append(a)
	y.append(c - b)
if sum(y):
	print(-1)
	exit()
e = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	e[a].append(b)
	e[b].append(a)
topo = []
q = deque([(0, -1)])
while q:
	(now, bef) = q.popleft()
	topo.append(now)
	for nex in e[now]:
		if nex == p[now]:
			continue
		cost[nex] = min(cost[nex], cost[now])
		p[nex] = now
		q.append((nex, now))
ans = 0
for i in topo[::-1]:
	if y[i] * y[p[i]] < 0:
		ans += cost[p[i]] * min(abs(y[i]), abs(y[p[i]]))
	y[p[i]] += y[i]
print(ans * 2)


import os
os_input = os.read(0, int(10000000.0)).split()
os_input_pos = -1
answer_list = []

def read_s():
	global os_input_pos
	os_input_pos += 1
	return os_input[os_input_pos].decode()

def read_i():
	return int(read_s())

def write_s(v):
	answer_list.append(v)

def write_i(v):
	write_s(str(v))

def print_ans():
	os.write(1, '\n'.join(answer_list).encode())
	os.write(1, '\n'.encode())
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func
n = read_i()
cost = [0 for i in range(n + 1)]
val = [0 for i in range(n + 1)]
for i in range(1, n + 1):
	cost[i] = read_i()
	a = read_i()
	b = read_i()
	val[i] = 0 if a == b else 1 if a else -1
adj = [[] for i in range(n + 1)]
for i in range(1, n):
	a = read_i()
	b = read_i()
	adj[a].append(b)
	adj[b].append(a)

@iterative
def solve(u, p, best):
	best = min(best, cost[u])
	a = val[u] == 1
	b = val[u] == -1
	res = 0
	for v in adj[u]:
		if v != p:
			(t, c, cur) = (yield solve(v, u, best))
			res += cur
			if t == 1:
				a += c
			else:
				b += c
	rem = min(a, b)
	res += 2 * rem * best
	yield (1 if a > b else -1, max(a, b) - rem, res)
result = solve(1, 0, 1061109567)
write_i(result[-1] if result[-2] == 0 else -1)
print_ans()


import io
import os
import sys
from collections import Counter, defaultdict, deque
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def solve(N, ABC, edges):
	g = [[] for i in range(N + 1)]
	for (u, v) in edges:
		g[u].append(v)
		g[v].append(u)
	if sum((b - c for (a, b, c) in ABC)) != 0:
		return -1
	ans = 0

	@bootstrap
	def f(node, parent, bestCost):
		nonlocal ans
		(a, b, c) = ABC[node - 1]
		bestCost = min(bestCost, a)
		needsZero = 0
		needsOne = 0
		if b != c:
			if c == 1:
				needsZero += 1
			else:
				needsOne += 1
		for nbr in g[node]:
			if nbr != parent:
				(zeroes, ones) = (yield f(nbr, node, bestCost))
				needsZero += zeroes
				needsOne += ones
		common = min(needsZero, needsOne)
		ans += 2 * common * bestCost
		yield (needsZero - common, needsOne - common)
	root = 1
	(zeroes, ones) = f(root, None, ABC[0][0])
	assert zeroes == ones == 0
	return ans
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(N,) = [int(x) for x in input().split()]
ABC = [[int(x) for x in input().split()] for i in range(N)]
edges = [[int(x) for x in input().split()] for i in range(N - 1)]
ans = solve(N, ABC, edges)
print(ans)


import sys
input = lambda : sys.stdin.readline().rstrip()
from collections import deque
N = int(input())
(C, Y) = ([], [])
for _ in range(N):
	(a, b, c) = list(map(int, input().split()))
	C.append(a)
	Y.append(c - b)
if sum(Y):
	print(-1)
	return
X = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = list(map(int, input().split()))
	X[x - 1].append(y - 1)
	X[y - 1].append(x - 1)
P = [-1] * N
Q = deque([0])
R = []
while Q:
	i = deque.popleft(Q)
	R.append(i)
	for a in X[i]:
		if a != P[i]:
			P[a] = i
			X[a].remove(i)
			deque.append(Q, a)
for i in R[1:]:
	C[i] = min(C[i], C[P[i]])
ans = 0
for i in R[1:][::-1]:
	if Y[i] * Y[P[i]] < 0:
		ans += C[P[i]] * min(abs(Y[i]), abs(Y[P[i]]))
	Y[P[i]] += Y[i]
print(ans * 2)


import sys
from collections.abc import Generator
input = sys.stdin.readline

def my_recursion(gen):
	stk = [gen]
	res = None
	while True:
		cur = stk[-1]
		obj = None
		if isinstance(cur, Generator):
			obj = next(cur)
		else:
			stk.pop()
			if not stk:
				res = cur
				break
			obj = stk[-1].send(cur)
		if isinstance(obj, Generator):
			stk.append(obj)
		else:
			stk[-1] = obj
	return res

def main():
	n = int(input())
	a = [0] * n
	b = [0] * n
	c = [0] * n
	for i in range(n):
		(a[i], b[i], c[i]) = map(int, input().split())
	g = [[] for _ in range(n)]
	for _ in range(n - 1):
		(x, y) = map(int, input().split())
		g[x - 1].append(y - 1)
		g[y - 1].append(x - 1)
	_01 = [0] * n
	_10 = [0] * n

	def dfs(u, p=-1):
		res = 0
		for v in g[u]:
			if v != p:
				a[v] = min(a[v], a[u])
				res += (yield dfs(v, u))
				_01[u] += _01[v]
				_10[u] += _10[v]
		if b[u] != c[u]:
			if b[u] == 0:
				_01[u] += 1
			else:
				_10[u] += 1
		m = min(_01[u], _10[u])
		res += 2 * m * a[u]
		_01[u] -= m
		_10[u] -= m
		yield res
	stk = [dfs(0)]
	ans = None
	while True:
		cur = stk[-1]
		obj = None
		if isinstance(cur, Generator):
			obj = next(cur)
		else:
			stk.pop()
			if not stk:
				ans = cur
				break
			obj = stk[-1].send(cur)
		if isinstance(obj, Generator):
			stk.append(obj)
		else:
			stk[-1] = obj
	print('-1') if _01[0] > 0 or _10[0] > 0 else print(ans)
main()


from __future__ import division, print_function
import itertools
import sys, threading
import os
from io import BytesIO, IOBase
from types import GeneratorType

def is_it_local():
	script_dir = str(os.getcwd()).split('/')
	username = 'dipta007'
	return username in script_dir

def READ(fileName):
	if is_it_local():
		sys.stdin = open(f'./{fileName}', 'r')
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')
if not is_it_local():
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
	input = lambda : sys.stdin.readline().rstrip('\r\n')

def input1(type=int):
	return type(input())

def input2(type=int):
	[a, b] = list(map(type, input().split()))
	return (a, b)

def input3(type=int):
	[a, b, c] = list(map(type, input().split()))
	return (a, b, c)

def input_array(type=int):
	return list(map(type, input().split()))

def input_string():
	s = input()
	return list(s)
adj = {}
label = []
target = []
cost = []
data = []

def merge(a, b):
	tmp = [a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3], a[4] + b[4], a[5] + b[5]]
	return tmp

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		to = f(*args, **kwargs)
		if stack:
			return to
		else:
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						return to
					to = stack[-1].send(to)
	return wrappedfunc

@bootstrap
def dfs1(u, p):
	global data, label, target, adj, cost
	now = [1, 1 if label[u] == 0 and label[u] != target[u] else 0, 1 if label[u] == 1 and label[u] != target[u] else 0, 1 if label[u] == target[u] else 0, 1 if target[u] == 0 and label[u] != target[u] else 0, 1 if target[u] == 1 and label[u] != target[u] else 0]
	if p != -1:
		cost[u] = min(cost[u], cost[p])
	if u in adj:
		for v in adj[u]:
			if v != p:
				tmp = (yield dfs1(v, u))
				now = merge(now, tmp)
	data[u] = now
	yield now
res = 0

@bootstrap
def call(u, p):
	global data, label, target, adj, cost, res
	(f_0, f_1) = (0, 0)
	if u in adj:
		for v in adj[u]:
			if v != p:
				(n_0, n_1) = (yield call(v, u))
				f_0 += n_0
				f_1 += n_1
	now = data[u]
	can_be_fixed_zero = min(now[4], now[1]) - f_0
	can_be_fixed_one = min(now[5], now[2]) - f_1
	not_fixed = can_be_fixed_zero + can_be_fixed_one
	res += not_fixed * cost[u]
	yield (f_0 + can_be_fixed_zero, f_1 + can_be_fixed_one)

def main():
	global data, label, target, adj, cost
	n = input1()
	data = [0 for _ in range(n + 4)]
	label = [0 for _ in range(n + 4)]
	target = [0 for _ in range(n + 4)]
	cost = [0 for _ in range(n + 4)]
	(z, o, tz, to) = (0, 0, 0, 0)
	for i in range(1, n + 1):
		(cost[i], label[i], target[i]) = input3()
		z += label[i] == 0
		o += label[i] == 1
		tz += target[i] == 0
		to += target[i] == 1
	adj = {}
	for i in range(n - 1):
		(u, v) = input2()
		if u not in adj:
			adj[u] = []
		if v not in adj:
			adj[v] = []
		adj[u].append(v)
		adj[v].append(u)
	if tz != z or o != to:
		print(-1)
		exit()
	dfs1(1, -1)
	global res
	res = 0
	call(1, -1)
	print(res)
	pass
main()


n = int(input())
aa = [None]
mm0 = [None]
mm1 = [None]
for _ in range(n):
	(a, b, c) = map(int, input().split())
	aa.append(a)
	m0 = m1 = 0
	if b != c:
		if b == 0:
			m0 = 1
		else:
			m1 = 1
	mm0.append(m0)
	mm1.append(m1)
g = [[] for _ in range(n + 1)]
for _ in range(n - 1):
	(u, v) = map(int, input().split())
	g[u].append(v)
	g[v].append(u)
q = [1]
par = [-1] * (n + 1)
par[1] = 1
depths = [0] * (n + 1)
root_to_leaves = [1]
while q:
	u = q.pop()
	for v in g[u]:
		if par[v] != -1:
			continue
		par[v] = u
		depths[v] = depths[u] + 1
		aa[v] = min(aa[v], aa[u])
		q.append(v)
		root_to_leaves.append(v)
ans = 0
for u in reversed(root_to_leaves):
	m = min(mm0[u], mm1[u])
	ans += aa[u] * m
	mm0[u] -= m
	mm1[u] -= m
	mm0[par[u]] += mm0[u]
	mm1[par[u]] += mm1[u]
print(ans * 2 if mm0[1] == mm1[1] == 0 else -1)


from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

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

def LS():
	return [list(x) for x in sys.stdin.readline().split()]

def S():
	res = list(sys.stdin.readline())
	if res[-1] == '\n':
		return res[:-1]
	return res

def IR(n):
	return [I() for i in range(n)]

def LIR(n):
	return [LI() for i in range(n)]

def SR(n):
	return [S() for i in range(n)]

def LSR(n):
	return [LS() for i in range(n)]
sys.setrecursionlimit(10000000)
mod = 1000000007

def solve():
	n = I()
	a = []
	b = []
	c = []
	for _ in range(n):
		(x, y, z) = LI()
		a.append(x)
		b.append(y)
		c.append(z)
	v = [[] for i in range(n)]
	for _ in range(n - 1):
		(x, y) = LI()
		x -= 1
		y -= 1
		v[x].append(y)
		v[y].append(x)
	if b.count(1) != c.count(1):
		print(-1)
		return
	q = deque([0])
	q2 = deque()
	d = [1] * n
	d[0] = 0
	ans = 0
	p = [[0] * 2 for i in range(n)]
	while q:
		x = q.popleft()
		ax = a[x]
		if b[x] != c[x]:
			p[x][b[x]] = 1
		for y in v[x]:
			if d[y]:
				d[y] = 0
				if ax < a[y]:
					a[y] = ax
				q.append(y)
				q2.append((x, y))
	while q2:
		(x, y) = q2.pop()
		p[x][0] += p[y][0]
		p[x][1] += p[y][1]
		m = min(p[x])
		ans += m * a[x]
		p[x][0] -= m
		p[x][1] -= m
	print(ans * 2)
	return

def __starting_point():
	solve()
__starting_point()


import sys
input = sys.stdin.readline
n = int(input())
COST = []
A = []
B = []
for i in range(n):
	(c, a, b) = map(int, input().split())
	COST.append(c)
	A.append(a)
	B.append(b)
E = [[] for i in range(n)]
for i in range(n - 1):
	(x, y) = map(int, input().split())
	x -= 1
	y -= 1
	E[x].append(y)
	E[y].append(x)
from collections import deque
Q = deque()
Q.append(0)
TOP_SORT = []
USE = [0] * n
P = [-1] * n
while Q:
	x = Q.pop()
	USE[x] = 1
	TOP_SORT.append(x)
	for to in E[x]:
		if USE[to] == 0:
			if COST[to] > COST[x]:
				COST[to] = COST[x]
			Q.appendleft(to)
			P[to] = x
ANS = 0
PLUS = [0] * (n + 1)
MINUS = [0] * (n + 1)
for x in TOP_SORT[::-1]:
	if A[x] > B[x]:
		PLUS[x] += 1
	if B[x] > A[x]:
		MINUS[x] += 1
	if PLUS[x] > 0 and MINUS[x] > 0:
		MIN = min(PLUS[x], MINUS[x])
		ANS += COST[x] * MIN * 2
		PLUS[x] -= MIN
		MINUS[x] -= MIN
	PLUS[P[x]] += PLUS[x]
	MINUS[P[x]] += MINUS[x]
	PLUS[x] = 0
	MINUS[x] = 0
if max(PLUS) == 0 and max(MINUS) == 0:
	print(ANS)
else:
	print(-1)


import os
os_input = os.read(0, int(10000000.0)).split()
os_input_pos = -1
answer_list = []

def read_s():
	global os_input_pos
	os_input_pos += 1
	return os_input[os_input_pos].decode()

def read_i():
	return int(read_s())

def write_s(v):
	answer_list.append(v)

def write_i(v):
	write_s(str(v))

def print_ans():
	os.write(1, '\n'.join(answer_list).encode())
	os.write(1, '\n'.encode())
n = read_i()
cost = [0 for i in range(n)]
val = [0 for i in range(n)]
for i in range(n):
	cost[i] = read_i()
	a = read_i()
	b = read_i()
	val[i] = 0 if a == b else 1 if a else -1
adj = [[] for i in range(n)]
for i in range(1, n):
	a = read_i() - 1
	b = read_i() - 1
	adj[a].append(b)
	adj[b].append(a)
par = [None for i in range(n)]
order = [0 for i in range(n)]
f = n
b = n - 1
par[0] = -1
while f > b:
	f -= 1
	u = order[f]
	for v in adj[u]:
		if par[v] is None:
			par[v] = u
			b -= 1
			order[b] = v
			cost[v] = min(cost[v], cost[u])
ans = 0
dp = [None for i in range(n)]
for u in order:
	ab = [val[u] == 1, val[u] == -1]
	for v in adj[u]:
		if dp[v] is not None:
			ab[dp[v][0]] += dp[v][1]
	rem = min(ab)
	ans += 2 * rem * cost[u]
	dp[u] = (ab[1] > ab[0], max(ab) - rem)
os.write(1, '{}\n'.format(-1 if dp[0][1] else ans).encode())


import os
import sys
from io import BytesIO, IOBase

def iin():
	return int(input())

def lin():
	return list(map(int, input().split()))
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def DFS(adj, v, a):
	parent = {}
	n = len(adj)
	dp = [a[i][0] for i in range(n)]
	ans = [0]

	@bootstrap
	def DFS_use(adj, s):
		for i in adj[s]:
			if i not in parent:
				parent[i] = s
				dp[i] = min(dp[s], dp[i])
				x = (yield DFS_use(adj, i))
		yield dp[s]

	@bootstrap
	def DFS_use_2(adj, s):
		t1 = [0, 0]
		if a[s][1] == 0 and a[s][2] == 1:
			t1[0] += 1
		if a[s][1] == 1 and a[s][2] == 0:
			t1[1] += 1
		for i in adj[s]:
			if i not in parent:
				parent[i] = s
				x = (yield DFS_use_2(adj, i))
				t1[0] += x[0]
				t1[1] += x[1]
		mn = min(t1)
		ans[0] += mn * dp[s] * 2
		t1[0] -= mn
		t1[1] -= mn
		yield t1
	for s in v:
		if s not in parent:
			parent[s] = None
			DFS_use(adj, s)
	parent = {}
	for s in v:
		if s not in parent:
			parent[s] = None
			sl = DFS_use_2(adj, s)
			if sl != [0, 0]:
				return -1
	return ans[0]

def main():
	T = 1
	while T:
		T -= 1
		n = iin()
		w = [lin() for i in range(n)]
		adj = [[] for i in range(n)]
		for _ in range(n - 1):
			(i, j) = lin()
			i -= 1
			j -= 1
			adj[i].append(j)
			adj[j].append(i)
		ans = DFS(adj, range(n), w)
		print(ans)
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
input = sys.stdin.readline
n = int(input())
cbc = [list(map(int, input().split())) for i in range(n)]
ab = [list(map(int, input().split())) for i in range(n - 1)]
graph = [[] for i in range(n + 1)]
if n == 1:
	if cbc[0][1] != cbc[0][2]:
		print(-1)
	else:
		print(0)
	exit()
deg = [0] * (n + 1)
for (a, b) in ab:
	graph[a].append(b)
	graph[b].append(a)
	deg[a] += 1
	deg[b] += 1
deg[1] += 1
stack = [1]
par = [0] * (n + 1)
par[1] = -1
leaf = []
while stack:
	x = stack.pop()
	if x != 1 and len(graph[x]) == 1:
		leaf.append(x)
	for y in graph[x]:
		if par[y]:
			continue
		par[y] = x
		cbc[y - 1][0] = min(cbc[y - 1][0], cbc[x - 1][0])
		stack.append(y)
dp = [[0, 0] for i in range(n + 1)]
ans = 0
while leaf:
	x = leaf.pop()
	p = par[x]
	if cbc[x - 1][1] != cbc[x - 1][2]:
		if cbc[x - 1][1] == 1:
			dp[x][0] += 1
		else:
			dp[x][1] += 1
	if min(dp[x][0], dp[x][1]):
		if dp[x][0] > dp[x][1]:
			dp[x][0] -= dp[x][1]
			ans += cbc[x - 1][0] * dp[x][1] * 2
			dp[x][1] = 0
		else:
			dp[x][1] -= dp[x][0]
			ans += cbc[x - 1][0] * dp[x][0] * 2
			dp[x][0] = 0
	dp[p][0] += dp[x][0]
	dp[p][1] += dp[x][1]
	deg[p] -= 1
	if deg[p] == 1:
		leaf.append(p)
if dp[1][0] != dp[1][1]:
	print(-1)
else:
	print(ans)


import sys
buff_readline = sys.stdin.readline
readline = sys.stdin.readline
INF = 2 ** 62 - 1

def read_int():
	return int(buff_readline())

def read_int_n():
	return list(map(int, buff_readline().split()))

def read_float():
	return float(buff_readline())

def read_float_n():
	return list(map(float, buff_readline().split()))

def read_str():
	return readline().strip()

def read_str_n():
	return readline().strip().split()

def error_print(*args):
	print(*args, file=sys.stderr)

def mt(f):
	import time

	def wrap(*args, **kwargs):
		s = time.time()
		ret = f(*args, **kwargs)
		e = time.time()
		error_print(e - s, 'sec')
		return ret
	return wrap

def slv(N, ABC, UV):
	from collections import defaultdict, Counter
	g = defaultdict(list)
	for (u, v) in UV:
		g[u - 1].append(v - 1)
		g[v - 1].append(u - 1)
	bc = Counter()
	cc = Counter()
	for (_, b, c) in ABC:
		bc[b] += 1
		cc[c] += 1
	for k in cc:
		if cc[k] != bc[k]:
			return -1
	s = [(0, -1, ABC[0][0])]
	o = []
	while s:
		(u, p, a) = s.pop()
		o.append((u, p, a))
		for v in g[u]:
			if v == p:
				continue
			va = ABC[v][0]
			s.append((v, u, min(a, va)))
	memo = [[0, Counter(), Counter()] for _ in range(N + 1)]
	while o:
		(u, p, a) = o.pop()
		(cost, bc, cc) = memo[u]
		(_, b, c) = ABC[u]
		if b != c:
			bc[b] += 1
			cc[c] += 1
		for k in cc:
			n = min(cc[k], bc[k])
			cost += n * a
			bc[k] -= n
			cc[k] -= n
		memo[p][0] += cost
		memo[p][1] += bc
		memo[p][2] += cc
		memo[u] = None
	return memo[-1][0]

def main():
	N = read_int()
	ABC = [read_int_n() for _ in range(N)]
	UV = [read_int_n() for _ in range(N - 1)]
	print(slv(N, ABC, UV))
main()


import sys
input = sys.stdin.buffer.readline
from collections import deque

def prog():
	n = int(input())
	type1 = 0
	type2 = 0
	nodes = [None]
	for _ in range(n):
		new = []
		(a, b, c) = map(int, input().split())
		new.append(a)
		if b == c:
			new.append(0)
			new.append(0)
		elif b == 0:
			new.append(1)
			new.append(0)
			type1 += 1
		elif b == 1:
			new.append(0)
			new.append(1)
			type2 += 1
		nodes.append(new)
	if type1 != type2:
		print(-1)
		return
	adj_list = [[] for i in range(n + 1)]
	for _ in range(n - 1):
		(a, b) = map(int, input().split())
		adj_list[a].append(b)
		adj_list[b].append(a)
	parent = [0 for i in range(n + 1)]
	s = deque()
	s.append(1)
	total_cost = 0
	prev = 0
	while s:
		curr = s[-1]
		had_neighbor = False
		if adj_list[curr]:
			neighbor = adj_list[curr].pop()
			if neighbor == parent[curr]:
				if adj_list[curr]:
					neighbor = adj_list[curr].pop()
					had_neighbor = True
			else:
				had_neighbor = True
		if had_neighbor:
			nodes[neighbor][0] = min(nodes[neighbor][0], nodes[curr][0])
			parent[neighbor] = curr
			s.append(neighbor)
		else:
			type1 = nodes[curr][1]
			type2 = nodes[curr][2]
			if type1 > type2:
				paired = type2
				total_cost += 2 * paired * nodes[curr][0]
				leftover = type1 - paired
				s.pop()
				if s:
					nodes[s[-1]][1] += leftover
			else:
				paired = type1
				total_cost += 2 * paired * nodes[curr][0]
				leftover = type2 - paired
				s.pop()
				if s:
					nodes[s[-1]][2] += leftover
	print(total_cost)
prog()


mod = 1000000007
eps = 10 ** (-9)

def main():
	import sys
	from collections import deque
	input = sys.stdin.buffer.readline
	N = int(input())
	A = [10 ** 10]
	BC = [0]
	for _ in range(N):
		(a, b, c) = map(int, input().split())
		A.append(a)
		BC.append(b - c)
	adj = [[] for _ in range(N + 1)]
	for _ in range(N - 1):
		(a, b) = map(int, input().split())
		adj[a].append(b)
		adj[b].append(a)
	que = deque()
	que.append(1)
	seen = [-1] * (N + 1)
	seen[1] = 0
	par = [0] * (N + 1)
	child = [[] for _ in range(N + 1)]
	seq = []
	while que:
		v = que.popleft()
		seq.append(v)
		for u in adj[v]:
			if seen[u] == -1:
				seen[u] = seen[v] + 1
				par[u] = v
				child[v].append(u)
				que.append(u)
				A[u] = min(A[u], A[v])
	seq.reverse()
	pos = [0] * (N + 1)
	neg = [0] * (N + 1)
	ans = 0
	for v in seq:
		if BC[v] == 1:
			pos[v] += 1
		elif BC[v] == -1:
			neg[v] += 1
		for u in child[v]:
			pos[v] += pos[u]
			neg[v] += neg[u]
		k = min(pos[v], neg[v])
		ans += A[v] * k * 2
		pos[v] -= k
		neg[v] -= k
	if pos[1] == neg[1] == 0:
		print(ans)
	else:
		print(-1)
main()


from collections import defaultdict
import sys
input = sys.stdin.buffer.readline
n = int(input())
a = [0 for _ in range(n + 1)]
b = [0 for _ in range(n + 1)]
c = [0 for _ in range(n + 1)]
for i in range(n):
	(a[i + 1], b[i + 1], c[i + 1]) = [int(x) for x in input().split()]
edges = [[] for _ in range(n + 1)]
for _ in range(n - 1):
	(u, v) = [int(x) for x in input().split()]
	edges[u].append(v)
	edges[v].append(u)
a[0] = 99999999999999999
parent = [0 for _ in range(n + 1)]
depth = defaultdict(list)
maxdepth = 1
dfs = [[1, 0, 1]]
while dfs:
	(node, par, d) = dfs.pop()
	depth[d].append(node)
	maxdepth = max(maxdepth, d)
	a[node] = min(a[node], a[par])
	parent[node] = par
	children = [x for x in edges[node] if x != par]
	for child in children:
		dfs.append([child, node, d + 1])
wrong0s = [0 for _ in range(n + 1)]
wrong1s = [0 for _ in range(n + 1)]
accumCosts = [0 for _ in range(n + 1)]
for dd in range(maxdepth, 0, -1):
	for node in depth[dd]:
		if b[node] == 0 and c[node] == 1:
			wrong0s[node] += 1
		elif b[node] == 1 and c[node] == 0:
			wrong1s[node] += 1
		change = min(wrong0s[node], wrong1s[node])
		accumCosts[node] += change * 2 * a[node]
		wrong0s[node] -= change
		wrong1s[node] -= change
		par = parent[node]
		accumCosts[par] += accumCosts[node]
		wrong0s[par] += wrong0s[node]
		wrong1s[par] += wrong1s[node]
if wrong0s[1] != 0 or wrong1s[1] != 0:
	print(-1)
else:
	print(accumCosts[1])


import sys
input = sys.stdin.readline
import heapq
import copy
import math
import decimal

class Node:

	def _init_(self, val):
		self.data = val
		self.left = None
		self.right = None

class fen_tree:

	def __init__(self, list):
		self.array = [0] + list
		for idx in range(1, len(self.array)):
			idx2 = idx + (idx & -idx)
			if idx2 < len(self.array):
				self.array[idx2] += self.array[idx]

	def prefix_query(self, idx):
		result = 0
		while idx:
			result += self.array[idx]
			idx -= idx & -idx
		return result

	def prints(self):
		print(self.array)
		return

	def range_query(self, from_idx, to_idx):
		return self.prefix_query(to_idx) - self.prefix_query(from_idx - 1)

	def update(self, idx, add):
		while idx < len(self.array):
			self.array[idx] += add
			idx += idx & -idx

def pre_sum(arr):
	p = [0]
	for i in arr:
		p.append(p[-1] + i)
	p.pop(0)
	return p

def pre_back(arr):
	p = [0]
	for i in arr:
		p.append(p[-1] + i)
	p.pop(0)
	return p

def bin_search(arr, l, r, val):
	if arr[r] <= val:
		return r + 1
	if r - l < 2:
		if arr[l] > val:
			return l
		else:
			return r
	mid = int((l + r) / 2)
	if arr[mid] <= val:
		return bin_search(arr, mid, r, val)
	else:
		return bin_search(arr, l, mid, val)

def search_leftmost(arr, val):

	def helper(arr, l, r, val):
		print(l, r)
		if arr[l] == val:
			return l
		if r - l <= 1:
			if arr[r] == val:
				return r
			else:
				print('not found')
				return
		mid = int((r + l) / 2)
		if arr[mid] >= val:
			return helper(arr, l, mid, val)
		else:
			return helper(arr, mid, r, val)
	return helper(arr, 0, len(arr) - 1, val)

def search_rightmost(arr, val):

	def helper(arr, l, r, val):
		print(l, r)
		if arr[r] == val:
			return r
		if r - l <= 1:
			if arr[l] == val:
				return r
			else:
				print('not found')
				return
		mid = int((r + l) / 2)
		if arr[mid] > val:
			return helper(arr, l, mid, val)
		else:
			return helper(arr, mid, r, val)
	return helper(arr, 0, len(arr) - 1, val)

def preorder_postorder(root, paths, parent, left, level):
	l = 0
	queue = [root]
	while queue != []:
		node = queue[-1]
		flag = 0
		for i in paths[node]:
			if i != parent[node] and level[i] == sys.maxsize:
				parent[i] = node
				level[i] = level[node] + 1
				flag = 1
				queue.append(i)
		if flag == 0:
			left[parent[node]] += 1 + left[node]
			queue.pop()
	return [parent, left, level]

def nCr(n, r, p):
	if r == 0:
		return 1
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def inp():
	return int(input())

def inlt():
	return list(map(int, input().split()))

def insr():
	s = input()
	return list(s[:len(s) - 1])

def insr2():
	s = input()
	return s[:len(s) - 1]

def invr():
	return map(int, input().split())

def pr_list(a):
	print(*a, sep=' ')

def main():
	tests = 1
	mod = 1000000007
	limit = 10 ** 18
	ans = 0
	for test in range(tests):
		n = inp()
		a = [-1]
		b = [-1]
		c = [-1]
		for i in range(n):
			[ai, bi, ci] = inlt()
			a.append(ai)
			b.append(bi)
			c.append(ci)
		paths2 = [[] for i in range(n + 1)]
		parent = [0 for i in range(n + 1)]
		for i in range(n - 1):
			[p, child] = inlt()
			paths2[p].append(child)
			paths2[child].append(p)
		path = [[] for i in range(n + 1)]
		root = 1
		queue = [root]
		parent[1] = -1
		queue = [root]
		done = [-1 for i in range(n + 1)]
		w_1 = [0 for i in range(n + 1)]
		w_0 = [0 for i in range(n + 1)]
		done[1] = 1
		while queue != []:
			curr = queue[-1]
			done[curr] = 1
			flag = 0
			for i in paths2[curr]:
				if parent[i] == 0:
					parent[i] = curr
				if done[i] == -1:
					queue.append(i)
					a[i] = min(a[i], a[curr])
					done[i] = 1
					flag = 1
			if flag == 0:
				curr = queue.pop()
				if curr == 1:
					parent[1] = 0
				if c[curr] == b[curr]:
					one = w_1[curr]
					zero = w_0[curr]
				elif b[curr] == 0:
					zero = w_0[curr] + 1
					one = w_1[curr]
				else:
					zero = w_0[curr]
					one = w_1[curr] + 1
				left = abs(one - zero)
				if one > zero:
					w_1[parent[curr]] = w_1[parent[curr]] + left
				else:
					w_0[parent[curr]] = w_0[parent[curr]] + left
				ans = ans + 2 * min(one, zero) * a[curr]
		if w_1[0] != w_0[0]:
			print(-1)
		else:
			print(ans)
main()


from types import GeneratorType
import sys
input = sys.stdin.readline
from collections import defaultdict as dd

def dfs(cur, prev, d, typ, val, ans):
	st = [(cur, prev)]
	bst = []
	while st:
		(cur, prev) = st.pop()
		bst.append((cur, prev))
		if prev != 0:
			val[cur] = min(val[cur], val[prev])
		for i in d[cur]:
			if i != prev:
				st.append((i, cur))
	while bst:
		(cur, prev) = bst.pop()
		for i in d[cur]:
			if i != prev:
				typ[cur][0] += typ[i][0]
				typ[cur][1] += typ[i][1]
		mi = min(typ[cur][0], typ[cur][1])
		ans[0] += val[cur] * mi * 2
		typ[cur][0] -= mi
		typ[cur][1] -= mi
n = int(input())
typ = [[0] * 2 for i in range(n + 1)]
val = [0] * (n + 1)
co1 = 0
co2 = 0
for i in range(1, n + 1):
	(va, a, b) = map(int, input().split())
	if a < b:
		typ[i][0] = 1
		co1 += 1
	elif a > b:
		typ[i][1] = 1
		co2 += 1
	val[i] = va
d = dd(list)
for i in range(n - 1):
	(u, v) = map(int, input().split())
	d[u].append(v)
	d[v].append(u)
ans = [0]
dfs(1, 0, d, typ, val, ans)
if co1 != co2:
	print(-1)
else:
	print(ans[0])


import os
import sys
from io import BytesIO, IOBase
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')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

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

def N():
	return int(input())

def print_list(l):
	print(' '.join(map(str, l)))
data = [list(map(int, line.rstrip().split())) for line in sys.stdin.readlines()]
n = data[0][0]
dic = [[] for _ in range(n + 1)]
dic[1].append(0)
for (u, v) in data[n + 1:]:
	dic[u].append(v)
	dic[v].append(u)
cost = [0] * (n + 1)
cost[1] = 1000000001
father = [0] * (n + 1)
now = [1]
leaf = []
gress = [0] * (n + 1)
while now:
	node = now.pop()
	gress[node] = len(dic[node])
	if gress[node] == 1:
		leaf.append(node)
	c = min(cost[node], data[node][0])
	for child in dic[node]:
		if child != father[node]:
			father[child] = node
			cost[child] = c
			now.append(child)
res = 0
count = [[0, 0] for _ in range(n + 1)]
while leaf:
	node = leaf.pop()
	if data[node][1:] == [0, 1]:
		count[node][0] += 1
	elif data[node][1:] == [1, 0]:
		count[node][1] += 1
	if data[node][0] < cost[node]:
		t = min(count[node])
		res += t * data[node][0] * 2
		count[node][0] -= t
		count[node][1] -= t
	f = father[node]
	count[f][0] += count[node][0]
	count[f][1] += count[node][1]
	gress[f] -= 1
	if gress[f] == 1:
		leaf.append(f)
if count[0] == [0, 0]:
	print(res)
else:
	print(-1)


from bisect import bisect_left as bl
from bisect import bisect_right as br
from heapq import heappush, heappop
import math
from collections import *
from functools import reduce, cmp_to_key, lru_cache
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
M = mod = 10 ** 9 + 7

def factors(n):
	return sorted(set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0))))

def inv_mod(n):
	return pow(n, mod - 2, mod)

def li():
	return [int(i) for i in input().rstrip().split()]

def st():
	return str(input().rstrip())[2:-1]

def val():
	return int(input().rstrip())

def li2():
	return [str(i)[2:-1] for i in input().rstrip().split()]

def li3():
	return [int(i) for i in st()]
n = val()
cost = [0] * (n + 1)
ini = cost[:]
fin = cost[:]
ones1 = ones2 = ans = 0
topotraversal = []
for i in range(1, n + 1):
	(a, b, c) = li()
	cost[i] = a
	ini[i] = b
	fin[i] = c
	ones1 += b & 1
	ones2 += c & 1
if ones1 != ones2:
	print(-1)
	exit()
g = defaultdict(set)
for i in range(n - 1):
	(a, b) = li()
	g[a].add(b)
	g[b].add(a)

def refinecostdfs(root=1, par=0):
	global g, cost, topotraversal
	d = deque()
	d.append([root, par, cost[root]])
	while d:
		(root, par, c) = d.popleft()
		topotraversal.append([root, par])
		c = min(c, cost[root])
		cost[root] = c
		for j in g[root]:
			if j != par:
				d.append([j, root, c])
	topotraversal.reverse()

def domaindfs(root=1, par=0):
	global g, ini, fin, cost, ans, topotraversal
	visited = defaultdict(list)
	ans = 0
	for i in range(n + 1):
		visited[i] = [0, 0]
	for i in range(n):
		(root, par) = topotraversal[i]
		if ini[root] != fin[root]:
			visited[root][fin[root]] += 1
		mn = min(visited[root])
		ans += cost[root] * mn * 2
		visited[root][0] -= mn
		visited[root][1] -= mn
		visited[par][0] += visited[root][0]
		visited[par][1] += visited[root][1]
refinecostdfs()
domaindfs()
print(ans)


from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
import sys
input = sys.stdin.buffer.readline
n = int(input())
a = [0 for _ in range(n + 1)]
b = [0 for _ in range(n + 1)]
c = [0 for _ in range(n + 1)]
for i in range(n):
	(a[i + 1], b[i + 1], c[i + 1]) = [int(x) for x in input().split()]
edges = [[] for _ in range(n + 1)]
for _ in range(n - 1):
	(u, v) = [int(x) for x in input().split()]
	edges[u].append(v)
	edges[v].append(u)

@bootstrap
def dfs(node, parent):
	a[node] = min(a[node], a[parent])
	wrong0s = 0
	wrong1s = 0
	cost = 0
	if b[node] == 1 and c[node] == 0:
		wrong1s += 1
	elif b[node] == 0 and c[node] == 1:
		wrong0s += 1
	children = [x for x in edges[node] if x != parent]
	for child in children:
		(w0, w1, cc) = (yield dfs(child, node))
		wrong0s += w0
		wrong1s += w1
		cost += cc
	change = min(wrong0s, wrong1s)
	wrong0s -= change
	wrong1s -= change
	cost += 2 * change * a[node]
	yield [wrong0s, wrong1s, cost]
a[0] = 9999999999999
(wrong0s, wrong1s, cost) = dfs(1, 0)
if wrong0s != 0 or wrong1s != 0:
	print(-1)
else:
	print(cost)


import sys
input = sys.stdin.readline
from collections import deque
n = int(input())
a = [0] * n
b = [0] * n
c = [0] * n
y = [0] * n
for i in range(n):
	(a[i], b[i], c[i]) = map(int, input().split())
	y[i] = b[i] - c[i]
if sum(y) != 0:
	print(-1)
	exit()
g = [[] for i in range(n)]
for _ in range(n - 1):
	(u, v) = map(int, input().split())
	g[u - 1].append(v - 1)
	g[v - 1].append(u - 1)
mc = [0] * n
mc[0] = a[0]
q = [[-1, 0]]
p = [-1] * n
while q:
	(par, ver) = q.pop()
	for to in g[ver]:
		if par != to:
			p[to] = ver
			mc[to] = min(a[to], mc[ver])
			q.append([ver, to])
order = []
dq = deque([[-1, 0]])
while dq:
	(par, ver) = dq.popleft()
	order.append(ver)
	for to in g[ver]:
		if par != to:
			dq.append([ver, to])
ans = 0
for x in order[1:][::-1]:
	if y[x] * y[p[x]] < 0:
		ans += mc[p[x]] * min(abs(y[x]), abs(y[p[x]]))
	y[p[x]] += y[x]
print(ans * 2)


import sys
input = sys.stdin.readline
import math

def inp():
	return int(input())

def inlt():
	return list(map(int, input().split()))

def insr():
	s = input().strip()
	return list(s[:len(s)])

def invr():
	return map(int, input().strip().split())

def from_file(f):
	return f.readline

def dfs(s, parent, min_parent, A, B, C, edges):
	(cost, zeros, ones) = (0, 0, 0)
	if B[s] != C[s]:
		if B[s] == 1:
			ones += 1
		else:
			zeros += 1
	for v in edges[s]:
		if v == parent:
			continue
		(cc, cz, co) = dfs(v, s, min(A[s], min_parent), A, B, C, edges)
		cost += cc
		zeros += cz
		ones += co
	can_swap = min(ones, zeros)
	if can_swap > 0 and A[s] < min_parent:
		cost += 2 * A[s] * can_swap
		ones -= can_swap
		zeros -= can_swap
	return (cost, zeros, ones)

def dfs_iter(A, B, C, edges):
	stack = [(0, -1, float('inf'))]
	states = [None] * len(A)
	while stack:
		cur = stack.pop()
		(s, s_par, s_min_par) = cur
		if states[s] is None:
			(ones, zeros) = (0, 0)
			if B[s] != C[s]:
				if B[s] == 1:
					ones += 1
				else:
					zeros += 1
			states[s] = [0, zeros, ones]
			stack.append(cur)
			for v in edges[s]:
				if v == s_par:
					continue
				stack.append((v, s, min(A[s], s_min_par)))
		else:
			(cost, zeros, ones) = states[s]
			for v in edges[s]:
				if v == s_par:
					continue
				(cc, cz, co) = states[v]
				cost += cc
				zeros += cz
				ones += co
			can_swap = min(ones, zeros)
			if can_swap > 0 and A[s] < s_min_par:
				cost += 2 * A[s] * can_swap
				ones -= can_swap
				zeros -= can_swap
			states[s] = [cost, zeros, ones]
	return states[0]

def solution(A, B, C, edges):
	(cost, ones, zeros) = dfs_iter(A, B, C, edges)
	if ones > 0 or zeros > 0:
		return -1
	return cost
n = inp()
A = []
B = []
C = []
edges = [[] for _ in range(n)]
for i in range(n):
	(ai, bi, ci) = invr()
	A.append(ai)
	B.append(bi)
	C.append(ci)
for _ in range(n - 1):
	(u, v) = invr()
	edges[u - 1].append(v - 1)
	edges[v - 1].append(u - 1)
print(solution(A, B, C, edges))


from sys import stdin, stdout

def main():
	n = int(stdin.readline())
	cost = [0] * (n + 1)
	tree = [list() for _ in range(n + 1)]
	obj = [-1] * (n + 1)
	one = [0] * (n + 1)
	zero = [0] * (n + 1)
	processed = [False] * (n + 1)
	for i in range(n):
		(add, j, k) = list(map(int, stdin.readline().split()))
		cost[i + 1] = add
		if j != k:
			obj[i + 1] = k
	for i in range(n - 1):
		(a, b) = list(map(int, stdin.readline().split()))
		tree[a].append(b)
		tree[b].append(a)
	stack = [1]
	processed[1] = True
	res = 0
	while stack:
		cur = stack[-1]
		if tree[cur]:
			if processed[tree[cur][-1]]:
				tree[cur].pop()
				if not tree[cur]:
					continue
			child = tree[cur].pop()
			processed[child] = True
			cost[child] = min(cost[child], cost[cur])
			stack.append(child)
		else:
			if obj[cur] != -1:
				if obj[cur] == 1:
					one[cur] += 1
				else:
					zero[cur] += 1
			if one[cur] > 0 and zero[cur] > 0:
				perform = min(one[cur], zero[cur])
				res += cost[cur] * perform * 2
				one[cur] -= perform
				zero[cur] -= perform
			stack.pop()
			if cur != 1:
				parent = stack[-1]
				one[parent] += one[cur]
				zero[parent] += zero[cur]
	if one[1] > 0 or zero[1] > 0:
		stdout.write('-1\n')
	else:
		stdout.write(str(res))
main()


from sys import stdin, gettrace
from collections import deque
if gettrace():
	inputi = input
else:

	def input():
		return next(stdin)[:-1]

	def inputi():
		return stdin.buffer.readline()

def readTree(n):
	adj = [set() for _ in range(n)]
	for _ in range(n - 1):
		(u, v) = map(int, inputi().split())
		adj[u - 1].add(v - 1)
		adj[v - 1].add(u - 1)
	return adj

def treeOrderByDepth(n, adj, root=0):
	parent = [-2] + [-1] * (n - 1)
	ordered = []
	q = deque()
	q.append(root)
	while q:
		c = q.popleft()
		ordered.append(c)
		for a in adj[c]:
			if parent[a] == -1:
				parent[a] = c
				q.append(a)
	return (ordered, parent)

def main():
	n = int(inputi())
	aa = []
	bb = []
	cc = []
	for _ in range(n):
		(a, b, c) = map(int, inputi().split())
		aa.append(a)
		bb.append(b)
		cc.append(c)
	adj = readTree(n)
	if sum(bb) != sum(cc):
		print(-1)
		return
	diff = [b - c for (b, c) in zip(bb, cc)]
	dc = [abs(b - c) for (b, c) in zip(bb, cc)]
	(ordered, parent) = treeOrderByDepth(n, adj, 0)
	hb = [0] * n
	move = [0] * n
	for i in ordered[:0:-1]:
		diff[parent[i]] += diff[i]
		dc[parent[i]] += dc[i]
	move[0] = dc[0]
	for i in ordered[1:]:
		aa[i] = min(aa[i], aa[parent[i]])
		move[i] = dc[i] - abs(diff[i])
		move[parent[i]] -= move[i]
	res = sum((aa[i] * move[i] for i in range(n)))
	print(res)
main()


import sys
input = sys.stdin.readline
from collections import deque
t = int(input())
C = []
P = [-1 for i in range(t)]
Y = []
X = [[] for i in range(t)]
for i in range(t):
	(a, b, c) = list(map(int, input().split()))
	C.append(a)
	Y.append(b - c)
for i in range(t - 1):
	(a, b) = list(map(int, input().split()))
	a -= 1
	b -= 1
	X[a].append(b)
	X[b].append(a)
if sum(Y) != 0:
	print(-1)
	exit()
else:
	R = []
	Q = deque([0])
	while Q:
		x = deque.popleft(Q)
		R.append(x)
		for c in X[x]:
			P[c] = x
			X[c].remove(x)
			deque.append(Q, c)
	for j in R[1:]:
		C[j] = min(C[j], C[P[j]])
	ans = 0
	for i in R[1:][::-1]:
		if Y[i] * Y[P[i]] < 0:
			ans += C[P[i]] * min(abs(Y[i]), abs(Y[P[i]]))
		Y[P[i]] += Y[i]
	print(ans * 2)


import os
os_input = os.read(0, int(10000000.0)).split()
os_input_pos = -1
answer_list = []

def read_s():
	global os_input_pos
	os_input_pos += 1
	return os_input[os_input_pos].decode()

def read_i():
	return int(read_s())

def write_s(v):
	answer_list.append(v)

def write_i(v):
	write_s(str(v))

def print_ans():
	os.write(1, '\n'.join(answer_list).encode())
	os.write(1, '\n'.encode())
n = int(read_s())
cost = [0 for i in range(n + 1)]
val = [0 for i in range(n + 1)]
for i in range(1, n + 1):
	cost[i] = int(read_s())
	a = int(read_s())
	b = int(read_s())
	val[i] = 0 if a == b else 1 if a else -1
adj = [[] for i in range(n + 1)]
for i in range(1, n):
	a = int(read_s())
	b = int(read_s())
	adj[a].append(b)
	adj[b].append(a)
from collections import deque
order = []
par = [None for i in range(n + 1)]
q = deque()
q.append(1)
par[1] = 0
while q:
	u = q.popleft()
	order.append(u)
	for v in adj[u]:
		if par[v] is None:
			par[v] = u
			q.append(v)
			cost[v] = min(cost[v], cost[u])
ans = 0
dp = [None for i in range(n + 1)]
for u in reversed(order):
	a = val[u] == 1
	b = val[u] == -1
	for v in adj[u]:
		if dp[v] is not None:
			(t, c) = dp[v]
			if t:
				a += c
			else:
				b += c
	rem = min(a, b)
	ans += 2 * rem * cost[u]
	dp[u] = (a > b, max(a, b) - rem)
write_i(-1 if dp[1][1] else ans)
print_ans()


import sys

def main(x):
	for i in v[x]:
		d[i - 1][-1] = min(d[x - 1][-1], d[i - 1][-1])

def main2(x):
	for i in v[x]:
		d[x - 1][0] += d[i - 1][0]
		d[x - 1][1] += d[i - 1][1]
		d[x - 1][2] += d[i - 1][2]
	delta = min(d[x - 1][0], d[x - 1][1])
	d[x - 1][0] -= delta
	d[x - 1][1] -= delta
	d[x - 1][2] += 2 * d[x - 1][-1] * delta
n = int(input())
b = 0
c = 0
d = []
v = dict()
for i in range(n):
	(a1, b1, c1) = map(int, sys.stdin.readline().split())
	if b1 == 0 and c1 == 1:
		d.append([1, 0, 0, a1])
		b += 1
	elif b1 == 1 and c1 == 0:
		d.append([0, 1, 0, a1])
		c += 1
	else:
		d.append([0, 0, 0, a1])
	v[i + 1] = set()
for i in range(n - 1):
	(x, y) = map(int, sys.stdin.readline().split())
	v[x].add(y)
	v[y].add(x)
if b != c:
	print(-1)
	exit(0)
g = dict()
for i in range(1, n + 1):
	g[i] = 0
x = 1
gl = 0
sosed = set()
sosed.add(x)
while len(sosed) > 0:
	sosed2 = set()
	for j in sosed:
		g[j] = gl
		for i in v[j]:
			v[i].discard(j)
		for i in v[j]:
			sosed2.add(i)
	sosed = sosed2.copy()
	gl += 1
have_glub = dict()
for i in range(n + 1):
	have_glub[i] = set()
for i in range(1, n + 1):
	have_glub[g[i]].add(i)
for i in range(n + 1):
	for j in have_glub[i]:
		main(j)
for i in range(n, -1, -1):
	for j in have_glub[i]:
		main2(j)
print(d[0][2])


import sys
readline = sys.stdin.readline
ns = lambda : readline().rstrip()
ni = lambda : int(readline().rstrip())
nm = lambda : map(int, readline().split())
nl = lambda : list(map(int, readline().split()))

def solve():
	n = ni()
	data = [tuple(nm()) for _ in range(n)]
	sb = sum((x[1] for x in data))
	sc = sum((x[2] for x in data))
	if sb != sc:
		print(-1)
		return
	G = [list() for _ in range(n)]
	for _ in range(n - 1):
		(u, v) = nm()
		u -= 1
		v -= 1
		G[u].append(v)
		G[v].append(u)
	q = [0]
	cost = [x[0] for x in data]
	dp = [None] * n
	ans = 0
	while q:
		v = q[-1]
		if dp[v] is None:
			dp[v] = [-1, -1]
			for x in G[v]:
				if dp[x] is None:
					if cost[x] > cost[v]:
						cost[x] = cost[v]
					q.append(x)
		else:
			q.pop()
			dp[v] = [0, 0]
			if data[v][1] != data[v][2]:
				dp[v][data[v][1]] += 1
			for x in G[v]:
				(a, b) = dp[x]
				if a >= 0:
					dp[v][0] += a
					dp[v][1] += b
			c = min(dp[v])
			ans += c * cost[v] * 2
			dp[v][0] -= c
			dp[v][1] -= c
	print(ans)
	return
solve()


import sys
ints = (int(x) for x in sys.stdin.read().split())
sys.setrecursionlimit(3000)
n = 2 * 10 ** 5 + 5
inf = 10 ** 9
a = [0] * n
b = [0] * n
c = [0] * n
pa = [-1] * n
Z = [0] * n
G = [[] for i in range(n)]

def main():
	n = next(ints)
	for i in range(n):
		a[i] = next(ints)
		b[i] = next(ints)
		c[i] = next(ints)
	for i in range(n - 1):
		(u, v) = (next(ints) - 1, next(ints) - 1)
		G[u].append(v)
		G[v].append(u)
	ans = -1 if sum(b) != sum(c) else solve(n)
	print(ans)
	return

def solve(n):
	topo = []
	q = [0]
	while q:
		u = q.pop()
		topo.append(u)
		for v in G[u]:
			if pa[v] == -1 and v != pa[u]:
				q.append(v)
				pa[v] = u
				G[v].remove(u)
				a[v] = min(a[v], a[u])
	ans = 0
	for i in topo[::-1]:
		Z[i] = c[i] - b[i] + sum((Z[j] for j in G[i]))
		pos = sum((Z[j] for j in G[i] if Z[j] > 0))
		neg = -sum((Z[j] for j in G[i] if Z[j] < 0))
		k = min((c[i] > b[i]) + pos, (c[i] < b[i]) + neg)
		ans += 2 * k * a[i]
	return ans
main()


import sys
input = sys.stdin.readline
from collections import deque, Counter

def main():
	N = int(input())
	(A, B, C, cb, cc) = ([], [], [], [0, 0], [0, 0])
	E = [[] for _ in range(N)]
	for _ in range(N):
		(a, b, c) = map(int, input().split())
		A.append(a)
		B.append(b)
		C.append(c)
		cb[b] += 1
		cc[c] += 1
	for _ in range(N - 1):
		(u, v) = map(lambda x: int(x) - 1, input().split())
		E[u].append(v)
		E[v].append(u)
	if cb[0] != cc[0]:
		print(-1)
		return
	R = [-1] * N
	V = [-1] * N
	V[0] = A[0]
	d = deque(E[0])
	for v in E[0]:
		R[v] = 0
	T = [0]
	while d:
		v = d.popleft()
		T.append(v)
		V[v] = min(V[R[v]], A[v])
		for w in E[v]:
			if V[w] == -1:
				d.append(w)
				R[w] = v
	RT = T[::-1]
	Hzero = [0] * N
	Hone = [0] * N
	ans = 0
	for v in RT:
		if B[v] != C[v]:
			if B[v] == 0:
				Hzero[v] += 1
			else:
				Hone[v] += 1
		if Hzero[v] > 0 and Hone[v] > 0:
			m = min(Hone[v], Hzero[v])
			ans += m * V[v] * 2
			Hzero[v] -= m
			Hone[v] -= m
		if v != 0:
			Hzero[R[v]] += Hzero[v]
			Hone[R[v]] += Hone[v]
	print(ans)
main()


import sys
sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

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

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

def MI1():
	return map(int1, sys.stdin.readline().split())

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

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline()[:-1]

def main():
	inf = 10 ** 16
	n = II()
	abc = LLI(n)
	to = [[] for _ in range(n)]
	for _ in range(n - 1):
		(u, v) = MI1()
		to[u].append(v)
		to[v].append(u)
	dp = [-1] * n
	cnt = [[0] * 2 for _ in range(n + 1)]
	stack = [(0, n, inf)]
	while stack:
		(u, pu, mn) = stack.pop()
		if dp[u] == -1:
			(a, b, c) = abc[u]
			mn = min(mn, a)
			if b + c == 1:
				cnt[u][b] += 1
			dp[u] = 0
			stack.append((u, pu, mn))
			for v in to[u]:
				if v == pu:
					continue
				stack.append((v, u, mn))
		else:
			k = min(cnt[u])
			dp[u] = mn * k * 2
			cnt[pu][0] += cnt[u][0] - k
			cnt[pu][1] += cnt[u][1] - k
	if sum(cnt[n]):
		print(-1)
	else:
		print(sum(dp))
main()


import sys
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
import collections
from collections import defaultdict

def bfs(root):
	visited = [0] * (n + 1)
	queue = collections.deque([root])
	visited[root] = 1
	while queue:
		vertex = queue.popleft()
		for neighbour in graph[vertex]:
			if visited[neighbour] == 0:
				binary[neighbour][0] = min(binary[neighbour][0], binary[vertex][0])
				visited[neighbour] = 1
				queue.append(neighbour)
	return
n = int(input())
binary = defaultdict(list)
(bsum, csum) = (0, 0)
for i in range(n):
	(a, b, c) = map(int, input().split())
	bsum += b
	csum += c
	binary[i + 1].append(a)
	binary[i + 1].append(b)
	binary[i + 1].append(c)
if bsum != csum:
	sys.stdout.write(str(-1) + '\n')
else:
	graph = defaultdict(list)
	for i in range(n - 1):
		(u, v) = map(int, input().split())
		graph[u].append(v)
		graph[v].append(u)
	bfs(1)
	OBSERVE = 0
	CHECK = 1
	stack = [(OBSERVE, 1, 0)]
	bit = [[0, 0] for _ in range(n + 1)]
	store = defaultdict(int)
	while len(stack):
		(state, vertex, parent) = stack.pop()
		if state == OBSERVE:
			stack.append((CHECK, vertex, parent))
			for child in graph[vertex]:
				if child != parent:
					stack.append((OBSERVE, child, vertex))
		else:
			sub_bit = [0, 0]
			if binary[vertex][1] != binary[vertex][2]:
				sub_bit[binary[vertex][2]] += 1
			for child in graph[vertex]:
				if child != parent:
					sub_bit[0] += bit[child][0]
					sub_bit[1] += bit[child][1]
			mina = min(sub_bit[0], sub_bit[1])
			sub_bit[0] -= mina
			sub_bit[1] -= mina
			bit[vertex] = sub_bit
			if len(graph[vertex]) > 1 or vertex == 1:
				if mina > 0:
					store[binary[vertex][0]] += mina * 2
	ans = 0
	for i in store:
		ans += i * store[i]
	sys.stdout.write(str(ans) + '\n')


import sys, bisect, string, math, time, functools, random, fractions
from heapq import heappush, heappop, heapify
from collections import deque, defaultdict, Counter
from itertools import permutations, combinations, groupby
rep = range

def Golf():
	(n, *t) = map(int, open(0).read().split())

def I():
	return int(input())

def S_():
	return input()

def IS():
	return input().split()

def LS():
	return [i for i in input().split()]

def LI():
	return [int(i) for i in input().split()]

def LI_():
	return [int(i) - 1 for i in input().split()]

def NI(n):
	return [int(input()) for i in range(n)]

def NI_(n):
	return [int(input()) - 1 for i in range(n)]

def StoLI():
	return [ord(i) - 97 for i in input()]

def ItoS(n):
	return chr(n + 97)

def LtoS(ls):
	return ''.join([chr(i + 97) for i in ls])

def RA():
	return map(int, open(0).read().split())

def GI(V, E, ls=None, Directed=False, index=1):
	org_inp = []
	g = [[] for i in range(V)]
	FromStdin = True if ls == None else False
	for i in range(E):
		if FromStdin:
			inp = LI()
			org_inp.append(inp)
		else:
			inp = ls[i]
		if len(inp) == 2:
			(a, b) = inp
			c = 1
		else:
			(a, b, c) = inp
		if index == 1:
			a -= 1
			b -= 1
		aa = (a, c)
		bb = (b, c)
		g[a].append(bb)
		if not Directed:
			g[b].append(aa)
	return (g, org_inp)

def GGI(h, w, search=None, replacement_of_found='.', mp_def={'#': 1, '.': 0}, boundary=1):
	mp = [boundary] * (w + 2)
	found = {}
	for i in range(h):
		s = input()
		for char in search:
			if char in s:
				found[char] = (i + 1) * (w + 2) + s.index(char) + 1
				mp_def[char] = mp_def[replacement_of_found]
		mp += [boundary] + [mp_def[j] for j in s] + [boundary]
	mp += [boundary] * (w + 2)
	return (h + 2, w + 2, mp, found)

def TI(n):
	return GI(n, n - 1)

def accum(ls):
	rt = [0]
	for i in ls:
		rt += [rt[-1] + i]
	return rt

def bit_combination(n, base=2):
	rt = []
	for tb in range(base ** n):
		s = [tb // base ** bt % base for bt in range(n)]
		rt += [s]
	return rt

def gcd(x, y):
	if y == 0:
		return x
	if x % y == 0:
		return y
	while x % y != 0:
		(x, y) = (y, x % y)
	return y

def show(*inp, end='\n'):
	if show_flg:
		print(*inp, end=end)
YN = ['YES', 'NO']
Yn = ['Yes', 'No']
mo = 10 ** 9 + 7
inf = float('inf')
FourNb = [(-1, 0), (1, 0), (0, 1), (0, -1)]
EightNb = [(-1, 0), (1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)]
compas = dict(zip('WENS', FourNb))
cursol = dict(zip('LRUD', FourNb))
l_alp = string.ascii_lowercase
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
input = lambda : sys.stdin.readline().rstrip()

class Tree:

	def __init__(self, inp_size=None, ls=None, init=True, index=1):
		self.LCA_init_stat = False
		self.ETtable = []
		if init:
			if ls == None:
				self.stdin(inp_size, index=index)
			else:
				self.size = len(ls) + 1
				(self.edges, _) = GI(self.size, self.size - 1, ls, index=index)
		return

	def stdin(self, inp_size=None, index=1):
		if inp_size == None:
			self.size = int(input())
		else:
			self.size = inp_size
		(self.edges, _) = GI(self.size, self.size - 1, index=index)
		return

	def listin(self, ls, index=0):
		self.size = len(ls) + 1
		(self.edges, _) = GI(self.size, self.size - 1, ls, index=index)
		return

	def __str__(self):
		return str(self.edges)

	def dfs(self, x, func=lambda prv, nx, dist: prv + dist, root_v=0):
		q = deque()
		q.append(x)
		v = [-1] * self.size
		v[x] = root_v
		while q:
			c = q.pop()
			for (nb, d) in self.edges[c]:
				if v[nb] == -1:
					q.append(nb)
					v[nb] = func(v[c], nb, d)
		return v

	def bfs(self, x, func=lambda prv, nx, dist: prv + dist, root_v=0):
		bup = []
		q = deque()
		q.append(x)
		v = [-1] * self.size
		self.par = [-1] * self.size
		v[x] = root_v
		while q:
			c = q.popleft()
			bup.append(c)
			for (nb, d) in self.edges[c]:
				if v[nb] == -1:
					q.append(nb)
					v[nb] = func(v[c], nb, d)
					self.par[nb] = c
		return (v, bup)

	def EulerTour(self, x):
		q = deque()
		q.append(x)
		self.depth = [None] * self.size
		self.depth[x] = 0
		self.ETtable = []
		self.ETdepth = []
		self.ETin = [-1] * self.size
		self.ETout = [-1] * self.size
		cnt = 0
		while q:
			c = q.pop()
			if c < 0:
				ce = ~c
			else:
				ce = c
				for (nb, d) in self.edges[ce]:
					if self.depth[nb] == None:
						q.append(~ce)
						q.append(nb)
						self.depth[nb] = self.depth[ce] + 1
			self.ETtable.append(ce)
			self.ETdepth.append(self.depth[ce])
			if self.ETin[ce] == -1:
				self.ETin[ce] = cnt
			else:
				self.ETout[ce] = cnt
			cnt += 1
		return

	def LCA_init(self, root):
		self.EulerTour(root)
		self.st = SparseTable(self.ETdepth, init_func=min, init_idl=inf)
		self.LCA_init_stat = True
		return

	def LCA(self, root, x, y):
		if self.LCA_init_stat == False:
			self.LCA_init(root)
		(xin, xout) = (self.ETin[x], self.ETout[x])
		(yin, yout) = (self.ETin[y], self.ETout[y])
		a = min(xin, yin)
		b = max(xout, yout, xin, yin)
		id_of_min_dep_in_et = self.st.query_id(a, b + 1)
		return self.ETtable[id_of_min_dep_in_et]

class SparseTable:

	def __init__(self, ls, init_func=min, init_idl=float('inf')):
		self.func = init_func
		self.idl = init_idl
		self.size = len(ls)
		self.N0 = self.size.bit_length()
		self.table = [ls[:]]
		self.index = [list(range(self.size))]
		self.lg = [0] * (self.size + 1)
		for i in range(2, self.size + 1):
			self.lg[i] = self.lg[i >> 1] + 1
		for i in range(self.N0):
			tmp = [self.func(self.table[i][j], self.table[i][min(j + (1 << i), self.size - 1)]) for j in range(self.size)]
			tmp_id = [self.index[i][j] if self.table[i][j] == self.func(self.table[i][j], self.table[i][min(j + (1 << i), self.size - 1)]) else self.index[i][min(j + (1 << i), self.size - 1)] for j in range(self.size)]
			self.table += [tmp]
			self.index += [tmp_id]

	def query(self, l, r):
		if r > self.size:
			r = self.size
		N = self.lg[r - l]
		return self.func(self.table[N][l], self.table[N][max(0, r - (1 << N))])

	def query_id(self, l, r):
		if r > self.size:
			r = self.size
		N = self.lg[r - l]
		(a, b) = (self.index[N][l], self.index[N][max(0, r - (1 << N))])
		if self.table[0][a] == self.func(self.table[N][l], self.table[N][max(0, r - (1 << N))]):
			b = a
		return b

	def right_bound(self, pos, x):
		k = (self.size - pos).bit_length()
		for j in range(k)[::-1]:
			nx = pos + (1 << j)
			if nx < n and self.query(pos, nx + 1) <= x:
				pos += 1 << j
		return pos

	def left_bound(self, pos, x):
		k = pos.bit_length()
		for j in range(k)[::-1]:
			nx = pos - (1 << j)
			if 0 <= nx and self.query(nx, pos + 1) <= x:
				pos -= 1 << j
		return pos

	def __str__(self):
		return str(self.table[0])

	def print(self):
		for i in self.table:
			print(*i)

def primeFactor(N):
	(i, n) = (2, N)
	ret = {}
	(d, sq) = (2, 99)
	while i <= sq:
		k = 0
		while n % i == 0:
			(n, k, ret[i]) = (n // i, k + 1, k + 1)
		if k > 0 or i == 97:
			sq = int(n ** (1 / 2) + 0.5)
		if i < 4:
			i = i * 2 - 1
		else:
			(i, d) = (i + d, d ^ 6)
	if n > 1:
		ret[n] = 1
	return ret

def topological_sort(G):
	n = len(G)
	rt = []
	indeg = [0] * n
	for i in range(n):
		for j in G[i]:
			indeg[j] += 1
	q = deque()
	for i in range(n):
		if indeg[i] == 0:
			q.append(i)
	while q:
		c = q.popleft()
		rt.append(c)
		for nb in G[c]:
			indeg[nb] -= 1
			if indeg[nb] == 0:
				q.append(nb)
	return rt
show_flg = False
show_flg = True
ans = 0
ans = 0
(A, B, C) = ([], [], [])
n = I()
for i in rep(n):
	(x, y, z) = LI()
	A += [x]
	B += [y]
	C += [z]
tin = [LI() for i in rep(n - 1)]
tr = Tree(n, tin, index=1)
A = tr.dfs(0, func=lambda prv, nx, dist: min(prv, A[nx]), root_v=A[0])
(v, bup) = tr.bfs(0, func=lambda prv, nx, dist: prv + 1, root_v=0)
if sum(B) != sum(C):
	print(-1)
	exit()
x = [[0, 0] for i in range(n)]
for i in bup[::-1]:
	if B[i] != C[i]:
		x[i][B[i]] += 1
	(b, c) = x[i]
	u = min(b, c)
	ans += A[i] * u * 2
	x[tr.par[i]][0] += x[i][0] - u
	x[tr.par[i]][1] += x[i][1] - u
	x[i] = [0, 0]
print(ans)


import sys
from types import GeneratorType
input = sys.stdin.readline

def my_recursion(gen):
	stk = [gen]
	res = None
	while True:
		cur = stk[-1]
		obj = None
		if type(cur) is GeneratorType:
			try:
				obj = next(cur)
			except StopIteration:
				pass
		else:
			stk.pop()
			if not stk:
				res = cur
				break
			try:
				obj = stk[-1].send(cur)
			except StopIteration:
				pass
		if type(obj) is GeneratorType:
			stk.append(obj)
		else:
			stk[-1] = obj
	return res

def main():
	n = int(input())
	a = [0] * n
	b = [0] * n
	c = [0] * n
	for i in range(n):
		(a[i], b[i], c[i]) = map(int, input().split())
	g = [[] for _ in range(n)]
	for _ in range(n - 1):
		(x, y) = map(int, input().split())
		g[x - 1].append(y - 1)
		g[y - 1].append(x - 1)
	_01 = [0] * n
	_10 = [0] * n
	ans = 0

	def dfs(u, p=-1):
		for v in g[u]:
			if v != p:
				a[v] = min(a[v], a[u])
				yield dfs(v, u)
				_01[u] += _01[v]
				_10[u] += _10[v]
		if b[u] != c[u]:
			if b[u] == 0:
				_01[u] += 1
			else:
				_10[u] += 1
		m = min(_01[u], _10[u])
		nonlocal ans
		ans += 2 * m * a[u]
		_01[u] -= m
		_10[u] -= m
	my_recursion(dfs(0))
	print('-1') if _01[0] > 0 or _10[0] > 0 else print(ans)
main()


from bisect import *
from collections import *
from math import gcd, ceil, sqrt, floor, inf
from heapq import *
from itertools import *
from operator import add, mul, sub, xor, truediv, floordiv
from functools import *
import os
import sys
from io import BytesIO, IOBase
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')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

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

def N():
	return int(input())
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
farr = [1]
ifa = []

def fact(x, mod=0):
	if mod:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr) % mod)
	else:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr))
	return farr[x]

def ifact(x, mod):
	global ifa
	ifa.append(pow(farr[-1], mod - 2, mod))
	for i in range(x, 0, -1):
		ifa.append(ifa[-1] * i % mod)
	ifa = ifa[::-1]

def per(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return fact(i) // fact(i - j)
	return farr[i] * ifa[i - j] % mod

def com(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return per(i, j) // fact(j)
	return per(i, j, mod) * ifa[j] % mod

def catalan(n):
	return com(2 * n, n) // (n + 1)

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def lowbit(n):
	return n & -n

def inverse(a, m):
	a %= m
	if a <= 1:
		return a
	return (1 - inverse(m, a) * m) // a % m

class BIT:

	def __init__(self, arr):
		self.arr = arr
		self.n = len(arr) - 1

	def update(self, x, v):
		while x <= self.n:
			self.arr[x] += v
			x += x & -x

	def query(self, x):
		ans = 0
		while x:
			ans += self.arr[x]
			x &= x - 1
		return ans

class DSU:

	def __init__(self, n):
		self.c = [-1] * n

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def find(self, x):
		if self.c[x] < 0:
			return x
		self.c[x] = self.find(self.c[x])
		return self.c[x]

	def union(self, u, v):
		(u, v) = (self.find(u), self.find(v))
		if u == v:
			return False
		if self.c[u] < self.c[v]:
			(u, v) = (v, u)
		self.c[u] += self.c[v]
		self.c[v] = u
		return True

	def size(self, x):
		return -self.c[self.find(x)]

class UFS:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.ranks = [0] * n

	def find(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return False
		if self.ranks[pu] >= self.ranks[pv]:
			self.parent[pv] = pu
			if self.ranks[pv] == self.ranks[pu]:
				self.ranks[pu] += 1
		else:
			self.parent[pu] = pv

def Prime(n):
	c = 0
	prime = []
	flag = [0] * (n + 1)
	for i in range(2, n + 1):
		if not flag[i]:
			prime.append(i)
			c += 1
		for j in range(c):
			if i * prime[j] > n:
				break
			flag[i * prime[j]] = prime[j]
			if i % prime[j] == 0:
				break
	return flag

def dij(s, graph):
	d = {}
	d[s] = 0
	heap = [(0, s)]
	seen = set()
	while heap:
		(dis, u) = heappop(heap)
		if u in seen:
			continue
		for v in graph[u]:
			if v not in d or d[v] > d[u] + graph[u][v]:
				d[v] = d[u] + graph[u][v]
				heappush(heap, (d[v], v))
	return d

def GP(it):
	return [[ch, len(list(g))] for (ch, g) in groupby(it)]

class DLN:

	def __init__(self, val):
		self.val = val
		self.pre = None
		self.next = None

def nb(i, j):
	for (ni, nj) in [[i + 1, j], [i - 1, j], [i, j - 1], [i, j + 1]]:
		if 0 <= ni < n and 0 <= nj < m:
			yield (ni, nj)

@bootstrap
def gdfs(r, p):
	if len(g[r]) == 1 and p != -1:
		yield None
	for ch in g[r]:
		if ch != p:
			yield gdfs(ch, r)
	yield None

@bootstrap
def dfs(r, p, res):
	cost[r] = min(cost[r], res)
	if len(g[r]) == 1 and p != -1:
		yield tp[r]
	a = b = 0
	if tp[r] == 1:
		a += 1
	elif tp[r] == -1:
		b -= 1
	for ch in g[r]:
		if ch != p:
			tmp = (yield dfs(ch, r, cost[r]))
			if tmp > 0:
				a += tmp
			elif tmp < 0:
				b += tmp
	global ans
	ans += min(a, -b) * cost[r] * 2
	yield (a + b)
t = 1
for i in range(t):
	n = N()
	cnt = 0
	cost = [0] * (n + 1)
	tp = [0] * (n + 1)
	for i in range(n):
		(a, b, c) = RL()
		if b != c:
			tp[i + 1] = 1 if b == 0 else -1
			cnt += tp[i + 1]
		cost[i + 1] = a
	g = [[] for i in range(n + 1)]
	for i in range(n - 1):
		(u, v) = RL()
		g[u].append(v)
		g[v].append(u)
	if cnt:
		print(-1)
		exit()
	ans = 0
	dfs(1, -1, inf)
	print(ans)


import os, sys
from io import BytesIO, IOBase
from copy import deepcopy

def main():
	n = int(input())
	prop = [0] + [tuple(map(int, input().split())) for _ in range(n)]
	path = [[] for _ in range(n + 1)]
	for _ in range(n - 1):
		(u1, v1) = map(int, input().split())
		path[u1].append(v1)
		path[v1].append(u1)
	path1 = deepcopy(path)
	z = 0
	for i in range(1, n + 1):
		z += (prop[i][1] == 0) - (prop[i][2] == 0)
	if z:
		return -1
	st = [1]
	to_be_changed = [[0, 0] for _ in range(n + 1)]
	parent = [0, 1] + [0] * (n - 1)
	while len(st):
		while len(path[st[-1]]) and parent[path[st[-1]][-1]]:
			path[st[-1]].pop()
		if not len(path[st[-1]]):
			x = st.pop()
			if prop[x][1] != prop[x][2]:
				to_be_changed[x][prop[x][1]] += 1
			if len(st):
				to_be_changed[st[-1]][0] += to_be_changed[x][0]
				to_be_changed[st[-1]][1] += to_be_changed[x][1]
			continue
		i = path[st[-1]].pop()
		parent[i] = 1
		st.append(i)
	ans = min(to_be_changed[1]) * 2 * prop[1][0]
	value_used = [0] + [prop[i][0] for i in range(1, n + 1)]
	st = [1]
	parent = [0, 1] + [0] * (n - 1)
	path = path1
	while len(st):
		while len(path[st[-1]]) and parent[path[st[-1]][-1]]:
			path[st[-1]].pop()
		if not len(path[st[-1]]):
			st.pop()
			continue
		i = path[st[-1]].pop()
		parent[i] = 1
		st.append(i)
		if value_used[st[-1]] < value_used[st[-2]]:
			ans -= (value_used[st[-2]] - value_used[st[-1]]) * min(to_be_changed[st[-1]]) * 2
		else:
			value_used[st[-1]] = value_used[st[-2]]
	return ans
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')
print(main())


import sys

def f():
	return map(int, sys.stdin.readline().split())
n = int(input())
val = []
bit = []
for i in range(n):
	(v, a, b) = f()
	val.append((v, i))
	bit.append(a - b)
val.sort()
go = [set() for _ in range(n)]
for _ in range(n - 1):
	(a, b) = f()
	a -= 1
	b -= 1
	go[a].add(b)
	go[b].add(a)
if sum(bit) != 0:
	print(-1)
	exit()
q = [0]
while len(q) != 0:
	now = q.pop()
	for x in go[now]:
		go[x].remove(now)
		q.append(x)
ans = 0
for (v, i) in val:
	pos = neg = 0
	q = [i]
	while len(q) != 0:
		now = q.pop()
		for x in go[now]:
			if bit[x] > 0:
				pos += bit[x]
			else:
				neg += bit[x]
			bit[x] = 0
			q.append(x)
		go[now] = []
	if bit[i] > 0:
		pos += bit[i]
	else:
		neg += bit[i]
	ans += v * min(pos, -neg) * 2
	bit[i] = pos + neg
print(ans)


import sys
input = sys.stdin.readline
(N,) = map(int, input().split())
(A, B1, B2) = ([0] * (N + 1), [0] * (N + 1), [0] * (N + 1))
for i in range(1, N + 1):
	(a, b, c) = map(int, input().split())
	A[i] = a
	if b == 1 and c == 0:
		B1[i] = 1
	if b == 0 and c == 1:
		B2[i] = 1
G = [set() for _ in range(N + 1)]
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	G[a].add(b)
	G[b].add(a)
if sum(B1) != sum(B2):
	print(-1)
else:
	vs = set([1])
	stack = [1]
	vs_dfs = list()
	d = [set() for _ in range(N + 1)]
	while stack:
		v = stack.pop()
		vs_dfs.append(v)
		for u in G[v]:
			if u in vs:
				continue
			if A[u] > A[v]:
				A[u] = A[v]
			d[v].add(u)
			vs.add(u)
			stack.append(u)
	R = 0
	for v in vs_dfs[::-1]:
		for u in d[v]:
			B1[v] += B1[u]
			B2[v] += B2[u]
		mnx = min(B1[v], B2[v])
		R += 2 * mnx * A[v]
		B1[v] -= mnx
		B2[v] -= mnx
	print(R)


import collections
import sys
input = sys.stdin.readline
n = int(input())
arr = [list(map(int, input().split())) for _ in range(n)]
cnt1 = 0
cnt2 = 0
cnt = [[0, 0] for _ in range(n + 1)]
cost = [10 ** 18] * (n + 1)
for i in range(n):
	(a, b, c) = arr[i]
	cost[i + 1] = a
	if b == 1 and c == 0:
		cnt1 += 1
		cnt[i + 1][0] = 1
	if b == 0 and c == 1:
		cnt2 += 1
		cnt[i + 1][1] = 1
if cnt1 != cnt2:
	print(-1)
else:
	g = [[] for _ in range(n + 1)]
	for _ in range(n - 1):
		(a, b) = map(int, input().split())
		g[a].append(b)
		g[b].append(a)
	q = collections.deque()
	q.append(1)
	checked = [0] * (n + 1)
	checked[1] = 1
	visit = []
	child = [[] for _ in range(n + 1)]
	while len(q) != 0:
		v = q.popleft()
		visit.append(v)
		for u in g[v]:
			if checked[u] == 0:
				checked[u] = 1
				cost[u] = min(cost[v], cost[u])
				child[v].append(u)
				q.append(u)
	ans = 0
	for v in visit[::-1]:
		for u in child[v]:
			cnt[v][0] += cnt[u][0]
			cnt[v][1] += cnt[u][1]
		m = min(cnt[v][0], cnt[v][1])
		ans += cost[v] * (2 * m)
		cnt[v][0] -= m
		cnt[v][1] -= m
	print(ans)


import sys
input = sys.stdin.buffer.readline

def main():
	n = int(input())
	ABC = []
	t01 = 0
	t10 = 0
	for i in range(n):
		(a, b, c) = map(int, input().split())
		if b == 0 and c == 1:
			t01 += 1
		elif b == 1 and c == 0:
			t10 += 1
		else:
			pass
		ABC.append((a, b, c))
	if t01 != t10:
		print(-1)
		exit()
	g = [[] for _ in range(n)]
	for i in range(n - 1):
		(u, v) = map(int, input().split())
		(u, v) = (u - 1, v - 1)
		g[u].append(v)
		g[v].append(u)
	s = []
	s.append(0)
	parent = [-1] * n
	order = []
	while s:
		x = s.pop()
		order.append(x)
		for nx in g[x]:
			if nx == parent[x]:
				continue
			parent[nx] = x
			s.append(nx)
	A = [10 ** 18] * n
	A[0] = ABC[0][0]
	for v in order:
		if parent[v] != -1:
			A[v] = min(A[parent[v]], ABC[v][0])
		else:
			continue
	order.reverse()
	ans = 0
	T = [[0] * 2 for _ in range(n)]
	for v in order:
		(b, c) = (ABC[v][1], ABC[v][2])
		if b == 0 and c == 1:
			T[v][0] += 1
		elif b == 1 and c == 0:
			T[v][1] += 1
		else:
			pass
		t = min(T[v])
		ans += 2 * t * A[v]
		if parent[v] != -1:
			T[parent[v]][0] += T[v][0] - t
			T[parent[v]][1] += T[v][1] - t
	print(ans)
main()


from sys import stdin
from collections import Counter, deque
from bisect import bisect_left
input = stdin.buffer.readline
n = int(input())
ls = [(0, 0, 0)]
for _ in range(n):
	(a, b, c) = map(int, input().split())
	ls.append((a, b, c))
e = [[] for _ in range(n + 1)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	e[a].append(b)
	e[b].append(a)
(p, mcc, nodes) = ([0] * (n + 1), [0] * (n + 1), [])
q = deque([1])
p[1] = 1
mcc[1] = ls[1][0]
while q:
	u = q.popleft()
	nodes.append(u)
	mcc[u] = min(ls[u][0], mcc[p[u]])
	for v in e[u]:
		if p[v]:
			continue
		p[v] = u
		q.append(v)
cov = [0] * (n + 1)
for u in reversed(nodes):
	(a, b, c) = (0, 0, 0)
	(oa, ob, oc) = ls[u]
	for v in e[u]:
		if v == p[u]:
			continue
		(ta, tb, tc) = cov[v]
		a += ta
		b += tb
		c += tc
	if ob != oc:
		if ob == 1:
			b += 1
		else:
			c += 1
	if oa == mcc[u]:
		both = min(b, c)
		a += oa * both * 2
		b -= both
		c -= both
	cov[u] = (a, b, c)
(a, b, c) = cov[1]
print(a if b + c == 0 else -1)


import os
import sys
if os.path.exists('/mnt/c/Users/Square/square/codeforces'):
	f = iter(open('E.txt').readlines())

	def input():
		return next(f).strip()
else:
	input = lambda : sys.stdin.readline().strip()
fprint = lambda *args: print(*args, flush=True)
import itertools
n = int(input())
g = {i: [] for i in range(1, n + 1)}
(A, B, C) = ([-1], [-1], [-1])
for i in range(n):
	(a, b, c) = map(int, input().split())
	A.append(a)
	B.append(b)
	C.append(c)
for i in range(n - 1):
	(u, v) = map(int, input().split())
	g[u].append(v)
	g[v].append(u)
INF = 10 ** 6
color = [0] * (n + 1)
imb = [0] * (n + 1)
tot = [0] * (n + 1)
cost = [0] * (n + 1)
best = [INF] * (n + 1)
stack = [1]
best[1] = A[1]
while stack:
	u = stack[-1]
	if color[u] == 0:
		for v in g[u]:
			if color[v] == 0:
				best[v] = min(best[u], A[v])
				stack.append(v)
		color[u] = 1
	elif color[u] == 1:
		total = 0
		imb[u] += B[u] - C[u]
		tot[u] += abs(B[u] - C[u])
		for v in g[u]:
			imb[u] += imb[v]
			tot[u] += abs(imb[v])
		cost[u] = (tot[u] - abs(imb[u])) * best[u]
		stack.pop()
if sum(B) != sum(C):
	print(-1)
else:
	print(sum(cost))


import sys
data = [list(map(int, line.rstrip().split())) for line in sys.stdin.readlines()]
n = data[0][0]
dic = [[] for _ in range(n + 1)]
dic[1].append(0)
for (u, v) in data[n + 1:]:
	dic[u].append(v)
	dic[v].append(u)
cost = [0] * (n + 1)
cost[1] = 1000000001
father = [0] * (n + 1)
now = [1]
leaf = []
gress = [0] * (n + 1)
while now:
	node = now.pop()
	gress[node] = len(dic[node])
	if gress[node] == 1:
		leaf.append(node)
	c = min(cost[node], data[node][0])
	for child in dic[node]:
		if child != father[node]:
			father[child] = node
			cost[child] = c
			now.append(child)
res = 0
count = [[0, 0] for _ in range(n + 1)]
while leaf:
	node = leaf.pop()
	if data[node][1] == 0 and data[node][2] == 1:
		count[node][0] += 1
	elif data[node][1] == 1 and data[node][2] == 0:
		count[node][1] += 1
	if data[node][0] < cost[node]:
		t = min(count[node])
		res += t * data[node][0] * 2
		count[node][0] -= t
		count[node][1] -= t
	f = father[node]
	count[f][0] += count[node][0]
	count[f][1] += count[node][1]
	gress[f] -= 1
	if gress[f] == 1:
		leaf.append(f)
if count[0] == [0, 0]:
	print(res)
else:
	print(-1)


import sys, math
from collections import defaultdict as dd, deque, Counter

def data():
	return sys.stdin.readline().strip()

def mdata():
	return list(map(int, data().split()))

def outl(var):
	sys.stdout.write(' '.join(map(str, var)) + '\n')

def out(var):
	sys.stdout.write(str(var) + '\n')
sys.setrecursionlimit(100000)
INF = float('inf')
mod = int(1000000000.0) + 7

def main():
	n = int(data())
	l = []
	c = [0] * n
	cnt = 0
	for i in range(n):
		(a, b, c) = mdata()
		(t1, t2) = (0, 0)
		if b == 0 and c == 1:
			t1 = 1
			cnt += 1
		elif b == 1 and c == 0:
			t2 = 1
			cnt -= 1
		l.append([i, a, t1, t2])
	if cnt != 0:
		out(-1)
		exit()
	l1 = sorted(l, key=lambda x: x[1])
	g = [set() for i in range(n)]
	for i in range(n - 1):
		(a, b) = mdata()
		g[a - 1].add(b - 1)
		g[b - 1].add(a - 1)
	par = [0] * n
	s = []
	s.append(0)
	vis = [0] * n
	while s:
		a = s.pop()
		vis[a] = 1
		for i in g[a]:
			if vis[i] == 0:
				par[i] = a
				s.append(i)
	vis = [0] * n
	cost = 0
	for i in range(n):
		(j, a, b, c) = l1[i]
		if vis[j] == 1:
			continue
		(t1, t2) = (b, c)
		s = []
		s.append(j)
		while s:
			a1 = s.pop()
			vis[a1] = 1
			for k in g[a1]:
				if vis[k] == 0 and k != par[a1]:
					s.append(k)
					t1 += l[k][2]
					t2 += l[k][3]
				elif vis[k] == 1 and k != par[a1]:
					t1 += l[k][2]
					t2 += l[k][3]
		cost += min(t1, t2) * 2 * a
		if t1 >= t2:
			l1[i][2] = t1 - t2
			l1[i][3] = 0
		else:
			l1[i][2] = 0
			l1[i][3] = t2 - t1
	out(cost)
main()


import sys
from collections import deque
input = sys.stdin.buffer.readline
n = int(input())
node = [tuple(map(int, input().split())) for i in range(n)]
edge = [[] for i in range(n)]
for i in range(n - 1):
	(u, v) = map(int, input().split())
	edge[u - 1].append(v - 1)
	edge[v - 1].append(u - 1)
parent = [-1] * n
unmatch = [[0, 0] for i in range(n)]
used = [False] * n
deq = deque([0])
while deq:
	v = deq.popleft()
	for nv in edge[v]:
		if nv != parent[v]:
			parent[nv] = v
			deq.append(nv)
for v in range(n):
	if node[v][1] != node[v][2]:
		unmatch[v][node[v][1]] += 1
Node = [i for i in range(n)]
Node.sort(key=lambda x: node[x][0])

def bfs(start):
	deq = deque([start])
	ans = []
	while deq:
		v = deq.popleft()
		ans.append(v)
		if used[v]:
			continue
		for nv in edge[v]:
			if nv != parent[v]:
				deq.append(nv)
		used[v] = True
	ans = ans[::-1]
	for pos in ans:
		if pos != start:
			unmatch[start][0] += unmatch[pos][0]
			unmatch[start][1] += unmatch[pos][1]
			unmatch[pos] = [0, 0]
ans = 0
for v in Node:
	if not used[v]:
		bfs(v)
		ans += 2 * node[v][0] * min(unmatch[v][0], unmatch[v][1])
		if unmatch[v][0] > unmatch[v][1]:
			unmatch[v] = [unmatch[v][0] - unmatch[v][1], 0]
		else:
			unmatch[v] = [0, unmatch[v][1] - unmatch[v][0]]
check = all((unmatch[v] == [0, 0] for v in range(n)))
if check:
	print(ans)
else:
	print(-1)


import sys
import threading
input = sys.stdin.readline

def main():
	n = int(input())
	a = [0] * n
	b = [0] * n
	c = [0] * n
	for i in range(n):
		(a[i], b[i], c[i]) = map(int, input().split())
	g = [[] for _ in range(n)]
	for _ in range(n - 1):
		(x, y) = map(int, input().split())
		g[x - 1].append(y - 1)
		g[y - 1].append(x - 1)
	_01 = [0] * n
	_10 = [0] * n

	def dfs(u, p=-1):
		res = 0
		for v in g[u]:
			if v != p:
				a[v] = min(a[v], a[u])
				res += dfs(v, u)
				_01[u] += _01[v]
				_10[u] += _10[v]
		if b[u] != c[u]:
			if b[u] == 0:
				_01[u] += 1
			else:
				_10[u] += 1
		m = min(_01[u], _10[u])
		res += 2 * m * a[u]
		_01[u] -= m
		_10[u] -= m
		return res
	ans = dfs(0)
	print('-1') if _01[0] > 0 or _10[0] > 0 else print(ans)
sys.setrecursionlimit(1 << 30)
threading.stack_size(1 << 27)
main_thread = threading.Thread(target=main)
main_thread.start()
main_thread.join()


import sys
from types import GeneratorType

def bootstrap(func, stack=[]):

	def wrapped_function(*args, **kwargs):
		if stack:
			return func(*args, **kwargs)
		else:
			call = func(*args, **kwargs)
			while True:
				if type(call) is GeneratorType:
					stack.append(call)
					call = next(call)
				else:
					stack.pop()
					if not stack:
						break
					call = stack[-1].send(call)
			return call
	return wrapped_function
Ri = lambda : [int(x) for x in sys.stdin.readline().split()]
ri = lambda : sys.stdin.readline().strip()
cost = 0

@bootstrap
def dfs(cur, par, cho):
	global cost
	w = 0
	b = 0
	for child in g[cur]:
		if child == par:
			continue
		cnt = (0, 0)
		if c[child] > c[cur]:
			c[child] = c[cur]
			cnt = (yield dfs(child, cur, 0))
		else:
			cnt = (yield dfs(child, cur, 1))
		w += cnt[0]
		b += cnt[1]
	if ini[cur] != fin[cur]:
		if fin[cur] == 1:
			b += 1
		else:
			w += 1
	minn = 0
	if cho == 1:
		minn = min(b, w)
		cost += minn * 2 * c[cur]
	yield (w - minn, b - minn)
n = int(ri())
c = [0] * (n + 1)
ini = [0] * (n + 1)
fin = [0] * (n + 1)
for i in range(1, n + 1):
	(c[i], ini[i], fin[i]) = Ri()
g = [[] for i in range(n + 1)]
for i in range(n - 1):
	(a, b) = Ri()
	g[a].append(b)
	g[b].append(a)
ans = dfs(1, -1, 1)
if ans[0] != ans[1]:
	print(-1)
else:
	print(cost)


from sys import stdin
from collections import namedtuple, deque
Node = namedtuple('Node', ['a', 'b', 'c'])
n = int(stdin.readline().strip())
N = {}
for i in range(1, n + 1):
	N[i] = Node(*map(int, stdin.readline().split()))
T = {}
T[1] = set()
for _ in range(n - 1):
	(u, v) = map(int, stdin.readline().split())
	T.setdefault(u, set()).add(v)
	T.setdefault(v, set()).add(u)
q = deque([(0, 1, 0, N[1].a)])
R = {}
M = 0
while q:
	(f, u, p, m) = q.pop()
	if f == 0:
		R[u] = [0, 0]
		m = min(m, N[u].a)
		q.append((1, u, p, m))
		for v in T[u]:
			if v == p:
				continue
			q.append((0, v, u, m))
	else:
		if N[u].b != N[u].c:
			R[u][N[u].c] += 1
		if R[u][0] and R[u][1]:
			d = min(R[u][0], R[u][1])
			(R[u][0], R[u][1]) = (R[u][0] - d, R[u][1] - d)
			M += d * 2 * m
		if p != 0:
			R[p][0] += R[u][0]
			R[p][1] += R[u][1]
if R[1][0] or R[1][1]:
	M = -1
print(M)


import sys
from types import GeneratorType
input = sys.stdin.readline

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

def main():
	n = int(input())
	a = [0] * n
	b = [0] * n
	c = [0] * n
	for i in range(n):
		(a[i], b[i], c[i]) = map(int, input().split())
	g = [[] for _ in range(n)]
	for _ in range(n - 1):
		(x, y) = map(int, input().split())
		g[x - 1].append(y - 1)
		g[y - 1].append(x - 1)
	_01 = [0] * n
	_10 = [0] * n
	ans = 0

	@bootstrap
	def dfs(u, p=-1):
		for v in g[u]:
			if v != p:
				a[v] = min(a[v], a[u])
				yield dfs(v, u)
				_01[u] += _01[v]
				_10[u] += _10[v]
		if b[u] != c[u]:
			if b[u] == 0:
				_01[u] += 1
			else:
				_10[u] += 1
		m = min(_01[u], _10[u])
		nonlocal ans
		ans += 2 * m * a[u]
		_01[u] -= m
		_10[u] -= m
		yield 0
	dfs(0)
	print('-1') if _01[0] > 0 or _10[0] > 0 else print(ans)
main()


from collections import defaultdict
import sys, math
f = None
try:
	f = open('q1.input', 'r')
except IOError:
	f = sys.stdin
if 'xrange' in dir(__builtins__):
	range = xrange

def print_case_iterable(case_num, iterable):
	print('Case #{}: {}'.format(case_num, ' '.join(map(str, iterable))))

def print_case_number(case_num, iterable):
	print('Case #{}: {}'.format(case_num, iterable))

def print_iterable(A):
	print(' '.join(A))

def read_int():
	return int(f.readline().strip())

def read_int_array():
	return [int(x) for x in f.readline().strip().split(' ')]

def rns():
	a = [x for x in f.readline().split(' ')]
	return (int(a[0]), a[1].strip())

def read_string():
	return list(f.readline().strip())

def bi(x):
	return bin(x)[2:]
from collections import deque
import math
from collections import deque, defaultdict
import heapq
from sys import stdout
import threading
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

@bootstrap
def dfs(v, adj, curr_min, visited, data, res):
	visited[v] = True
	curr_min = min(curr_min, data[v][0])
	balance = data[v][2] - data[v][1]
	total = abs(balance)
	for u in adj[v]:
		if visited[u]:
			continue
		zeros = (yield dfs(u, adj, curr_min, visited, data, res))
		balance += zeros
		total += abs(zeros)
	res[0] += curr_min * (total - abs(balance))
	yield balance

def solution(n, data, adj):
	visited = [False] * (n + 1)
	res = [0]
	balance = dfs(1, adj, 10 ** 10, visited, data, res)
	if balance == 0:
		return res[0]
	return -1

def main():
	T = 1
	for i in range(T):
		n = read_int()
		adj = defaultdict(list)
		data = [0]
		for j in range(n):
			data.append(read_int_array())
		for j in range(n - 1):
			(u, v) = read_int_array()
			adj[u].append(v)
			adj[v].append(u)
		x = solution(n, data, adj)
		if 'xrange' not in dir(__builtins__):
			print(x)
		else:
			(print >> output, str(x))
	if 'xrange' in dir(__builtins__):
		print(output.getvalue())
		output.close()
	stdout.flush()
if 'xrange' in dir(__builtins__):
	import cStringIO
	output = cStringIO.StringIO()
threading.stack_size(10 ** 8)
main()


import sys
from collections import deque
N = int(sys.stdin.readline())
(A, B, C) = ([], [], [])
(bd, cd) = (0, 0)
for i in range(N):
	(a, b, c) = [int(_) for _ in sys.stdin.readline().split()]
	A.append(a)
	B.append(b)
	C.append(c)
	if b == 0 and c == 1:
		bd += 1
	elif c == 0 and b == 1:
		cd += 1
edges = [[] for _ in range(N)]
for i in range(N - 1):
	(u, v) = [int(_) for _ in sys.stdin.readline().split()]
	edges[u - 1].append(v - 1)
	edges[v - 1].append(u - 1)
if bd != cd:
	print(-1)
	sys.exit(0)
costs = [-1] * N
parents = [None] * N
D = [0] * N
nodes_per_dist = [[] for _ in range(N)]

def dfs(costs, edges, node, curr, dist):
	costs[node] = min(curr, A[node])
	nodes_per_dist[dist].append(node)
	for neighbour in edges[node]:
		if costs[neighbour] == -1:
			parents[neighbour] = node
			dfs(costs, edges, neighbour, costs[node], dist + 1)

def bfs(costs, edges, node, ordered_nodes):
	Q = deque()
	Q.append(node)
	D = [0] * len(edges)
	nodes_per_dist[0].append(node)
	while Q:
		el = Q.popleft()
		ordered_nodes.append(el)
		if parents[el] is not None:
			costs[el] = min(A[el], costs[parents[el]])
		else:
			costs[el] = A[el]
		for n in edges[el]:
			if costs[n] == -1:
				Q.append(n)
				D[n] = D[el] + 1
				nodes_per_dist[D[n]].append(n)
				parents[n] = el
ordered_nodes = []
bfs(costs, edges, 0, ordered_nodes)
ninfos = [(0, 0) for _ in range(N)]
answer = 0
for i in range(len(ordered_nodes) - 1, -1, -1):
	leaf = ordered_nodes[i]
	ninfo = ninfos[leaf]
	if B[leaf] == 0 and C[leaf] == 1:
		ninfos[leaf] = (ninfo[0] + 1, ninfo[1])
	elif B[leaf] == 1 and C[leaf] == 0:
		ninfos[leaf] = (ninfo[0], ninfo[1] + 1)
	swap = min(ninfos[leaf][0], ninfos[leaf][1])
	answer += swap * 2 * costs[leaf]
	parent = parents[leaf]
	if parent is not None:
		ninfos[parent] = (ninfos[parent][0] + ninfos[leaf][0] - swap, ninfos[parent][1] + ninfos[leaf][1] - swap)
print(answer)


from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		to = f(*args, **kwargs)
		if stack:
			return to
		else:
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						return to
					to = stack[-1].send(to)
	return wrappedfunc
import sys
input = sys.stdin.readline
from collections import defaultdict as dd

@bootstrap
def dfs(cur, prev, d, typ, val, ans):
	if prev != 0:
		val[cur] = min(val[cur], val[prev])
	for i in d[cur]:
		if i != prev:
			yield dfs(i, cur, d, typ, val, ans)
	for i in d[cur]:
		if i != prev:
			typ[cur][0] += typ[i][0]
			typ[cur][1] += typ[i][1]
	mi = min(typ[cur][0], typ[cur][1])
	ans[0] += val[cur] * mi * 2
	typ[cur][0] -= mi
	typ[cur][1] -= mi
	yield
n = int(input())
typ = [[0] * 2 for i in range(n + 1)]
val = [0] * (n + 1)
co1 = 0
co2 = 0
for i in range(1, n + 1):
	(va, a, b) = map(int, input().split())
	if a < b:
		typ[i][0] = 1
		co1 += 1
	elif a > b:
		typ[i][1] = 1
		co2 += 1
	val[i] = va
d = dd(list)
for i in range(n - 1):
	(u, v) = map(int, input().split())
	d[u].append(v)
	d[v].append(u)
ans = [0]
dfs(1, 0, d, typ, val, ans)
if co1 != co2:
	print(-1)
else:
	print(ans[0])


import sys
input = sys.stdin.readline
from collections import deque
n = int(input())
type1 = 0
type2 = 0
ret = [None]
for _ in range(n):
	new = []
	(a, b, c) = map(int, input().split())
	new.append(a)
	if b == c:
		new.append(0)
		new.append(0)
	elif b == 0:
		new.append(1)
		new.append(0)
		type1 += 1
	elif b == 1:
		new.append(0)
		new.append(1)
		type2 += 1
	ret.append(new)
if type1 != type2:
	print(-1)
	exit()
adj_list = [[] for i in range(n + 1)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	adj_list[a].append(b)
	adj_list[b].append(a)
xir = [0 for i in range(n + 1)]
s = deque()
s.append(1)
foh = 0
prev = 0
while s:
	curr = s[-1]
	had_eyr = False
	if adj_list[curr]:
		eyr = adj_list[curr].pop()
		if eyr == xir[curr]:
			if adj_list[curr]:
				eyr = adj_list[curr].pop()
				had_eyr = True
		else:
			had_eyr = True
	if had_eyr:
		ret[eyr][0] = min(ret[eyr][0], ret[curr][0])
		xir[eyr] = curr
		s.append(eyr)
	else:
		type1 = ret[curr][1]
		type2 = ret[curr][2]
		if type1 > type2:
			paired = type2
			foh += 2 * paired * ret[curr][0]
			ugh = type1 - paired
			s.pop()
			if s:
				ret[s[-1]][1] += ugh
		else:
			paired = type1
			foh += 2 * paired * ret[curr][0]
			ugh = type2 - paired
			s.pop()
			if s:
				ret[s[-1]][2] += ugh
print(foh)


import sys
input = sys.stdin.readline

def buildGraph(n, arr):
	graph = []
	for _ in range(n):
		graph.append([])
	for x in arr:
		(u, v) = map(int, x.split(' '))
		(u, v) = (u - 1, v - 1)
		graph[u].append(v)
		graph[v].append(u)
	return graph

def buildCostArr(arr, n):
	cost = [0] * n
	shuff = [0] * n
	s_01 = 0
	s_10 = 0
	for (i, x) in enumerate(arr):
		(a, b, c) = map(int, x.split(' '))
		cost[i] = a
		if b == 0 and c == 1:
			shuff[i] = 1
			s_01 += 1
		elif b == 1 and c == 0:
			shuff[i] = -1
			s_10 += 1
	return (cost, shuff, s_01, s_10)

def optimizeCost(graph, cost, p, i, nodes):
	nodes.append(i)
	if len(graph[i]) > 1 or i == 0:
		for c in graph[i]:
			if c != p[i]:
				p[c] = i
				if cost[i] < cost[c]:
					cost[c] = cost[i]
				optimizeCost(graph, cost, p, c, nodes)
n = int(input())
arr = []
for _ in range(n):
	arr.append(input())
buildArr = buildCostArr(arr, n)
cost = buildArr[0]
y = buildArr[1]
s_01 = buildArr[2]
s_10 = buildArr[3]
if s_01 != s_10:
	print(-1)
else:
	arr = []
	for _ in range(n - 1):
		arr.append(input())
	p = [-1] * n
	graph = buildGraph(n, arr)
	nodes = []
	ans = 0
	q = [0]
	while len(q) > 0:
		now = q.pop(-1)
		nodes.append(now)
		for c in graph[now]:
			if c != p[now]:
				p[c] = now
				if cost[now] < cost[c]:
					cost[c] = cost[now]
				q.append(c)
	for i in nodes[::-1]:
		if y[i] * y[p[i]] < 0:
			ans += cost[p[i]] * min(abs(y[p[i]]), abs(y[i]))
		y[p[i]] += y[i]
	print(ans * 2)


import sys
input = sys.stdin.buffer.readline
n = int(input())
cost = [0 for _ in range(n + 1)]
typee = [-1 for _ in range(n + 1)]
edges = dict()
type0Total = 0
type1Total = 0
for i in range(n):
	(cost_, before, after) = [int(x) for x in input().split()]
	cost[i + 1] = cost_
	if before == 0 and after == 1:
		typee[i + 1] = 0
		type0Total += 1
	elif before == 1 and after == 0:
		typee[i + 1] = 1
		type1Total += 1
	edges[i + 1] = []
for _ in range(n - 1):
	(a, b) = [int(x) for x in input().split()]
	edges[a].append(b)
	edges[b].append(a)
if type0Total != type1Total:
	print(-1)
else:
	depthOfNodes = dict()
	stack = [[1, -1, 1]]
	while stack:
		(node, parent, depth) = stack.pop()
		if depth not in depthOfNodes.keys():
			depthOfNodes[depth] = []
		depthOfNodes[depth].append(node)
		if parent != -1:
			cost[node] = min(cost[node], cost[parent])
			edges[node].remove(parent)
		for child in edges[node]:
			stack.append([child, node, depth + 1])
	remainingTypesUnder = [[0, 0] for _ in range(n + 1)]
	accumulatedCosts = [0 for _ in range(n + 1)]
	deepest = max(depthOfNodes.keys())
	for node in depthOfNodes[deepest]:
		if typee[node] == 0:
			remainingTypesUnder[node][0] += 1
		elif typee[node] == 1:
			remainingTypesUnder[node][1] += 1
	for depth in range(deepest - 1, 0, -1):
		for node in depthOfNodes[depth]:
			accumCosts = 0
			accumType0 = 0
			accumType1 = 0
			if typee[node] == 0:
				accumType0 += 1
			elif typee[node] == 1:
				accumType1 += 1
			for child in edges[node]:
				accumCosts += accumulatedCosts[child]
				accumType0 += remainingTypesUnder[child][0]
				accumType1 += remainingTypesUnder[child][1]
			maxChildNodesToNeutralize = min(accumType0, accumType1)
			accumCosts += cost[node] * maxChildNodesToNeutralize * 2
			accumType0 -= maxChildNodesToNeutralize
			accumType1 -= maxChildNodesToNeutralize
			remainingTypesUnder[node] = [accumType0, accumType1]
			accumulatedCosts[node] = accumCosts
	print(accumulatedCosts[1])


from collections import defaultdict, deque
import sys
input = sys.stdin.buffer.readline

class Graph:

	def __init__(self, nVertices, graphArr):
		self.graph = defaultdict(list)
		for (u, v) in graphArr:
			self.graph[u].append(v)
		self.V = nVertices

	def topologicalSort(self):
		in_degree = [0] * self.V
		for i in self.graph:
			for j in self.graph[i]:
				in_degree[j] += 1
		queue = deque()
		for i in range(self.V):
			if in_degree[i] == 0:
				queue.append(i)
		cnt = 0
		top_order = []
		while queue:
			u = queue.popleft()
			top_order.append(u)
			for i in self.graph[u]:
				in_degree[i] -= 1
				if in_degree[i] == 0:
					queue.append(i)
			cnt += 1
		if cnt != self.V:
			return []
		else:
			return top_order
n = int(input())
a = [0 for _ in range(n + 1)]
b = [0 for _ in range(n + 1)]
c = [0 for _ in range(n + 1)]
for i in range(n):
	(a[i + 1], b[i + 1], c[i + 1]) = [int(x) for x in input().split()]
edges = [[] for _ in range(n + 1)]
for _ in range(n - 1):
	(u, v) = [int(x) for x in input().split()]
	edges[u].append(v)
	edges[v].append(u)
a[0] = 99999999999999999
parent = [0 for _ in range(n + 1)]
dfs = [[1, 0]]
while dfs:
	(node, par) = dfs.pop()
	a[node] = min(a[node], a[par])
	parent[node] = par
	children = [x for x in edges[node] if x != par]
	for child in children:
		dfs.append([child, node])
graphArr = []
for node in range(2, n + 1):
	graphArr.append([node - 1, parent[node] - 1])
g = Graph(n, graphArr)
leafToRootSort = g.topologicalSort()
for i in range(len(leafToRootSort)):
	leafToRootSort[i] += 1
wrong0s = [0 for _ in range(n + 1)]
wrong1s = [0 for _ in range(n + 1)]
accumCosts = [0 for _ in range(n + 1)]
for node in leafToRootSort:
	if b[node] == 0 and c[node] == 1:
		wrong0s[node] += 1
	elif b[node] == 1 and c[node] == 0:
		wrong1s[node] += 1
	change = min(wrong0s[node], wrong1s[node])
	accumCosts[node] += change * 2 * a[node]
	wrong0s[node] -= change
	wrong1s[node] -= change
	par = parent[node]
	accumCosts[par] += accumCosts[node]
	wrong0s[par] += wrong0s[node]
	wrong1s[par] += wrong1s[node]
if wrong0s[1] != 0 or wrong1s[1] != 0:
	print(-1)
else:
	print(accumCosts[1])


from collections import deque
from sys import stdin, stdout
int_in = lambda : int(stdin.readline())
arr_in = lambda : [int(x) for x in stdin.readline().split()]
mat_in = lambda rows: [arr_in() for y in range(rows)]
str_in = lambda : stdin.readline().strip()
out = lambda o: stdout.write('{}\n'.format(o))
arr_out = lambda o: out(' '.join(map(str, o)))
bool_out = lambda o: out('YES' if o else 'NO')
tests = lambda : range(1, int_in() + 1)
case_out = lambda i, o: out('Case #{}: {}'.format(i, o))

def solve(n, abcs, edges):
	if n == 1:
		if abcs[0][1] != abcs[0][2]:
			return -1
		return 0
	if sum(map(lambda x: x[1] == 1, abcs)) != sum(map(lambda x: x[2] == 1, abcs)):
		return -1
	neighbors = {}
	for edge in edges:
		if edge[0] not in neighbors:
			neighbors[edge[0]] = []
		if edge[1] not in neighbors:
			neighbors[edge[1]] = []
		neighbors[edge[0]].append(edge[1])
		neighbors[edge[1]].append(edge[0])
	best_swap_costs = {}
	bfs = deque([(1, abcs[0][0])])
	visited = set()
	parents = {}
	process_stack = deque()
	while len(bfs) > 0:
		curr = bfs.popleft()
		visited.add(curr[0])
		best_swap_costs[curr[0]] = curr[1]
		process_stack.append(curr[0])
		for neighbor in neighbors[curr[0]]:
			if neighbor not in visited:
				bfs.append((neighbor, min(curr[1], abcs[neighbor - 1][0])))
				parents[neighbor] = curr[0]
	result = 0
	stuff = {}
	while len(process_stack) > 0:
		curr = process_stack.pop()
		if curr not in stuff:
			stuff[curr] = [0, 0]
		if curr in parents and parents[curr] not in stuff:
			stuff[parents[curr]] = [0, 0]
		if abcs[curr - 1][1] != abcs[curr - 1][2]:
			if abcs[curr - 1][1] == 1:
				stuff[curr][0] += 1
			else:
				stuff[curr][1] += 1
		resolve = min(stuff[curr])
		if resolve > 0:
			result += 2 * resolve * best_swap_costs[curr]
			stuff[curr][0] -= resolve
			stuff[curr][1] -= resolve
		if sum(stuff[curr]) > 0:
			if curr not in parents:
				return -1
			stuff[parents[curr]][0] += stuff[curr][0]
			stuff[parents[curr]][1] += stuff[curr][1]
	return result
n = int_in()
abcs = mat_in(n)
edges = mat_in(n - 1)
out(solve(n, abcs, edges))


import sys
input = sys.stdin.readline
N = int(input())
As = []
B = []
C = []
for i in range(N):
	(a, b, c) = map(int, input().split())
	As.append((a, i))
	B.append(b)
	C.append(c)
graph = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	graph[a - 1].append(b - 1)
	graph[b - 1].append(a - 1)
Graph = [[] for _ in range(N)]
checked = [False] * N
checked[0] = True
q = [0]
while q:
	qq = []
	for p in q:
		for np in graph[p]:
			if not checked[np]:
				checked[np] = True
				qq.append(np)
				Graph[p].append(np)
	q = qq
As.sort()
already = [False] * N
remain = [0] * N
ans = 0
for (a, node) in As:
	if already[node]:
		continue
	q = [node]
	already[node] = True
	Balance = [0, 0, 0]
	Balance[C[node] - B[node]] += 1
	while q:
		qq = []
		for p in q:
			for np in Graph[p]:
				if already[np]:
					if remain[np] > 0:
						Balance[1] += remain[np]
					elif remain[np] < 0:
						Balance[-1] += -remain[np]
				else:
					qq.append(np)
					already[np] = True
					Balance[C[np] - B[np]] += 1
		q = qq
	if Balance[1] >= Balance[-1]:
		ans += 2 * a * Balance[-1]
		remain[node] = Balance[1] - Balance[-1]
	else:
		ans += 2 * a * Balance[1]
		remain[node] = -Balance[-1] + Balance[1]
if remain[0] != 0:
	print(-1)
else:
	print(ans)


from collections import defaultdict
import sys, math
f = None
try:
	f = open('q1.input', 'r')
except IOError:
	f = sys.stdin
if 'xrange' in dir(__builtins__):
	range = xrange
sys.setrecursionlimit(10 ** 2)

def print_case_iterable(case_num, iterable):
	print('Case #{}: {}'.format(case_num, ' '.join(map(str, iterable))))

def print_case_number(case_num, iterable):
	print('Case #{}: {}'.format(case_num, iterable))

def print_iterable(A):
	print(' '.join(A))

def read_int():
	return int(f.readline().strip())

def read_int_array():
	return [int(x) for x in f.readline().strip().split(' ')]

def rns():
	a = [x for x in f.readline().split(' ')]
	return (int(a[0]), a[1].strip())

def read_string():
	return list(f.readline().strip())

def bi(x):
	return bin(x)[2:]
from collections import deque
import math
NUMBER = 10 ** 9 + 7

def factorial(n):
	M = NUMBER
	f = 1
	for i in range(1, n + 1):
		f = f * i % M
	return f

def mult(a, b):
	return a * b % NUMBER

def minus(a, b):
	return (a - b) % NUMBER

def plus(a, b):
	return (a + b) % NUMBER

def egcd(a, b):
	if a == 0:
		return (b, 0, 1)
	else:
		(g, y, x) = egcd(b % a, a)
		return (g, x - b // a * y, y)

def modinv(a):
	m = NUMBER
	(g, x, y) = egcd(a, m)
	if g != 1:
		raise Exception('modular inverse does not exist')
	else:
		return x % m

def choose(n, k):
	if n < k:
		assert false
	return mult(factorial(n), modinv(mult(factorial(k), factorial(n - k))))
from collections import deque, defaultdict
import heapq

def is_leaf(v, adj):
	return len(adj[v]) == 1

def dfs(v, adj, curr_min, visited, data):
	stack = [[v, data[v][0], data[v][2] - data[v][1], abs(data[v][2] - data[v][1]), 0]]
	res = 0
	balance = 0
	while stack:
		(v, curr_min, curr_balance, curr_total, neig_i) = stack[-1]
		curr_min = min(curr_min, data[v][0])
		stack[-1][1] = curr_min
		visited[v] = True
		if neig_i == 0:
			balance = curr_balance
			total = curr_total
		else:
			curr_balance += balance
			curr_total += abs(balance)
			stack[-1][2] = curr_balance
			stack[-1][3] = curr_total
		while neig_i < len(adj[v]):
			u = adj[v][neig_i]
			if visited[u]:
				neig_i += 1
				continue
			stack[-1][4] = neig_i + 1
			stack.append([u, min(curr_min, data[u][0]), data[u][2] - data[u][1], abs(data[u][2] - data[u][1]), 0])
			break
		if neig_i == len(adj[v]):
			stack.pop()
			res += curr_min * (curr_total - abs(curr_balance))
		balance = curr_balance
	if balance == 0:
		return res
	return -1

def solution(n, data, adj):
	visited = [False] * (n + 1)
	return dfs(1, adj, 10 ** 10, visited, data)

def main():
	T = 1
	for i in range(T):
		n = read_int()
		adj = defaultdict(list)
		data = [0]
		for j in range(n):
			data.append(read_int_array())
		for j in range(n - 1):
			(u, v) = read_int_array()
			adj[u].append(v)
			adj[v].append(u)
		x = solution(n, data, adj)
		if 'xrange' not in dir(__builtins__):
			print(x)
		else:
			(print >> output, str(x))
	if 'xrange' in dir(__builtins__):
		print(output.getvalue())
		output.close()
if 'xrange' in dir(__builtins__):
	import cStringIO
	output = cStringIO.StringIO()
main()


from __future__ import division, print_function
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

@bootstrap
def dfs(x, y):
	global ch, l1, l, adj, ans, v
	v[x] = 1
	l1[x] = min(l1[y], l[x])
	l2 = ch[x]
	for i in adj[x]:
		if not v[i]:
			ll = (yield dfs(i, x))
			l2[0] += ll[0]
			l2[1] += ll[1]
	ans += l1[x] * min(l2) * 2
	if l2[0] > l2[1]:
		yield [l2[0] - l2[1], 0]
	else:
		yield [0, l2[1] - l2[0]]
import os
import sys
from io import BytesIO, IOBase
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')
n = int(input())
v = [0] * (n + 1)
ch = [0] * (n + 1)
inf = 10 ** 9
adj = [[] for i in range(n + 1)]
l = [0] * (n + 1)
l1 = [inf] * (n + 1)
ans = 0
(t1, t2) = (0, 0)
for i in range(n):
	(a, b, c) = map(int, input().split())
	l[i + 1] = a
	if b == 0 and c == 1:
		ch[i + 1] = [1, 0]
		t1 += 1
	elif b == 1 and c == 0:
		ch[i + 1] = [0, 1]
		t2 += 1
	else:
		ch[i + 1] = [0, 0]
l1[0] = l[1]
for i in range(n - 1):
	(x, y) = map(int, input().split())
	adj[x].append(y)
	adj[y].append(x)
if t1 != t2:
	print(-1)
else:
	dfs(1, 0)
	print(ans)