#include <bits/stdc++.h>
using namespace std;
const int MAXN = 15e4;
const long long INF = 4e18;
int N;
vector<int> adj[MAXN + 10];
long long A[MAXN + 10];
struct Node {
  long long a, b;
  Node *lc, *rc;
  Node() : lc(NULL), rc(NULL), a(0), b(-INF) {}
  ~Node() {
    if (lc != NULL) delete lc;
    if (rc != NULL) delete rc;
  }
};
void update(Node *node, long long tl, long long tr, long long a, long long b) {
  long long fl = node->a * tl + node->b, fr = node->a * tr + node->b;
  long long nfl = a * tl + b, nfr = a * tr + b;
  if (fl >= nfl && fr >= nfr) return;
  if (nfl >= fl && nfr >= fr) {
    node->a = a;
    node->b = b;
    return;
  }
  long long mid = tl + tr >> 1ll;
  if (node->lc == NULL) node->lc = new Node();
  if (node->rc == NULL) node->rc = new Node();
  update(node->lc, tl, mid, a, b);
  update(node->rc, mid + 1, tr, a, b);
}
long long query(Node *node, long long tl, long long tr, long long x) {
  if (node == NULL) return -INF;
  long long mid = tl + tr >> 1ll;
  if (x <= mid)
    return max(node->a * x + node->b, query(node->lc, tl, mid, x));
  else
    return max(node->a * x + node->b, query(node->rc, mid + 1, tr, x));
}
Node *root;
int sz[MAXN + 10], del[MAXN + 10];
long long ans;
void getsz(int now, int bef) {
  sz[now] = 1;
  for (int nxt : adj[now]) {
    if (nxt == bef) continue;
    if (del[nxt]) continue;
    getsz(nxt, now);
    sz[now] += sz[nxt];
  }
}
int getcen(int now, int bef, int p) {
  for (int nxt : adj[now]) {
    if (nxt == bef) continue;
    if (del[nxt]) continue;
    if (sz[nxt] > p / 2) return getcen(nxt, now, p);
  }
  return now;
}
void dfs1(int now, int bef, long long val, long long sum, int dep) {
  ans = max(ans, query(root, 0, N, dep) + val + sum + A[now]);
  for (auto nxt : adj[now]) {
    if (nxt == bef) continue;
    if (del[nxt]) continue;
    dfs1(nxt, now, val + sum + A[now], sum + A[now], dep + 1);
  }
}
void dfs2(int now, int bef, long long val, long long sum, int dep) {
  update(root, 0, N, sum + A[now], val + A[now] * dep);
  ans = max(ans, val + A[now] * dep);
  for (auto nxt : adj[now]) {
    if (nxt == bef) continue;
    if (del[nxt]) continue;
    dfs2(nxt, now, val + A[now] * dep, sum + A[now], dep + 1);
  }
}
void decomp(int now) {
  int i, j;
  getsz(now, now);
  now = getcen(now, now, sz[now]);
  del[now] = true;
  vector<int> chd;
  for (auto nxt : adj[now]) {
    if (del[nxt]) continue;
    chd.push_back(nxt);
  }
  root = new Node();
  for (i = 0; i < chd.size(); i++) {
    int nxt = chd[i];
    dfs1(nxt, now, 0, 0, 1);
    dfs2(nxt, now, A[now], A[now], 2);
  }
  delete root;
  root = new Node();
  for (i = chd.size() - 1; i >= 0; i--) {
    int nxt = chd[i];
    dfs1(nxt, now, 0, 0, 1);
    dfs2(nxt, now, A[now], A[now], 2);
  }
  delete root;
  for (auto nxt : chd) decomp(nxt);
}
int main() {
  int i, j;
  scanf("%d", &N);
  for (i = 1; i < N; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (i = 1; i <= N; i++) scanf("%lld", &A[i]);
  decomp(1);
  printf("%lld", ans);
}
