#include <bits/stdc++.h>
using namespace std;
const int maxn = 150005;
const long long is_query = -(1LL << 62);
struct Line {
  long long m, b;
  mutable function<const Line *()> succ;
  bool operator<(const Line &rhs) const {
    if (rhs.b != is_query) return m < rhs.m;
    const Line *s = succ();
    if (!s) return false;
    return b - s->b < (s->m - m) * rhs.m;
  }
};
struct MaxDynamicCHT : public multiset<Line> {
  bool bad(iterator y) {
    auto z = next(y);
    if (y == begin()) {
      if (z == end()) return 0;
      return y->m == z->m && y->b <= z->b;
    }
    auto x = prev(y);
    if (z == end()) return y->m == x->m && y->b <= x->b;
    return (x->b - y->b) * (z->m - y->m) >= (y->b - z->b) * (y->m - x->m);
  }
  void add(long long m, long long b) {
    auto y = insert({m, b});
    y->succ = [=] { return next(y) == end() ? 0 : &*next(y); };
    if (bad(y)) {
      erase(y);
      return;
    }
    while (next(y) != end() && bad(next(y))) erase(next(y));
    while (y != begin() && bad(prev(y))) erase(prev(y));
  }
  long long query(long long x) {
    auto l = *lower_bound({x, is_query});
    return l.m * x + l.b;
  }
};
int n, vals[maxn], sz[maxn];
long long res;
bool done[maxn];
vector<int> g[maxn];
vector<pair<int, pair<long long, pair<long long, long long>>>> v;
int gsz(int u, int p) {
  sz[u] = 1;
  for (int v : g[u]) {
    if (v == p || done[v]) continue;
    sz[u] += gsz(v, u);
  }
  return sz[u];
}
int centroid(int u, int p, int msz) {
  for (int v : g[u]) {
    if (v == p || done[v]) continue;
    if (sz[v] * 2 > msz) return centroid(v, u, msz);
  }
  return u;
}
void dfs(int u, int p, int dep, long long rev, long long val, long long sum) {
  v.push_back(make_pair(dep, make_pair(rev, make_pair(val, sum))));
  for (int v : g[u]) {
    if (v == p || done[v]) continue;
    dfs(v, u, dep + 1, rev + 1LL * (dep + 1) * vals[v], val + sum + vals[v],
        sum + vals[v]);
  }
}
void calc(int u) {
  MaxDynamicCHT cht;
  cht.add(vals[u], vals[u]);
  for (int ck : g[u]) {
    if (done[ck]) continue;
    v.clear();
    dfs(ck, u, 1, vals[ck], vals[ck], vals[ck]);
    for (pair<int, pair<long long, pair<long long, long long>>> ck2 : v) {
      long long best = cht.query(ck2.first) + ck2.second.second.first;
      res = max(res, best);
    }
    for (pair<int, pair<long long, pair<long long, long long>>> ck2 : v)
      cht.add(ck2.second.second.second + vals[u],
              ck2.second.first + ck2.second.second.second + vals[u]);
  }
  if (cht.size()) res = max(res, cht.query(0));
}
void solve(int u, int msz) {
  u = centroid(u, -1, msz);
  gsz(u, -1);
  done[u] = true;
  calc(u);
  reverse(g[u].begin(), g[u].end());
  calc(u);
  for (int v : g[u]) {
    if (done[v]) continue;
    solve(v, sz[v]);
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int a, b;
    scanf(" %d %d", &a, &b);
    g[a].push_back(b);
    g[b].push_back(a);
  }
  for (int i = 1; i <= n; i++) scanf(" %d", &vals[i]);
  gsz(1, -1);
  solve(1, n);
  printf("%lld\n", res);
}
