#include <cstdio>
#include <cctype>
#include <vector>
#include <utility>
#include <algorithm>
#define x first
#define y second
#define BUF_SIZE 1<<17
#define MAXN 200000
#define MAXP 530000
int pos=BUF_SIZE;
char buf[BUF_SIZE];
FILE *fin;
std::vector <int> g[MAXN+1], u[MAXN+1], q[MAXN+1];
int t[MAXN+1], v[MAXN+1], st[MAXN+1], s[MAXN+1];
int k, h, n, d[MAXN+1], r[MAXN+1], e[MAXN+1];
std::pair <int, int> a[MAXN+2];
int poz, aint[MAXP];
inline char nextch(){
if(pos==BUF_SIZE) fread(buf, BUF_SIZE, 1, fin), pos=0;
return buf[pos++];
}
inline int read(){
int x=0, s=1;
char ch=nextch();
while((!isdigit(ch))&&(ch!='-')) ch=nextch();
if(ch=='-') ch=nextch(), s=-1;
while(isdigit(ch)){
x=10*x+ch-'0';
ch=nextch();
}
return x*s;
}
void query(int p, int st, int dr){
if((st==poz)&&(aint[p]==0)) poz=dr+1;
else if(st<dr){
int m=(st+dr)/2;
if(poz<=m) query(2*p, st, m);
if(m+1<=poz) query(2*p+1, m+1, dr);
}
}
void update(int p, int st, int dr){
if(st==dr) aint[p]^=1;
else{
int m=(st+dr)/2;
if(poz<=m) update(2*p, st, m);
else update(2*p+1, m+1, dr);
aint[p]=aint[2*p]+aint[2*p+1];
}
}
void dfs(int x){
poz=v[x]+1;
query(1, 1, n);
u[a[poz].y].push_back(x);
poz=v[x];
update(1, 1, n);
e[++h]=x;
for(auto y:g[x]){
if(y!=t[x]){
t[y]=x;
dfs(y);
}
}
k++;
r[x]=k;
poz=v[x];
update(1, 1, n);
}
int main(){
FILE *fout;
fin=fopen("guvern.in", "r");
fout=fopen("guvern.out", "w");
n=read();
for(int i=1; i<n; i++){
int x=read();
int y=read();
g[x].push_back(y);
g[y].push_back(x);
}
for(int i=1; i<=n; i++)
v[i]=read();
for(int i=1; i<=n; i++)
a[i]=std::make_pair(v[i], i);
std::sort(a+1, a+n+1);
for(int i=1; i<=n; i++)
v[a[i].y]=i;
for(int i=0; i<=n; i++)
u[i].push_back(i);
dfs(1);
r[0]=n+1;
for(int i=n; i>=0; i--){
int x=e[i], vf=0;
for(auto y:u[x]){
while((vf>0)&&(r[y]>r[st[vf]]))
vf--;
if(vf>0)
q[st[vf]].push_back(y);
st[++vf]=y;
}
for(int j=u[x].size()-1; j>=0; j--){
int y=u[x][j];
s[y]=0;
for(auto z:q[y])
s[y]+=d[z];
s[y]=std::max(s[y], d[y]);
q[y].clear();
}
d[x]=1+s[x];
}
fprintf(fout, "%d\n", d[0]-1);
fclose(fin);
fclose(fout);
return 0;
}