// I can't tell you what it really is,
// I can only tell you what it feels like.
#include "bits/stdc++.h"
using namespace std;
 
#define int long long
#define rep(i,a,n) for (int i = a; i <= n; ++i)
#define pb push_back
#define P pair < int, int > 
#define s second
#define f first
#define all(v)  v.begin(), v.end()
#define lb(v, x)  lower_bound(all(v), x) - v.begin()
#define up(v, x)  upper_bound(all(v), x) - v.begin()

const int mod = 1e9 + 7;
const int N = 2e5 + 5;

vector < int > v[N];
int val[N], idx[N], ar[N], ok = 1;
int sz[N];

void dfs(int x, int p) {
    ar[ok] = x;
    idx[x] = ok++;
    sz[x] = 1;
    for (int i : v[x]) {
        if (i != p) {
            dfs(i, x);
            sz[x] += sz[i];
        }
    }
}


int a[N];
vector < int > tree[N << 2], sum[N<<2];

class merge_sort_tree{        
        public:
        void build(int l, int r, int node){
            if(l == r){
                tree[node].pb(a[l]);
                return ;
            }
            int mid = l + r >> 1, lc = node + node, rc = 1 + lc;
            build(l, mid, lc);    build(mid + 1, r, rc);

            merge(all(tree[lc]), all(tree[rc]), back_inserter(tree[node]));
        }
        void done() {
            int kit = N<<2;
            for (int i = 0; i < kit; ++i) {
                sum[i].resize(tree[i].size());
                if (!tree[i].empty())
                    sum[i][0] = tree[i][0];
                for (int j = 1; j < tree[i].size(); ++j) {
                    sum[i][j] = sum[i][j-1] + tree[i][j];
                }
            }
        }
        int query(int l, int r, int ql, int qr, int val, int node){
            if(qr < l || r < ql)
                return 0;
            if(ql <= l and r <= qr){
                int L = lower_bound(all(tree[node]), val) - tree[node].begin();                               
                if (!L) {
                    return 0;
                }                
                return sum[node][L-1];                                
            }
            int mid = l + r >> 1, lc = node + node, rc = 1 + lc;

            return (query(l, mid, ql, qr, val, lc)+ query(mid + 1, r, ql, qr, val, rc));
        }
};

inline void solve() {
   int n, l, r;
   cin >> n;
   rep(i,2,n) {
       cin >> l >> r;
       v[l].pb(r);
       v[r].pb(l);
   }
   dfs(1, 1);
   rep(i,1,n) {
       cin >> val[i];
       a[idx[i]] = val[i];
   }
   merge_sort_tree obj;
   obj.build(1, n, 1);
   obj.done();
   int ans = 0;
   rep(i,1,n) {
       if (sz[ar[i]] == 1) {
           continue;
       }
       int l = i+1, r = i + sz[ar[i]] - 1;
       if (l <= r) {
           ans += obj.query(1, n, l, r, val[ar[i]], 1);
       }
   }
   cout << ans;
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  cout.tie(NULL);
  int t = 1;
  solve();
  return 0;
}