#include <bits/stdc++.h>
using namespace std;
const int N = 150000 + 5;
vector<int> e[N];
struct faction {
  __int128 k, b;
  __int128 val(long long x) { return k * x + b; }
} a[N];
int Rt, tot, ls[N << 2], rs[N << 2], tr[N << 2];
void upt(int &p, long long l, long long r, int id) {
  if (!p) p = ++tot;
  if (l == r) {
    if (a[tr[p]].val(l) < a[id].val(l)) tr[p] = id;
    return;
  }
  if (a[tr[p]].val(l) >= a[id].val(l) && a[tr[p]].val(r) >= a[id].val(r))
    return;
  if (a[tr[p]].val(l) < a[id].val(l) && a[tr[p]].val(r) < a[id].val(r))
    return (void)(tr[p] = id);
  long long mid = (l + r) >> 1;
  if (a[tr[p]].val(mid) < a[id].val(mid)) {
    if (a[tr[p]].k < a[id].k)
      upt(ls[p], l, mid, tr[p]);
    else
      upt(rs[p], mid + 1, r, tr[p]);
    tr[p] = id;
  } else {
    if (a[tr[p]].k < a[id].k)
      upt(rs[p], mid + 1, r, id);
    else
      upt(ls[p], l, mid, id);
  }
}
__int128 query(int p, long long l, long long r, long long pos) {
  if (!p) return 0;
  if (l == r) return a[tr[p]].val(pos);
  long long mid = (l + r) >> 1;
  if (pos <= mid)
    return max(query(ls[p], l, mid, pos), a[tr[p]].val(pos));
  else
    return max(query(rs[p], mid + 1, r, pos), a[tr[p]].val(pos));
}
int rt, mx[N], vis[N], sz[N];
void dfs(int x, int fath, int s) {
  sz[x] = 1;
  mx[x] = 0;
  for (int v : e[x]) {
    if (vis[v] || v == fath) continue;
    dfs(v, x, s);
    sz[x] += sz[v];
    mx[x] = max(mx[x], sz[v]);
  }
  mx[x] = max(mx[x], s - sz[x]);
  if (mx[rt] > mx[x]) rt = x;
}
int A[N];
__int128 ans;
long long st[N][3];
int cnt[N], top;
void ddddfs(int x, int fath, long long sum1, long long sum2, long long sum,
            int dep) {
  sum += A[x];
  ++dep;
  sum1 += sum;
  sum2 += 1ll * A[x] * (dep + 1);
  st[++top][0] = sum1;
  st[top][1] = sum2;
  st[top][2] = sum;
  cnt[top] = dep;
  ans = max(ans, (__int128)max(sum1, sum2));
  for (int v : e[x])
    if (v != fath && vis[v] == 0) ddddfs(v, x, sum1, sum2, sum, dep);
}
void dddddfs(int x, int fath, long long sum1, long long sum) {
  sum += A[x];
  sum1 += sum;
  ans = max(ans, (__int128)sum1);
  for (int v : e[x])
    if (v != fath && vis[v] == 0) dddddfs(v, x, sum1, sum);
}
void Clear() {
  for (int i = 1; i <= tot; ++i) ls[i] = rs[i] = tr[i] = 0;
  Rt = tot = 0;
}
void solve(int x) {
  vis[x] = 1;
  int C = 0;
  Clear();
  for (int v : e[x]) {
    if (vis[v]) continue;
    top = 0;
    ddddfs(v, x, 0, A[x], 0, 0);
    dddddfs(v, x, A[x], A[x]);
    for (int i = 1; i <= top; ++i)
      ans = max(ans, query(Rt, 0, 2e11, cnt[i]) + st[i][0]);
    for (int i = 1; i <= top; ++i)
      a[++C].k = st[i][2] + A[x], a[C].b = st[i][1], upt(Rt, 0, 2e11, C);
  }
  reverse(e[x].begin(), e[x].end());
  C = 0, Clear();
  for (int v : e[x]) {
    if (vis[v]) continue;
    top = 0;
    ddddfs(v, x, 0, A[x], 0, 0);
    for (int i = 1; i <= top; ++i)
      ans = max(ans, query(Rt, 0, 2e11, cnt[i]) + st[i][0]);
    for (int i = 1; i <= top; ++i)
      a[++C].k = st[i][2] + A[x], a[C].b = st[i][1], upt(Rt, 0, 2e11, C);
  }
  for (int v : e[x]) {
    if (vis[v]) continue;
    rt = 0;
    mx[rt] = N;
    dfs(v, x, sz[v]);
    int k = rt;
    solve(k);
  }
}
inline int rd() {
  int x = 0;
  char ch = getchar();
  bool f = 0;
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = 1;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  return f ? -x : x;
}
void write(__int128 x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  int n = rd();
  int u, v;
  for (int i = 1; i < n; ++i) {
    u = rd();
    v = rd();
    e[u].push_back(v);
    e[v].push_back(u);
  }
  for (int i = 1; i <= n; ++i) A[i] = rd();
  rt = 0;
  mx[rt] = N;
  dfs(1, 0, n);
  solve(rt);
  write(ans);
  return 0;
}
