#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<

typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second

const int MAX = 1<<18;

int dist_down[MAX], dist_up[MAX];
vector <int> V[MAX];
vector <int> Ld[MAX], Rd[MAX];
int poz_par[MAX], par[MAX];
char s[MAX];

void dfs_down(int node, int pr)
{
  par[node] = pr;
  for (auto it = V[node].begin(); it != V[node].end(); it++)
    if (*it == pr) {
      V[node].erase(it);
      break;
    }

  Ld[node].push_back(0);  
  for (auto it : V[node]) {
    dfs_down(it, node);
    poz_par[it] = (int) Ld[node].size();
    Ld[node].push_back(max(Ld[node].back(), dist_down[it] + 1));
  }
  dist_down[node] = Ld[node].back();

  Rd[node].push_back(0);
  for (int i=(int) V[node].size()-1; i>=0; i--) {
    int it = V[node][i];
    Rd[node].push_back(max(Rd[node].back(), dist_down[it] + 1));
  }

  reverse(Rd[node].begin(), Rd[node].end());    
}

P presjek(P a, P b)
{
  return P(max(a.X, b.X), min(a.Y, b.Y));
}

P unija(P a, P b)
{
  if (a.X > a.Y) return b;
  if (b.X > b.Y) return a;
  P tmp = presjek(a, b);
  assert(tmp.X - 1 <= tmp.Y);
  return P(min(a.X, b.X), max(a.Y, b.Y));
}

P razlika(P a, P b)
{
  P tmp = presjek(a, b);
  if (tmp.X > tmp.Y) return a;
  assert(tmp.Y == a.Y || tmp.X == a.X);
  if (tmp.Y == a.Y) return P(a.X, tmp.X - 1);
  return P(tmp.Y + 1, a.Y);
}

P un[MAX];

ll rje = 0;
void dfs_up(int node, int pr)
{  
  if (pr != -1) {
    dist_up[node] = 1 + max(dist_up[pr],
			    max(Ld[pr][poz_par[node]-1], Rd[pr][poz_par[node]]));
  }    

  //  if (node+1 == 6)
    //    printf("UNPAR %d %d\n", un[pr].X, un[pr].Y);

  if (pr != -1) {
    if (dist_down[node] > dist_up[node] - 1) {
      P tmp = presjek(P(dist_up[node], MAX), P(un[pr].X-1, un[pr].Y-1));

      //      if (node+1 == 5) TRACE(tmp.X _ tmp.Y);
      un[node] = unija(un[node], tmp);
      //      un[pr] = unija(un[pr], P(tmp.X+1, tmp.Y+1));
      //      un[node] = unija(un[node], presjek(P(dust_up[node], MAX), P(un[pr].X-1, un[pr].Y-1)));
      //      un[pr] = unija(un[pr], presjek(P_P(un[node].X+1, un[node].Y+1));
    }
    //      pres = razlika(pres, presjek(P(dist_up[node], MAX), P(un[pr].X-1, un[pr].Y-1)));
    else if (dist_down[node] < dist_up[node] - 1) {
      P tmp = presjek(P(dist_down[node] + 2, MAX), P(un[pr].X+1, un[pr].Y+1));

      //if (node+1 == 5) { printf("AA\n"); TRACE(tmp.X _ tmp.Y); }
      un[node] = unija(un[node], tmp);
      //      un[pr] = unija(un[pr], P(tmp.X-1, tmp.Y-1));
      //      un[node] = unija(un[node], P(un[pr].X+1, un[pr].Y+1));
      //      un[pr] = unija(un[pr], P(un[node].X-1, un[node].Y-1));
    }
    //      pres = razlika(pres, presjek(P(dist_down[node] + 2, MAX), P(un[pr].X+1, un[pr].Y+1)));
  }

  P pres = P(0, max(dist_down[node], dist_up[node]) - 1);  
  pres = razlika(pres, un[node]);
  
  //  if (node+1 == 2)
  //    printf("UN %d    %d %d\n", node+1, un[node].X, un[node].Y);


  if (s[node] == '1') {
    un[node] = unija(un[node], pres);
    rje += max(0, pres.Y - pres.X + 1);
    //    printf("NODE %d %d %d\n", node+1, pres.X, pres.Y);
  }

  // if (pr != -1) {
  //   if (dist_down[node] > dist_up[node] - 1)
  //     pres = presjek(pres, P(0, dist_up[node] - 1));
  //   else if (dist_down[node] < dist_up[node] - 1)
  //     pres = presjek(pres, P(0, dist_down[node] + 1));
  // }
  
  //  TRACE(node+1 _ dist_down[node] _ dist_up[node]);
  //TRACE(node+1 _ pres.X _ pres.Y);

  //  printf("UNIJA %d   %d %d\n", node+1, un[node].X, un[node].Y);

  for (auto it : V[node])
    dfs_up(it, node);

  if (pr != -1) {
    if (dist_down[node] > dist_up[node] - 1) {
      P tmp = presjek(P(dist_up[node], MAX), un[node]);

      //      if (node+1 == 5) TRACE(tmp.X _ tmp.Y);
      //      un[node] = unija(un[node], tmp);
      un[pr] = unija(un[pr], P(tmp.X+1, tmp.Y+1));
      //      un[pr] = unija(un[pr], P(tmp.X+1, tmp.Y+1));
      //      un[node] = unija(un[node], presjek(P(dust_up[node], MAX), P(un[pr].X-1, un[pr].Y-1)));
      //      un[pr] = unija(un[pr], presjek(P_P(un[node].X+1, un[node].Y+1));
    }
    //      pres = razlika(pres, presjek(P(dist_up[node], MAX), P(un[pr].X-1, un[pr].Y-1)));
    else if (dist_down[node] < dist_up[node] - 1) {
      P tmp = presjek(P(dist_down[node] + 2, MAX), un[node]);

      un[pr] = unija(un[pr], P(tmp.X-1, tmp.Y-1));

      //      if (node+1 == 5) { printf("AA\n"); TRACE(tmp.X _ tmp.Y); }
      //      un[node] = unija(un[node], tmp);
      //      un[pr] = unija(un[pr], P(tmp.X-1, tmp.Y-1));
      //      un[node] = unija(un[node], P(un[pr].X+1, un[pr].Y+1));
      //      un[pr] = unija(un[pr], P(un[node].X-1, un[node].Y-1));
    }
    //      pres = razlika(pres, presjek(P(dist_down[node] + 2, MAX), P(un[pr].X+1, un[pr].Y+1)));
  }
}

int main()
{
  REP(i, MAX) un[i] = P(0, -1);
  
  int n;
  scanf("%d", &n);
  REP(i, n-1) {
    int a, b;
    scanf("%d%d", &a, &b); a--; b--;
    V[a].push_back(b);
    V[b].push_back(a);
  }

  scanf(" %s", s);

  dfs_down(0, -1);
  dfs_up(0, -1);

  rje++;
  printf("%lld\n", rje);  
  
  return 0;
}


Measured memory_bytes: 60288