from types import GeneratorType def bootstrap(f, stack=[]): def wrappedfunc(*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) else: stack.pop() if not stack: break to = stack[-1].send(to) return to return wrappedfunc class BIT: def __init__(self, A): self.size = len(A) self.bit = [0]*(len(A)+1) for i in range(len(A)): self.add(i, A[i]) def sum(self, i): i += 1 ans = 0 while i > 0: ans += self.bit[i] i -= -i&i return ans def query(self, l, r): if l == 0: return self.sum(r-1) else: return self.sum(r-1)-self.sum(l-1) def add(self, i, x): i += 1 while i <= self.size: self.bit[i] += x i += -i&i N = int(input()) G = [[] for _ in range(N)] for _ 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 = input() @bootstrap def get_size(n, p, b): if S[n] == "1": b += 1 else: b -= 1 B[n] = b for v in G[n]: if v == p: continue yield get_size(v, n, b) size[n] += size[v] yield size = [1]*N B = [0]*N get_size(0, -1, 0) @bootstrap def dfs(n, p, keep): MAX, bigv = -1, -1 for v in G[n]: if v == p: continue if MAX < size[v]: MAX = size[v] bigv = v for v in G[n]: if v == p or v == bigv: continue yield dfs(v, n, 0) if bigv != -1: yield dfs(bigv, n, 1) A[n] = A[bigv] A[n].append(n) if S[n] == "1": SUM = F.query(N+B[n], N*2+5)+1 else: SUM = F.query(N+B[n]+2, N*2+5) F.add(N+B[n], 1) for v in G[n]: if v == p or v == bigv: continue for x in A[v]: now = B[x]-B[n] if S[n] == "1": SUM += F.query(N+B[n]-now, N*2+5) else: SUM += F.query(N+B[n]-now+2, N*2+5) A[n].append(x) for x in A[v]: F.add(N+B[x], 1) ans[n] = SUM if keep == 0: for v in A[n]: F.add(N+B[v], -1) yield A = [[] for _ in range(N)] F = BIT([0]*(N*2+5)) ans = [-1]*N dfs(0, -1, 0) print(sum(ans))