#include <bits/stdc++.h>
using std::make_pair;
template <typename T>
inline T read() {
  T x = 0;
  char ch = std::getchar();
  bool f = 0;
  while (!std::isdigit(ch)) f = (ch == '-'), ch = std::getchar();
  while (std::isdigit(ch)) x = x * 10 + (ch - '0'), ch = std::getchar();
  return f ? -x : x;
}
template <typename T>
void print(T x) {
  if (x < 0) {
    x = -x;
    std::putchar('-');
  }
  if (x < 10) {
    std::putchar(x + 48);
    return;
  }
  print<T>(x / 10);
  std::putchar(x % 10 + 48);
  return;
}
namespace Solution {
using std::cin;
using std::cout;
using std::deque;
using std::endl;
using std::map;
using std::pair;
using std::queue;
using std::set;
using std::vector;
const int N = 150011, mod = 1e9 + 7, INT_INF = 0x3f3f3f3f;
const long long LONG_INF = 0x3f3f3f3f3f3f3f3f;
struct SEG {
  struct Node {
    int L, R;
    pair<long long, long long> line;
  } QS[N * 4];
  inline int ls(int k) { return k << 1; }
  inline int rs(int k) { return k << 1 | 1; }
  long long calc(pair<long long, long long> res, int pos) {
    return res.first * pos + res.second;
  }
  void insert(int k, pair<long long, long long> x) {
    if (!~QS[k].line.first) {
      QS[k].line = x;
      return;
    }
    if (QS[k].L == QS[k].R) {
      if (calc(x, QS[k].L) > calc(QS[k].line, QS[k].L)) QS[k].line = x;
      return;
    }
    int mid((QS[k].L + QS[k].R) / 2);
    long long res1(calc(x, mid)), res2(calc(QS[k].line, mid));
    if (x.first < QS[k].line.first) {
      if (res1 < res2)
        insert(ls(k), x);
      else
        insert(rs(k), QS[k].line), QS[k].line = x;
    } else {
      if (res1 < res2)
        insert(rs(k), x);
      else
        insert(ls(k), QS[k].line), QS[k].line = x;
    }
  }
  void build(int k, int l, int r) {
    QS[k].line = make_pair(-1, -1);
    QS[k].L = l;
    QS[k].R = r;
    if (l == r) return;
    int mid((l + r) / 2);
    build(ls(k), l, mid);
    build(rs(k), mid + 1, r);
  }
  long long query(int k, int pos) {
    if (!~QS[k].line.first) return -LONG_INF;
    if (QS[k].L == QS[k].R) return calc(QS[k].line, pos);
    int mid((QS[k].L + QS[k].R) / 2);
    return std::max(calc(QS[k].line, pos),
                    pos <= mid ? query(ls(k), pos) : query(rs(k), pos));
  }
} T;
int n, a[N], sz[N], S, dep[N], mxd, tot;
vector<int> v[N];
bool vis[N];
long long ans;
inline void add_edge(int x, int y) {
  v[x].push_back(y);
  v[y].push_back(x);
}
int find_center(int u, int f) {
  int rt1(0), mx(0);
  sz[u] = 1;
  for (auto &i : v[u]) {
    if (i ^ f && !vis[i]) {
      rt1 = std::max(find_center(i, u), rt1);
      sz[u] += sz[i];
      mx = std::max(sz[i], mx);
    }
  }
  if (S / 2 >= std::max(mx, S - sz[u])) rt1 = u;
  return rt1;
}
struct Path {
  long long sum1, sum2, sum;
  int fr, lst;
  Path(long long S1 = 0, long long S2 = 0, long long S = 0, int F = 0,
       int L = 0)
      : sum1(S1), sum2(S2), sum(S), fr(F), lst(L) {}
} X[N];
void dfs(int u, long long sum1, long long sum2, long long sum, int fa, int fr) {
  mxd = std::max(dep[u] = dep[fa] + (sz[u] = 1), mxd);
  if (fa && !fr) fr = u;
  for (auto &i : v[u]) {
    if (fa ^ i && !vis[i]) {
      dfs(i, sum1 + sum + a[i], sum2 + (long long)dep[u] * a[i], sum + a[i], u,
          fr);
      sz[u] += sz[i];
    }
  }
  if (sz[u] == 1) X[++tot] = Path(sum1, sum2, sum, fr, dep[u]);
}
void solve(int u) {
  vis[u] = 1;
  X[tot = 0] = Path(a[u], 0, a[u], 0, 1);
  dfs(u, a[u], 0, a[u], mxd = 0, 0);
  T.build(1, 1, mxd);
  for (int i = 0, j; i <= tot; i = j) {
    for (j = i; j <= tot && X[j].fr == X[i].fr; ++j)
      ans = std::max(ans, T.query(1, X[j].lst) + X[j].sum1);
    for (j = i; j <= tot && X[j].fr == X[i].fr; ++j)
      T.insert(1, make_pair(X[j].sum - a[u], X[j].sum2));
  }
  T.build(1, 1, mxd);
  for (int i = tot, j; ~i; i = j) {
    for (j = i; ~j && X[j].fr == X[i].fr; --j)
      ans = std::max(ans, T.query(1, X[j].lst) + X[j].sum1);
    for (j = i; ~j && X[j].fr == X[i].fr; --j)
      T.insert(1, make_pair(X[j].sum - a[u], X[j].sum2));
  }
  for (auto &i : v[u]) {
    if (!vis[i]) {
      S = sz[i];
      int rt = find_center(i, u);
      solve(rt);
    }
  }
}
void Fakemain() {
  n = read<int>();
  for (int i = 2; i <= n; ++i) add_edge(read<int>(), read<int>());
  for (int i = 1; i <= n; ++i) a[i] = read<int>();
  S = n;
  int rt = find_center(1, 0);
  solve(rt);
  print<long long>(ans), putchar(' ');
  return;
}
}  // namespace Solution
int main(int argc, char *argv[]) {
  Solution::Fakemain();
  return 0;
}
