#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7, M = 1e6 + 7;
int n;
int dead[N], sz[N], hei[N];
long long a[N], suf[N];
vector<int> adj[N];
long long ans;
int root = 0, nowa;
vector<pair<int, pair<long long, long long> > > hull;
vector<pair<long long, long long> > queries;
vector<int> his;
struct line {
  long long x, b;
  line() { x = 0LL, b = 4e18; }
  line(long long _x, long long _b) {
    x = _x;
    b = _b;
  }
  long long eval(long long X) { return 1LL * X * x + b; }
} c[M << 1];
void update(line r, int node = 1, long long L = 1, long long R = N) {
  long long m = (L + R) >> 1;
  bool le = (c[node].eval(L) > r.eval(L));
  bool mid = (c[node].eval(m) > r.eval(m));
  his.push_back(node);
  if (mid) swap(c[node], r);
  if (L == R - 1) return;
  if (le == mid)
    update(r, node * 2 + 1, m, R);
  else
    update(r, node * 2, L, m);
}
long long query(long long x, int node = 1, long long L = 1, long long R = N) {
  long long m = (L + R) >> 1;
  long long evalx = c[node].eval(x);
  if (R - L == 1) return evalx;
  if (x < m) {
    return min(evalx, query(x, node * 2, L, m));
  } else {
    return min(evalx, query(x, node * 2 + 1, m, R));
  }
}
int dfz(int x, int p) {
  sz[x] = 1;
  if (x == p) {
    hei[x] = 0;
    suf[x] = 0;
  }
  hei[x] = hei[p] + 1;
  suf[x] = suf[p] + a[x];
  for (auto u : adj[x]) {
    if (u == p || dead[u]) continue;
    sz[x] += dfz(u, x);
  }
  return sz[x];
}
int cen(int x, int p, int siz) {
  for (auto u : adj[x]) {
    if (u == p || dead[u]) continue;
    if (sz[u] > siz / 2) return cen(u, x, siz);
  }
  return x;
}
void dfs1(int x, int p, long long pre) {
  pre += suf[x];
  ans = max(ans, pre);
  ans = max(ans, (hei[x] + 1) * suf[x] - pre);
  for (auto u : adj[x]) {
    if (u == p || dead[u]) continue;
    dfs1(u, x, pre);
  }
}
long long get(int x) {
  long long ret = 0;
  for (auto u : hull) {
    if (nowa == u.first) continue;
    ret = max(ret, u.second.first * x + u.second.second);
  }
  return ret;
}
void dfa(int x, int p, long long pre) {
  pre += suf[x] - a[root];
  hull.push_back({nowa, {hei[x], pre + a[root] * hei[x]}});
  queries.push_back({suf[x] - a[root], (suf[x] - a[root]) * hei[x] - pre});
  for (auto u : adj[x]) {
    if (u == p || dead[u]) continue;
    dfa(u, x, pre);
  }
}
void hullc() {
  for (auto u : his) {
    c[u] = line();
  }
  his.clear();
}
void solve(int x) {
  root = x;
  dfz(x, x);
  hull.clear();
  queries.clear();
  hullc();
  dfs1(x, x, 0LL);
  for (auto u : adj[x]) {
    if (dead[u]) continue;
    nowa = u;
    dfa(u, x, 0LL);
  }
  int ls = hull[0].first, j = 0;
  for (int i = 0; i < (int)hull.size(); i++) {
    while (ls != hull[i].first && j < i) {
      update(line(-hull[j].second.first, -hull[j].second.second));
      j++;
    }
    ans = max(ans, -query(queries[i].first) + queries[i].second);
    ls = hull[i].first;
  }
  hullc();
  ls = hull[(int)hull.size() - 1].first, j = (int)hull.size() - 1;
  for (int i = (int)hull.size() - 1; i >= 0; i--) {
    while (ls != hull[i].first && j > i) {
      update(line(-hull[j].second.first, -hull[j].second.second));
      j--;
    }
    ans = max(ans, -query(queries[i].first) + queries[i].second);
    ls = hull[i].first;
  }
}
void decom(int x) {
  dfz(x, x);
  int center = cen(x, x, sz[x]);
  solve(center);
  dead[center] = 1;
  for (auto u : adj[center]) {
    if (dead[u]) continue;
    decom(u);
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (int i = 1; i <= n; i++) cin >> a[i];
  decom(1);
  cout << ans;
  return 0;
}
