Problem:
Score : 1900 points

Problem Statement

There is a tree with N vertices.
The vertices are numbered 1 through N.
For each 1 ≤ i ≤ N - 1, the i-th edge connects vertices a_i and b_i.
The lengths of all the edges are 1.

Snuke likes some of the vertices.
The information on his favorite vertices are given to you as a string s of length N.
For each 1 ≤ i ≤ N, s_i is 1 if Snuke likes vertex i, and 0 if he does not like vertex i.

Initially, all the vertices are white.
Snuke will perform the following operation exactly once:

Select a vertex v that he likes, and a non-negative integer d. Then, paint all the vertices black whose distances from v are at most d.

Find the number of the possible combinations of colors of the vertices after the operation.

Constraints

2 ≤ N ≤ 2×10^5

1 ≤ a_i, b_i ≤ N

The given graph is a tree.

|s| = N

s consists of 0 and 1.

s contains at least one occurrence of 1.

Partial Score

In the test set worth 1300 points, s consists only of 1.

Input

The input is given from Standard Input in the following format:

N
a_1 b_1
a_2 b_2
:
a_{N - 1} b_{N - 1}
s

Output

Print the number of the possible combinations of colors of the vertices after the operation.

Sample Input 1

4
1 2
1 3
1 4
1100

Sample Output 1

4

The following four combinations of colors of the vertices are possible:

Sample Input 2

5
1 2
1 3
1 4
4 5
11111

Sample Output 2

11

This case satisfies the additional constraint for the partial score.

Sample Input 3

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

Sample Output 3

8

Solution in C++ (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>

using namespace std;

int read() {
  int res = 0; char c = getchar();
  while(!isdigit(c)) c = getchar();
  while(isdigit(c)) res = res * 10 + c - '0', c = getchar();
  return res;
}

void read(char *S) {
  char *s = S, c = getchar();
  while(c != '0' && c != '1') c = getchar();
  while(c == '0' || c == '1') *s = c, s++, c = getchar();
}

typedef long long ll;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;

int head[maxn], nxt[maxn << 1], to[maxn << 1], e_cnt;
void link(int u, int v) {
  nxt[++e_cnt] = head[u], head[u] = e_cnt, to[e_cnt] = v;
  nxt[++e_cnt] = head[v], head[v] = e_cnt, to[e_cnt] = u;
}

int mx[maxn], se[maxn], d[maxn], sz[maxn], n;
char S[maxn];
long long Ans;

void dfs_1(int x, int fa) {
  if(S[x] == '1') d[x] = 0, sz[x] = 1;
  else d[x] = inf;
  for(int i = head[x]; i; i = nxt[i]) {
    int y = to[i];
    if(y == fa) continue;
    dfs_1(y, x), sz[x] += sz[y];
    if(mx[y] + 1 > mx[x]) se[x] = mx[x], mx[x] = mx[y] + 1;
    else if(mx[y] + 1 > se[x]) se[x] = mx[y] + 1;
    if(sz[y]) d[x] = min(d[x], mx[y] + 1);
  }
}

void dfs_2(int x, int fa) {
  int R = min(se[x] + 1, mx[x] - 1);
  if(d[x] <= R) Ans += 1LL * (R - d[x] + 1);
  for(int i = head[x]; i; i = nxt[i]) {
    int y = to[i];
    if(y == fa) continue;
    int kl = (mx[y] + 1 == mx[x] ? se[x] + 1 : mx[x] + 1);
    if(kl > mx[y]) se[y] = mx[y], mx[y] = kl;
    else if(kl > se[y]) se[y] = kl;
    if(sz[1] - sz[y]) d[y] = min(d[y], kl);
    dfs_2(y, x);
  }
}

int main() {
  n = read();
  for(int i = 2; i <= n; i++) link(read(), read());
  read(S + 1);
  dfs_1(1, 0);
  dfs_2(1, 0);
  printf("%lld\n", Ans + 1);
}