#include <bits/stdc++.h>
using namespace std;
char buf[1 << 21], *p1 = buf, *p2 = buf;
template <class T>
void read(T &x) {
  x = 0;
  int c = getchar();
  int flag = 0;
  while (c < '0' || c > '9') flag |= (c == '-'), c = getchar();
  while (c >= '0' && c <= '9')
    x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  if (flag) x = -x;
}
template <class T>
T _max(T a, T b) {
  return b < a ? a : b;
}
template <class T>
T _min(T a, T b) {
  return a < b ? a : b;
}
template <class T>
bool checkmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <class T>
bool checkmin(T &a, T b) {
  return b < a ? a = b, 1 : 0;
}
const int N = 150005, inf = 0x3f3f3f3f;
int n;
long long a[N];
vector<int> G[N];
long long ans = 0;
int Root = 0, Min = inf;
int siz[N];
vector<pair<long long, long long> > A, B;
void add_edge(int x, int y) { G[x].push_back(y); }
void init() {
  read(n);
  for (int i = 1, u, v; i < n; ++i) {
    read(u);
    read(v);
    add_edge(u, v);
    add_edge(v, u);
  }
  for (int i = 1; i <= n; ++i) read(a[i]);
}
void get_root(int x, int f, int tot) {
  int Max = 0;
  siz[x] = 1;
  for (int i = 0; i < (int)G[x].size(); ++i) {
    int to = G[x][i];
    if (to == f) continue;
    get_root(to, x, tot);
    siz[x] += siz[to];
    checkmax(Max, siz[to]);
  }
  checkmax(Max, tot - siz[x]);
  if (checkmin(Min, Max)) Root = x;
}
void get_size(int x, int f) {
  siz[x] = 1;
  for (int i = 0; i < (int)G[x].size(); ++i) {
    int to = G[x][i];
    if (to == f) continue;
    get_size(to, x);
    siz[x] += siz[to];
  }
}
void run1(int x, int f, long long val, long long sum, int dep) {
  sum += a[x];
  val += sum;
  ++dep;
  A.push_back(make_pair(dep, val));
  for (int i = 0; i < (int)G[x].size(); ++i) {
    int to = G[x][i];
    if (to == f) continue;
    run1(to, x, val, sum, dep);
  }
}
void run2(int x, int f, long long val, long long sum, int dep) {
  sum += a[x];
  val += a[x] * dep;
  B.push_back(make_pair(sum, val));
  for (int i = 0; i < (int)G[x].size(); ++i) {
    int to = G[x][i];
    if (to == f) continue;
    run2(to, x, val, sum, dep + 1);
  }
}
bool check(pair<long long, long long> a, pair<long long, long long> b,
           pair<long long, long long> c) {
  return (c.first - b.first) * (a.second - b.second) -
             (c.second - b.second) * (a.first - b.first) >=
         0;
}
void doit() {
  if (A.empty() || B.empty()) return;
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  vector<pair<long long, long long> > P;
  for (int i = 0; i < (int)A.size(); ++i) {
    while ((int)P.size() >= 2 &&
           check(P[(int)P.size() - 2], P[(int)P.size() - 1], A[i]))
      P.pop_back();
    P.push_back(A[i]);
  }
  int now = 0;
  for (int i = 0; i < (int)B.size(); ++i) {
    while (now + 1 < (int)P.size() &&
           B[i].first * P[now + 1].first + P[now + 1].second >=
               B[i].first * P[now].first + P[now].second)
      ++now;
    checkmax(ans, B[i].first * P[now].first + P[now].second + B[i].second);
  }
}
void dfs(int x, int Size) {
  if (Size == 1) {
    checkmax(ans, a[x]);
    return;
  }
  Min = inf;
  Root = 0;
  get_root(x, 0, Size);
  x = Root;
  get_size(x, 0);
  if (Size == 2) {
    checkmax(ans, a[x] + a[G[x][0]] + _max(a[x], a[G[x][0]]));
    return;
  }
  vector<int> adj = G[x];
  sort(adj.begin(), adj.end(), [](int p, int q) { return siz[p] > siz[q]; });
  int mid = 0, now = 0;
  while (mid < (int)adj.size() && siz[adj[mid]] + now <= siz[x] / 2)
    now += siz[adj[mid]], ++mid;
  A.clear();
  B.clear();
  A.push_back(make_pair(1LL, a[x]));
  for (int i = 0; i < mid; ++i) run1(adj[i], x, a[x], a[x], 1);
  for (int i = mid; i < (int)adj.size(); ++i) run2(adj[i], x, 0, 0, 1);
  doit();
  A.clear();
  B.clear();
  A.push_back(make_pair(1LL, a[x]));
  for (int i = mid; i < (int)adj.size(); ++i) run1(adj[i], x, a[x], a[x], 1);
  for (int i = 0; i < mid; ++i) run2(adj[i], x, 0, 0, 1);
  doit();
  vector<int> P(adj.begin(), adj.begin() + mid);
  G[x] = P;
  dfs(x, now + 1);
  vector<int> Q(adj.begin() + mid, adj.end());
  G[x] = Q;
  dfs(x, Size - now);
  G[x] = adj;
}
void solve() {
  dfs(1, n);
  printf("%lld\n", ans);
}
int main() {
  init();
  solve();
  return 0;
}
