#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
ifstream cin("guvern.in");
ofstream cout("guvern.out");
const int MAXN = 200000;
vector<int> g[1 + MAXN], links[1 + MAXN];
set<pair<int, int> > grandfathers;
int value[1 + MAXN], dp[1 + MAXN], upwards[1 + MAXN];
int first[1 + MAXN], last[1 + MAXN], FuckYouSTL = 0;
int eventCount = 0;
pair<pair<int, int>, int> event[1 + MAXN];
bool seen[1 + MAXN];
int best[1 + MAXN];
void DFS(int node, int father) {
auto it = grandfathers.lower_bound(make_pair(value[node], 0));
if (it != grandfathers.end())
upwards[node] = it->second;
else
upwards[node] = 0;
links[upwards[node]].push_back(node);
grandfathers.insert(make_pair(value[node], node));
FuckYouSTL++;
first[node] = FuckYouSTL;
for (auto &son : g[node])
if (son != father)
DFS(son, node);
grandfathers.erase(make_pair(value[node], node));
last[node] = FuckYouSTL;
}
int BinarySearch() {
sort(event + 1, event + eventCount + 1);
for (int i = 1; i <= eventCount; i++) {
int left = 1, right = i - 1, answer = 0;
while (left <= right) {
int middle = (left + right) / 2;
if (event[middle].first.first < event[i].first.second) {
answer = middle;
left = middle + 1;
}
else
right = middle - 1;
}
best[i] = max(best[i - 1], event[i].second + best[answer]);
}
return best[eventCount];
}
void Solve(int node) {
seen[node] = true;
for (auto &son : links[node])
if (!seen[son])
Solve(son);
eventCount = 0;
for (auto &son : links[node]) {
eventCount++;
event[eventCount] = make_pair(make_pair(last[son], first[son]), dp[son]);
}
dp[node] = 1 + BinarySearch();
}
int main() {
int n;
cin >> n;
for (int i = 1; i < n; i++) {
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
for (int i = 1; i <= n; i++)
cin >> value[i];
DFS(1, -1);
Solve(0);
cout << dp[0] - 1;
return 0;
}