#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:36777216")
using namespace std;
void go(int a, int p, const vector<vector<int> >& G, vector<int>& parent,
        vector<vector<int> >& dists) {
  parent[a] = p;
  dists[a].assign(3, 0);
  for (int i = 0; i < G[a].size(); ++i) {
    int other = G[a][i];
    if (other == p) {
      continue;
    }
    go(other, a, G, parent, dists);
    if (1 + dists[other][0] > dists[a][0]) {
      dists[a][2] = dists[a][1];
      dists[a][1] = dists[a][0];
      dists[a][0] = 1 + dists[other][0];
    } else if (1 + dists[other][0] > dists[a][1]) {
      dists[a][2] = dists[a][1];
      dists[a][1] = 1 + dists[other][0];
    } else if (1 + dists[other][0] > dists[a][2]) {
      dists[a][2] = 1 + dists[other][0];
    }
  }
}
void go2(int a, int p, const vector<vector<int> >& G, const vector<int>& parent,
         vector<vector<int> >& dists, long long& result) {
  int up = dists[a][0];
  if (p != -1) {
    multiset<int> dists_p;
    for (int i = 0; i < 3; ++i) {
      dists_p.insert(dists[p][i]);
    }
    multiset<int>::iterator it = dists_p.find(1 + dists[a][0]);
    if (it != dists_p.end()) {
      dists_p.erase(it);
    }
    int max_through_p = 1 + *dists_p.rbegin();
    if (max_through_p > dists[a][0]) {
      dists_p.clear();
      for (int i = 0; i < 3; ++i) {
        dists_p.insert(dists[p][i]);
      }
      if (1 + dists[a][0] != *dists_p.rbegin()) {
        dists_p.erase(dists_p.find(*dists_p.rbegin()));
      }
      it = dists_p.find(1 + dists[a][0]);
      if (it != dists_p.end()) {
        dists_p.erase(it);
      }
      up = min(max(up, max(1, *dists_p.rbegin()) + 1),
               max(dists[a][0], max_through_p));
    } else {
      multiset<int> dists_a;
      for (int i = 0; i < 3; ++i) {
        dists_a.insert(dists[a][i]);
      }
      dists_p.clear();
      for (int i = 0; i < 3; ++i) {
        dists_p.insert(dists[p][i]);
      }
      dists_a.erase(dists_a.find(*dists_a.rbegin()));
      it = dists_p.find(1 + dists[a][0]);
      if (it != dists_p.end()) {
        dists_p.erase(it);
      }
      up = max(*dists_a.rbegin(), 1 + *dists_p.rbegin());
    }
    if (max_through_p > dists[a][0]) {
      dists[a][2] = dists[a][1];
      dists[a][1] = dists[a][0];
      dists[a][0] = max_through_p;
    } else if (max_through_p > dists[a][1]) {
      dists[a][2] = dists[a][1];
      dists[a][1] = max_through_p;
    } else if (max_through_p > dists[a][2]) {
      dists[a][2] = max_through_p;
    }
  }
  result += up;
  for (int i = 0; i < G[a].size(); ++i) {
    int other = G[a][i];
    if (other == p) {
      continue;
    }
    go2(other, a, G, parent, dists, result);
  }
}
int main() {
  int n;
  scanf("%d", &n);
  vector<vector<int> > G(n);
  for (int i = 0; i < n - 1; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    --x;
    --y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  string s;
  cin >> s;
  vector<int> parent(n);
  vector<vector<int> > dists(n);
  go(0, -1, G, parent, dists);
  long long result = 1;
  go2(0, -1, G, parent, dists, result);
  cout << result << endl;
  return 0;
}
