#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void amin(T &x, const T &y) {
  if (y < x) x = y;
}
template <class T>
inline void amax(T &x, const T &y) {
  if (x < y) x = y;
}
template <class Iter>
void rprintf(const char *fmt, Iter begin, Iter end) {
  for (bool sp = 0; begin != end; ++begin) {
    if (sp)
      putchar(' ');
    else
      sp = true;
    printf(fmt, *begin);
  }
  putchar('\n');
}
struct Seg {
  bool fav;
  int height;
  Seg() {
    fav = false;
    height = -1;
  }
  Seg inc(bool fav_) const {
    Seg z = *this;
    z.fav = z.fav || fav_;
    z.height++;
    return z;
  }
};
Seg operator+(const Seg &x, const Seg &y) {
  Seg z;
  z.fav = x.fav || y.fav;
  z.height = max(x.height, y.height);
  return z;
}
const int MAXN = 200111;
int N;
vector<int> G[MAXN];
vector<int> ord;
char S[MAXN];
Seg up[MAXN], dw[MAXN];
vector<Seg> L[MAXN], R[MAXN];
long long answer;
void treeDP() {
  ord.clear();
  ord.reserve(N);
  ord.push_back(0);
  for (int i_ = 0, i__len = (N); i_ < i__len; ++i_) {
    int v = ord[i_];
    for (__typeof((G[v]).begin()) e = (G[v]).begin(), e_end = (G[v]).end();
         e != e_end; ++e) {
      ord.push_back(*e);
      G[*e].erase(remove(G[*e].begin(), G[*e].end(), v), G[*e].end());
    }
  }
  for (int i_ = 0, i__len = (N); i_ < i__len; ++i_) {
    int v = ord[N - 1 - i_];
    int m = G[v].size();
    L[v].assign(m + 1, Seg());
    R[v].assign(m + 1, Seg());
    for (int i = 0, i_len = (m); i < i_len; ++i)
      L[v][i + 1] = L[v][i] + up[G[v][i]];
    for (int i = m; i--;) R[v][i] = up[G[v][i]] + R[v][i + 1];
    up[v] = R[v][0].inc(S[v] == '1');
  }
  const int INF = 1 << 29;
  dw[0] = Seg();
  for (int i_ = 0, i__len = (N); i_ < i__len; ++i_) {
    int v = ord[i_];
    int lo = INF, hi[3] = {};
    auto update = [&](int h) {
      hi[2] = h;
      if (hi[1] < hi[2]) swap(hi[1], hi[2]);
      if (hi[0] < hi[1]) swap(hi[0], hi[1]);
    };
    if (S[v] == '1') {
      amin(lo, 0);
    }
    if (v) {
      if (dw[v].fav) amin(lo, dw[v].height + 1);
      update(dw[v].height + 1);
      if (dw[v].height <= up[v].height && dw[v].fav) {
        answer++;
      } else if (dw[v].height >= up[v].height && up[v].fav) {
        answer++;
      }
    }
    for (int i = 0, i_len = (G[v].size()); i < i_len; ++i) {
      int w = G[v][i];
      if (up[v].fav) amin(lo, up[w].height + 1);
      update(up[w].height + 1);
    }
    if (lo <= hi[1]) {
      answer += hi[1] - lo + 1;
    }
    for (int i = 0, i_len = (G[v].size()); i < i_len; ++i) {
      int w = G[v][i];
      dw[w] = (R[v][i + 1] + dw[v] + L[v][i]).inc(S[v] == '1');
    }
  }
}
void MAIN() {
  scanf("%d", &N);
  for (int i = 0, i_len = (N - 1); i < i_len; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    x--;
    y--;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  scanf("%s", S);
  treeDP();
  printf("%lld\n", answer);
}
int main() {
  int TC = 1;
  for (int tc = 0, tc_len = (TC); tc < tc_len; ++tc) MAIN();
  return 0;
}
