#include <bits/stdc++.h>
using namespace std;
void fastscan(int& number) {
  bool negative = false;
  register int c;
  number = 0;
  c = getchar();
  while (c == 10) c = getchar();
  if (c == '-') {
    negative = true;
    c = getchar();
  }
  for (; (c > 47 && c < 58); c = getchar()) number = number * 10 + c - 48;
  if (negative) number *= -1;
}
const int N = 150005;
struct line {
  long long k, b;
  line(long long K = 0, long long B = -1000000007ll * 1000000007ll) {
    k = K;
    b = B;
  }
};
long long f(line p, long long x) { return p.k * x + p.b; }
line t[4 * N];
void cl(int k) {
  k++;
  k *= 4;
  for (int i = 1; i <= k; i++) t[i] = line();
}
void add(int v, int l, int r, line p) {
  int m = (l + r) / 2;
  bool M = f(p, m) > f(t[v], m);
  bool L = f(p, l) > f(t[v], l);
  if (M) swap(p, t[v]);
  if (r - l == 1) return;
  if (L != M)
    add(v * 2, l, m, p);
  else
    add(v * 2 + 1, m, r, p);
}
long long get(int v, int l, int r, int pos) {
  if (r - l == 1) return f(t[v], pos);
  int m = (l + r) / 2;
  if (pos <= m)
    return max(f(t[v], pos), get(v * 2, l, m, pos));
  else
    return max(f(t[v], pos), get(v * 2 + 1, m, r, pos));
}
int n, used[N], color[N], cnt[N], col;
long long a[N], ans;
vector<int> g[N];
void dfsCnt(int v, int p) {
  cnt[v] = 1;
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i];
    if (used[to] || to == p) continue;
    dfsCnt(to, v);
    cnt[v] += cnt[to];
  }
}
int centr(int u) {
  dfsCnt(u, 0);
  col++;
  queue<int> q;
  q.push(u);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    color[v] = col;
    int can = 1;
    if (!can) continue;
    for (int i = 0; i < g[v].size(); i++) {
      int to = g[v][i];
      if (used[to] || color[to] == col) continue;
      if (!(cnt[u] >= 2 * cnt[to])) {
        q.push(to);
        can = 0;
      }
    }
    if (can) {
      used[v] = 1;
      return v;
    }
  }
  assert(0);
}
vector<line> upd;
long long pr[N], sum1[N], sum2[N], st;
int k;
void dfs(int v, int p, int d) {
  pr[v] = pr[p] + a[v];
  sum1[v] = sum1[p] + d * a[v];
  sum2[v] = sum2[p] + pr[v];
  cnt[v] = 1;
  ans = max(ans, get(1, 0, k, d - 1) + sum2[v] - st * d);
  ans = max(ans, sum1[v]);
  upd.push_back(line(pr[v], sum1[v]));
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i];
    if (used[to] || to == p) continue;
    dfs(to, v, d + 1);
    cnt[v] += cnt[to];
  }
}
void solve(int v, int K) {
  v = centr(v);
  k = max(K, 1);
  pr[v] = sum1[v] = sum2[v] = st = a[v];
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i];
    if (used[to]) continue;
    dfs(to, v, 2);
    while (!upd.empty()) {
      add(1, 0, k, upd.back());
      upd.pop_back();
    }
  }
  cl(k);
  for (int i = g[v].size() - 1; i >= 0; i--) {
    int to = g[v][i];
    if (used[to]) continue;
    dfs(to, v, 2);
    while (!upd.empty()) {
      add(1, 0, k, upd.back());
      upd.pop_back();
    }
  }
  cl(k);
  for (int i = 0; i < g[v].size(); i++) {
    int to = g[v][i];
    if (used[to]) continue;
    solve(to, cnt[to] / 2 + 1);
  }
}
int main() {
  cin >> n;
  for (int i = 2; i <= n; i++) {
    int a, b;
    fastscan(a);
    fastscan(b);
    g[a].push_back(b);
    g[b].push_back(a);
  }
  for (int i = 1; i <= n; i++) {
    int x;
    fastscan(x);
    a[i] = x;
  }
  solve(1, n / 2 + 1);
  cout << ans << endl;
  return 0;
}
