#include <bits/stdc++.h>
const long long P = 1000000007;
using namespace std;
inline void ckmax(long long &a, long long b) { a = max(a, b); }
inline void ckmin(long long &a, long long b) { a = min(a, b); }
inline void mulmod(long long &a, long long b) { a = 1ll * a * b % P; }
inline void addmod(long long &a, long long b) {
  long long t = a + b;
  a = (t >= P ? t - P : t);
}
inline long long ksm(long long a, long long b) {
  long long ans = 1;
  for (; b; b >>= 1) {
    if (b & 1) ans = 1ll * ans * a % P;
    a = 1ll * a * a % P;
  }
  return ans;
}
inline long long inv(long long a) { return ksm(a, P - 2); }
inline void printarray(long long *a, long long n) {
  for (register long long i = (1); i <= (n); i++) fprintf(stderr, "%d ", a[i]);
  fprintf(stderr, "\n");
}
namespace FastIO {
const long long SIZE = 1 << 16;
char buf[SIZE], obuf[SIZE], str[64];
long long bi = SIZE, bn = SIZE, opt;
long long read(char *s) {
  while (bn) {
    for (; bi < bn && buf[bi] <= ' '; bi++)
      ;
    if (bi < bn) break;
    bn = fread(buf, 1, SIZE, stdin), bi = 0;
  }
  long long sn = 0;
  while (bn) {
    for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
    if (bi < bn) break;
    bn = fread(buf, 1, SIZE, stdin), bi = 0;
  }
  s[sn] = 0;
  return sn;
}
bool read(long long &x) {
  if (x) x = 0;
  long long bf = 0, n = read(str);
  if (!n) return 0;
  long long i = 0;
  if (str[i] == '-') bf = 1, i = 1;
  for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
  if (bf) x = -x;
  return 1;
}
void write(long long x) {
  if (!x)
    obuf[opt++] = '0';
  else {
    if (x < 0) obuf[opt++] = '-', x = -x;
    long long sn = 0;
    while (x) str[sn++] = x % 10 + '0', x /= 10;
    for (long long i = sn - 1; i >= 0; i--) obuf[opt++] = str[i];
  }
  if (opt >= (SIZE >> 1)) {
    fwrite(obuf, 1, opt, stdout);
    opt = 0;
  }
}
void write(char x) {
  obuf[opt++] = x;
  if (opt >= (SIZE >> 1)) {
    fwrite(obuf, 1, opt, stdout);
    opt = 0;
  }
}
void Fflush() {
  if (opt) fwrite(obuf, 1, opt, stdout);
  opt = 0;
}
};  // namespace FastIO
inline long long read() {
  long long x;
  FastIO::read(x);
  return x;
}
const long long MAXN = 3e5 + 5;
vector<long long> e[MAXN];
long long n, a[MAXN];
struct Line {
  long long k, b;
  Line() { k = 0, b = -1e18; }
  Line(long long K, long long B) : k(K), b(B) {}
  void print() { fprintf(stderr, "k = %lld, b = %lld\n", k, b); }
};
inline long long Y(Line v, long long x) { return x * v.k + v.b; }
struct LC_tree {
  static const long long N = MAXN << 2;
  Line a[N];
  void build(long long k, long long l, long long r) {
    a[k].k = 0, a[k].b = -1e18;
    if (l == r) return;
    build((k << 1), l, ((l + r) >> 1)),
        build((k << 1 | 1), ((l + r) >> 1) + 1, r);
  }
  void insert(long long k, long long l, long long r, Line v) {
    long long lv = Y(a[k], l), rv = Y(a[k], r), Lv = Y(v, l), Rv = Y(v, r);
    if (lv <= Lv && rv <= Rv) return a[k] = v, void();
    if (lv >= Lv && lv >= Rv) return;
    if (l == r) {
      if (Y(a[k], ((l + r) >> 1)) < Y(v, ((l + r) >> 1))) swap(a[k], v);
      return;
    }
    if (Y(a[k], ((l + r) >> 1)) < Y(v, ((l + r) >> 1))) swap(a[k], v);
    v.k < a[k].k ? insert((k << 1), l, ((l + r) >> 1), v)
                 : insert((k << 1 | 1), ((l + r) >> 1) + 1, r, v);
  }
  long long query(long long k, long long l, long long r, long long pos) {
    if (l == r) return Y(a[k], pos);
    return max(Y(a[k], pos),
               pos <= ((l + r) >> 1)
                   ? query((k << 1), l, ((l + r) >> 1), pos)
                   : query((k << 1 | 1), ((l + r) >> 1) + 1, r, pos));
  }
  void print(long long k, long long l, long long r) {
    fprintf(stderr, "%lld %lld %lld\n", k, l, r);
    a[k].print();
    if (l != r)
      print((k << 1), l, ((l + r) >> 1)),
          print((k << 1 | 1), ((l + r) >> 1) + 1, r);
  }
} tr;
long long siz[MAXN], dep[MAXN], mxdep, vis[MAXN], ans, rt,
    vrt = ((1 << 30) - 1);
void getroot(long long u, long long fa, long long allsiz) {
  siz[u] = 1;
  long long mx = -((1 << 30) - 1);
  for (auto v : e[u]) {
    if (v == fa || vis[v]) continue;
    getroot(v, u, allsiz);
    siz[u] += siz[v];
    ckmax(mx, siz[v]);
  }
  ckmax(mx, allsiz - siz[u]);
  if (mx < vrt) rt = u, vrt = mx;
}
void getinfo(long long u, long long fa) {
  dep[u] = dep[fa] + 1, siz[u] = 1;
  ckmax(mxdep, dep[u]);
  for (auto v : e[u]) {
    if (v == fa || vis[v]) continue;
    getinfo(v, u);
    siz[u] += siz[v];
  }
}
vector<Line> q;
void solve(long long u, long long fa, long long val, long long sum,
           long long tsum, long long len, long long antival, long long st) {
  if (e[u].size() == 1) {
    ckmax(ans, tr.query(1, 1, mxdep, len) + val);
    ckmax(ans, val);
    ckmax(ans, antival + tsum);
    q.push_back(Line(sum, antival));
  }
  for (auto v : e[u]) {
    if (v == fa || vis[v]) continue;
    solve(v, u, val + tsum + a[v], sum + a[v], tsum + a[v], len + 1,
          antival + a[v] * (dep[v] - 1), st);
  }
}
void dfs(long long u, long long allsiz, long long dep) {
  vis[u] = 1;
  mxdep = 0;
  assert(dep <= 40);
  getinfo(u, 0);
  tr.build(1, 1, mxdep);
  for (auto v : e[u]) {
    if (vis[v]) continue;
    solve(v, 0, 2 * a[u] + a[v], a[v], a[u] + a[v], 2, a[v], u);
    for (auto it : q) tr.insert(1, 1, mxdep, it);
    q.clear();
  }
  reverse(e[u].begin(), e[u].end());
  tr.build(1, 1, mxdep);
  for (auto v : e[u]) {
    if (vis[v]) continue;
    solve(v, 0, 2 * a[u] + a[v], a[v], a[u] + a[v], 2, a[v], u);
    for (auto it : q) tr.insert(1, 1, mxdep, it);
    q.clear();
  }
  for (auto v : e[u]) {
    if (vis[v]) continue;
    vrt = ((1 << 30) - 1);
    getroot(v, u, siz[v]);
    dfs(rt, siz[v], dep + 1);
  }
}
signed main() {
  n = read();
  for (register long long i = (1); i <= (n - 1); i++) {
    long long u = read(), v = read();
    e[u].push_back(v), e[v].push_back(u);
  }
  for (register long long i = (1); i <= (n); i++) a[i] = read();
  getroot(1, 0, n);
  dfs(rt, n, 0);
  cout << ans << endl;
  return FastIO::Fflush(), 0;
}
