/*
Catalin-Stefan Tiseanu
Pre-written code is assembled from various sources found online.
Big thanks to the community for that !
*/
// Pre-written code below
using namespace std;
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <unordered_map>
//START_CLEAN
// always remove
//START:mandatory
//#define DEBUG
#ifndef NDEBUG
# define assert_msg(condition, message) \
do { \
if (! (condition)) { \
std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \
<< " line " << __LINE__ << ": " << message << std::endl; \
std::exit(EXIT_FAILURE); \
} \
} while (false)
#else
# define ASSERT(condition, message) do { } while (false)
#endif
#ifdef DEBUG
#define debug(args...) {dbg,args; cerr<<endl;}
#else
#define debug(args...) // Just strip off all debug tokens
#endif
template<class T> std::ostream& operator <<(std::ostream& stream, const vector<T> & v) {
for (auto el : v)
stream << el << " ";
return stream;
}
template<class T> std::ostream& operator <<(std::ostream& stream, const vector<vector<T>> & v) {
for (auto line : v) {
for (auto el : line)
stream << el << " ";
stream << endl;
}
return stream;
}
template<class T, class U> std::ostream& operator <<(std::ostream& stream, const pair<U, T> & p) {
stream << "( " << p.first << ", " << p.second << " )";
return stream;
}
class debugger {
public:
template<class T> void output (const T& v) {
cerr << v << " ";
}
template<class T> debugger& operator , (const T& v) {
output(v);
return *this;
}
} dbg;
//END:mandatory
////////////////
// templates //
////////////////
// general
//template size
template<typename T> int size(const T& c) { return int(c.size()); }
//template abs
template<typename T> T abs(T x) { return x < 0 ? -x : x; }
//template sqr
template<typename T> T sqr(T x) { return x*x; }
//template remin
template<typename T> bool remin(T& x, T y) { if (x <= y) return false; x = y; return true; }
//template remax
template<typename T> bool remax(T& x, T y) { if (x >= y) return false; x = y; return true; }
//template factorize
template<class T> inline vector<pair<T,int> > factorize(T n) {vector<pair<T,int> > R;for (T i=2;n>1;){if (n%i==0){int C=0;for (;n%i==0;C++,n/=i);R.push_back(make_pair(i,C));} i++;if (i>n/i) i=n;}if (n>1) R.push_back(make_pair(n,1));return R;}
//template toStr
template<typename T> string toStr(T x) { stringstream ss; ss << x; return ss.str(); }
// misc
#define EPS 1e-5
// types
//template int64
typedef long long int64 ;
//template uint64
typedef unsigned long long uint64 ;
// shortcuts
#define all(_xx) _xx.begin(), _xx.end()
#define pb push_back
#define vi vector<int>
#define vs vector<string>
#define vvi vector<vector<int>>
#define vd vector<double>
#define vpii vector<pair<int,int> >
#define vpdd vector<pair<double,double> >
#define pii pair<int,int>
#define pll pair<long long, long long>
#define pdd pair<double, double>
#define mp(XX, YY) make_pair(XX, YY)
#define fi first
#define se second
#define ll long long
#define SS stringstream
// for loops
#define re(II, NN) for (int II(0), _NN(NN); (II) < (NN); ++(II))
#define fod(II, XX, YY) for (int II(XX), _YY(YY); (II) >= (_YY); --(II))
#define fo(II, XX, YY) for (int II(XX), _YY(YY); (II) <= (_YY); ++(II))
#define foreach(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
// Useful hardware instructions
#define bitcount __builtin_popcount
#define gcd __gcd
// Useful all around
#define checkbit(n,b) ( (n >> b) & 1)
#define DREP(a) sort(a.begin(), a.end());a.erase(unique(a.begin(), a.end()),a.end())
#define INDEX(arr,ind) (lower_bound(arr.begin(), arr.end(),ind)-arr.begin())
#define PAUSE cerr << "Press any key to continue ..."; char xxxx; scanf("%c", &xxxx);
#define fill(xx,val) memset(xx, val, sizeof(xx))
struct Scanner {
char* curPos;
const static int BUF_SIZE = (2000000);
char input[BUF_SIZE];
FILE * fin;
void init(FILE * _fin) {
fin = _fin;
fread(input, 1, sizeof(input), fin);
curPos = input;
}
Scanner() {;}
inline void ensureCapacity() {
int size = input + BUF_SIZE - curPos;
if (size < 100) {
memcpy(input, curPos, size);
fread(input + size, 1, BUF_SIZE - size, fin);
curPos = input;
}
}
inline int nextInt() {
ensureCapacity();
while (!isdigit(*curPos) && *curPos != '-')
++curPos;
int res = 0;
int sign = 1;
if (*curPos == '-')
sign = -1,
++curPos;
while (*curPos >= '0' && *curPos <= '9')
res = res * 10 + (*(curPos++) & 15);
return sign * res;
}
} Sc;
struct IntervalTree {
static const int maxn = (1<<17);
int tree[2*maxn + 1];
void init() {
memset(tree, -1, sizeof(tree));
}
IntervalTree() {init();}
int query(int n, int n_l, int n_r, int val) {
if (n_l == n_r)
return tree[n];
int mid = (n_l + n_r) >> 1;
if (val <= mid && tree[2*n] > val)
return query(2 * n, n_l, mid, val);
else if (tree[2*n+1] > val)
return query(2 * n + 1, mid + 1, n_r, val);
return -1;
}
int query(int val) {return query(1, 0, maxn - 1, val); }
void update(int pos, int val) {
tree[pos + maxn] = val;
for (int n = (pos + maxn) >> 1; n; n >>= 1)
tree[n] = max(tree[2*n], tree[2*n+1]);
}
} Tree;
#define INF (1<<30)
const string filein = "guvern.in";
const string fileout = "guvern.out";
#define MAX_N 200111
int N, euler_time;
vvi arb;
vi priority, next_minister, bst;
vpii start_end_time, all_priorities, edges;
vector<pair<int, pii>> bst_so_far[MAX_N];
set<int> ancestors;
int df (int x, int from) {
start_end_time[x].first = ++euler_time;
// find next guy
next_minister[x] = Tree.query(x);
Tree.update(x, x);
// debug("next_minister:", x, next_minister[x]);
for (auto son : arb[x])
if (son != from)
df (son, x);
int cur_next = next_minister[x];
int tot_val = 1;
for (auto el : bst_so_far[x])
tot_val += el.se.fi;
debug("node:", x, cur_next, tot_val);
debug("bst_so_far:", bst_so_far[x]);
bst_so_far[x].clear();
if (x == N) // final stop
return tot_val;
if (bst_so_far[cur_next].size() && bst_so_far[cur_next].back().fi > start_end_time[x].first) {
// search for best
int pos =
lower_bound(all(bst_so_far[cur_next]), mp(start_end_time[x].first + 1, mp(-1, -1))) - bst_so_far[cur_next].begin();
debug("updating parent:", cur_next, bst_so_far[cur_next], pos);
if (tot_val > bst_so_far[cur_next].back().se.se + bst_so_far[cur_next].back().se.fi - bst_so_far[cur_next][pos].se.se) {
int pref_val = bst_so_far[cur_next][pos].se.se;
bst_so_far[cur_next].erase(bst_so_far[cur_next].begin() + pos, bst_so_far[cur_next].end());
bst_so_far[cur_next].pb(mp(start_end_time[x].first, mp(tot_val, pref_val)));
}
} else if (bst_so_far[cur_next].size() == 0) {
bst_so_far[cur_next].pb(mp(start_end_time[x].first, mp(tot_val, 0)));
} else {
bst_so_far[cur_next].pb(mp(start_end_time[x].first, mp(tot_val, bst_so_far[cur_next].back().se.se + bst_so_far[cur_next].back().se.fi)));
}
Tree.update(x, -1);
start_end_time[x].second = ++euler_time;
return tot_val;
}
int solve() {
return df (N, N);
}
int main() {
FILE * fin = fopen(filein.c_str(), "r");
FILE * fout = fopen(fileout.c_str(), "w");
Sc.init(fin);
N = Sc.nextInt();
arb.resize(N + 1);
priority.resize(N + 1);
start_end_time.resize(N + 1);
next_minister.resize(N + 1);
bst.resize(N + 1);
fo (i, 1, N - 1) {
int x = Sc.nextInt(), y = Sc.nextInt();
//arb[x].pb(y);
//arb[y].pb(x);
edges.pb(mp(x,y));
}
edges.pb(mp(0, 1));
//arb[0].pb(1);
fo (i, 1, N) {
priority[i] = Sc.nextInt();
all_priorities.pb(mp(priority[i], i));
}
debug("all_priorities:", all_priorities);
sort(all(all_priorities));
re (i, size(all_priorities))
priority[all_priorities[i].second] = i;
priority[0] = N;
debug("priority:", priority);
for (auto e: edges) {
arb[ priority[e.fi] ].pb(priority[e.se]);
arb[ priority[e.se] ].pb(priority[e.fi]);
}
debug("arb:");
fprintf(fout, "%d\n", solve() - 1);
return 0;
}