#include <bits/stdc++.h>
using namespace std;
namespace RA {
int r(int p) { return 1ll * rand() * rand() % p; }
int r(int L, int R) { return r(R - L + 1) + L; }
}  // namespace RA
const int N = 2e5 + 5, SZ = N << 2;
int n, sz[N], Cut[N], sm[N];
vector<int> g[N];
long long a[N], ans = 0;
namespace seg {
int mx[SZ], mn[SZ], tim[SZ], totim;
pair<long long, long long> tag[SZ];
inline void cls(int u) {
  if (tim[u] < totim) tag[u] = {0, 0}, tim[u] = totim;
}
void insert(long long k, long long b, int u = 1, int l = 1, int r = n) {
  cls(u);
  if (k * l + b >= tag[u].first * l + tag[u].second &&
      k * r + b >= tag[u].first * r + tag[u].second)
    return tag[u] = {k, b}, void();
  if (l == r || (k * l + b < tag[u].first * l + tag[u].second &&
                 k * r + b < tag[u].first * r + tag[u].second))
    return;
  int mid = (l + r) >> 1;
  insert(k, b, u << 1, l, mid), insert(k, b, u << 1 | 1, mid + 1, r);
}
long long query(long long x, int u = 1, int l = 1, int r = n) {
  cls(u);
  if (l == r) return tag[u].first * x + tag[u].second;
  int mid = (l + r) >> 1;
  return max(
      tag[u].first * x + tag[u].second,
      x <= mid ? query(x, u << 1, l, mid) : query(x, u << 1 | 1, mid + 1, r));
}
void clear() { ++totim; }
}  // namespace seg
void Size(int u, int p) {
  sz[u] = 1, sm[u] = 0;
  for (int v : g[u])
    if (v != p && !Cut[v])
      Size(v, u), sz[u] += sz[v], sm[u] = max(sm[u], sz[v]);
}
int Core(int u, int p, int T) {
  int c = u;
  for (int v : g[u])
    if (v != p && !Cut[v]) {
      int x = Core(v, u, T);
      if (max(sm[c], T - sz[c]) > max(sm[x], T - sz[x])) c = x;
    }
  return c;
}
void dfs(int u, int p, vector<pair<long long, long long> >& v1,
         vector<pair<long long, long long> >& v2, int dep, long long x1,
         long long x2, long long x3) {
  x1 += dep * a[u], x2 += a[u], x3 += x2, v1.push_back({x3, dep}),
      v2.push_back({x1, x2});
  for (int v : g[u])
    if (v != p && !Cut[v]) dfs(v, u, v1, v2, dep + 1, x1, x2, x3);
}
void Solve(int u, int p) {
  Size(u, p);
  int core = Core(u, p, sz[u]);
  vector<vector<pair<long long, long long> > > v1, v2;
  for (int v : g[core])
    if (!Cut[v]) {
      vector<pair<long long, long long> > t1, t2;
      dfs(v, core, t1, t2, 1, 0, 0, 0), v1.push_back(t1), v2.push_back(t2);
    }
  seg::clear();
  for (int i = 0; i < int(v1.size()); ++i) {
    for (auto& x : v1[i])
      ans = max(ans,
                seg::query(x.second + 1) + x.first + a[core] * (x.second + 1));
    for (auto& x : v2[i]) seg::insert(x.second, x.first);
  }
  seg::clear();
  for (int i = int(v1.size()) - 1; i >= 0; --i) {
    for (auto& x : v1[i])
      ans = max(ans,
                seg::query(x.second + 1) + x.first + a[core] * (x.second + 1));
    for (auto& x : v2[i]) seg::insert(x.second, x.first);
  }
  Cut[core] = 1;
  for (int v : g[core])
    if (!Cut[v]) Solve(v, core);
}
int main() {
  cin >> n;
  for (int i = (1); i <= (n - 1); ++i) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int i = (1); i <= (n); ++i) {
    cin >> a[i];
  }
  Solve(1, 0);
  if (n == 2) ans = max(a[1] * 2 + a[2], a[1] + a[2] * 2);
  cout << ans << endl;
  return 0;
}
