#include <bits/stdc++.h>
using namespace std;
inline int read() {
  static char buf[1 << 21], *p1, *p2;
  int f = 0, c = 1;
  char ch =
      (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
           ? EOF
           : *p1++);
  while (ch < '0' || ch > '9') {
    if (ch == '-') c = -1;
    ch =
        (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
             ? EOF
             : *p1++);
  }
  while (ch >= '0' && ch <= '9') {
    f = f * 10 + ch - '0';
    ch =
        (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
             ? EOF
             : *p1++);
  }
  return c * f;
}
const int M = 3e5 + 10;
struct node {
  long long k, b;
  inline long long operator()(const long long &x) { return x * k + b; }
  node(long long x = 0, long long y = 0) { k = x, b = y; }
} e, f[M * 4];
vector<int> v[M];
int fa[M], siz[M], mx[M], dep[M], belong[M], vis[M];
long long v1[M], v2[M], st[M], l[M], a[M], s[M];
int sz, n, x, y, md, top, rt;
long long ans;
void build(int o, int l, int r) {
  f[o] = (node){0, 0};
  if (l == r) return;
  build((o << 1), l, ((l + r) >> 1));
  build((o << 1 | 1), ((l + r) >> 1) + 1, r);
}
long long ask(int o, int l, int r, long long x) {
  long long ans = f[o](x);
  if (l == r) return ans;
  if (x <= ((l + r) >> 1))
    return max(ans, ask((o << 1), l, ((l + r) >> 1), x));
  else
    return max(ans, ask((o << 1 | 1), ((l + r) >> 1) + 1, r, x));
}
void insert(int o, int l, int r, node x) {
  if (f[o](((l + r) >> 1)) < x(((l + r) >> 1))) swap(f[o], x);
  if (l == r) return;
  if (x.k < f[o].k)
    insert((o << 1), l, ((l + r) >> 1), x);
  else
    insert((o << 1 | 1), ((l + r) >> 1) + 1, r, x);
}
void getroot(int x, int fa) {
  siz[x] = 1;
  mx[x] = 0;
  for (int i = 0; i < v[x].size(); ++i) {
    int y = v[x][i];
    if (y == fa || vis[y]) continue;
    getroot(y, x);
    siz[x] += siz[y];
    mx[x] = max(mx[x], siz[y]);
  }
  mx[x] = max(mx[x], sz - siz[x]);
  if (mx[x] < mx[rt]) rt = x;
}
void dfs(int x, int fa, long long val1, long long val2, long long sum,
         int from) {
  if (x != rt && !from) from = x;
  dep[x] = dep[fa] + 1;
  md = max(md, dep[x]);
  int f = 0;
  siz[x] = 1;
  for (int i = 0; i < v[x].size(); ++i) {
    int y = v[x][i];
    if (y == fa || vis[y]) continue;
    dfs(y, x, val1 + sum + a[y], val2 + a[y] * dep[x], sum + a[y], from);
    siz[x] += siz[y];
    f = 1;
  }
  if (!f) {
    st[++top] = x, v1[top] = val1, v2[top] = val2, s[top] = sum - a[rt],
    l[top] = dep[x], belong[top] = from;
  }
}
void dfz(int x) {
  vis[x] = 1;
  top = 0;
  md = 0;
  dfs(x, 0, a[x], 0, a[x], 0);
  st[++top] = x;
  v1[top] = a[x], l[top] = 1, v2[top] = s[top] = belong[top] = 0;
  build(1, 1, md);
  belong[top + 1] = belong[0] = -1;
  for (int i = 1; i <= top;) {
    int j = i;
    while (belong[j] == belong[i])
      ans = max(ans, ask(1, 1, md, l[j]) + v1[j]), ++j;
    j = i;
    while (belong[j] == belong[i]) insert(1, 1, md, node(s[j], v2[j])), ++j;
    i = j;
  }
  build(1, 1, md);
  for (int i = top; i >= 1;) {
    int j = i;
    while (belong[j] == belong[i])
      ans = max(ans, ask(1, 1, md, l[j]) + v1[j]), --j;
    j = i;
    while (belong[i] == belong[j]) insert(1, 1, md, node(s[j], v2[j])), --j;
    i = j;
  }
  for (int i = 0; i < v[x].size(); ++i) {
    int y = v[x][i];
    if (vis[y]) continue;
    sz = siz[y];
    rt = 0;
    getroot(y, x);
    dfz(rt);
  }
}
int main() {
  n = read();
  for (int i = 1; i < n; ++i) {
    x = read();
    y = read();
    v[x].push_back(y);
    v[y].push_back(x);
  }
  for (int i = 1; i <= n; ++i) a[i] = read();
  siz[0] = mx[0] = sz = n;
  getroot(1, 0);
  dfz(rt);
  cout << ans;
  return 0;
}
