#include <bits/stdc++.h>
using namespace std;
const long long N = 2e5 + 4, LOG = 18;
long long n, a[N], res;
vector<long long> adj[N];
long long numChild[N], Banish[N], total;
void DFS_getnumChild(long long dad, long long u) {
  numChild[u] = 1;
  for (long long v : adj[u])
    if (v != dad && !Banish[v]) {
      DFS_getnumChild(u, v);
      numChild[u] += numChild[v];
    }
}
long long getCentroid(long long dad, long long u) {
  for (long long v : adj[u])
    if (v != dad && !Banish[v])
      if (2 * numChild[v] >= total) return getCentroid(u, v);
  return u;
}
long long hei[N], maxHei;
void DFS_getHei(long long dad, long long u) {
  for (long long v : adj[u])
    if (v != dad && !Banish[v]) {
      hei[v] = hei[u] + 1;
      maxHei = max(maxHei, hei[v]);
      DFS_getHei(u, v);
    }
}
struct Line {
  long long a, b;
  Line(){};
  Line(long long a, long long b) : a(a), b(b){};
  long long getVal(long long x) { return a * x + b; }
};
struct Line_Interval_Tree {
  Line node[4 * N];
  void Clear(long long i, long long l, long long r) {
    node[i] = Line(0, 0);
    if (l == r) return;
    long long mid = (l + r) / 2;
    Clear(2 * i, l, mid);
    Clear(2 * i + 1, mid + 1, r);
  }
  void update(long long i, long long l, long long r, long long x, long long y,
              Line val) {
    if (l > y || x > r) return;
    if (x <= l && r <= y) {
      long long mid = (l + r) / 2;
      if (val.getVal(l) <= node[i].getVal(l) &&
          val.getVal(r) <= node[i].getVal(r))
        return;
      if (val.getVal(l) >= node[i].getVal(r) &&
          val.getVal(r) >= node[i].getVal(r)) {
        node[i] = val;
        return;
      }
      if (val.getVal(l) <= node[i].getVal(l) &&
          val.getVal(mid) <= node[i].getVal(mid)) {
        update(2 * i + 1, mid + 1, r, x, y, val);
        return;
      }
      if (val.getVal(l) >= node[i].getVal(l) &&
          val.getVal(mid) >= node[i].getVal(mid)) {
        update(2 * i + 1, mid + 1, r, x, y, node[i]);
        node[i] = val;
        return;
      }
      if (val.getVal(mid + 1) <= node[i].getVal(mid + 1) &&
          val.getVal(r) <= node[i].getVal(r)) {
        update(2 * i, l, mid, x, y, val);
        return;
      }
      if (val.getVal(mid + 1) >= node[i].getVal(mid + 1) &&
          val.getVal(r) >= node[i].getVal(r)) {
        update(2 * i, l, mid, x, y, node[i]);
        node[i] = val;
        return;
      }
    }
    long long mid = (l + r) / 2;
    update(2 * i, l, mid, x, y, val);
    update(2 * i + 1, mid + 1, r, x, y, val);
  }
  long long get(long long i, long long l, long long r, long long x) {
    if (l > x || x > r) return 0;
    long long res = node[i].getVal(x), mid = (l + r) / 2;
    if (l != r)
      res = max({res, get(2 * i, l, mid, x), get(2 * i + 1, mid + 1, r, x)});
    return res;
  }
} IT;
void DFS_get(long long dad, long long u, long long partial, long long sum) {
  long long val = IT.get(1, 0, maxHei, hei[u]) + partial;
  res = max(res, val);
  for (long long v : adj[u])
    if (v != dad && !Banish[v]) DFS_get(u, v, partial + sum + a[v], sum + a[v]);
}
void DFS_update(long long dad, long long u, long long A, long long B) {
  IT.update(1, 0, maxHei, 0, maxHei, Line(A, B));
  for (long long v : adj[u])
    if (v != dad && !Banish[v])
      DFS_update(u, v, A + a[v], B + a[v] * (hei[v] + 1));
}
void process(long long dad, long long u) {
  maxHei = hei[u] = 0;
  DFS_getHei(dad, u);
  IT.Clear(1, 0, maxHei);
  IT.update(1, 0, maxHei, 0, maxHei, Line(a[u], a[u]));
  for (long long v : adj[u])
    if (v != dad && !Banish[v]) {
      DFS_get(u, v, a[v], a[v]);
      DFS_update(u, v, a[u] + a[v], a[u] + 2 * a[v]);
    }
  reverse(adj[u].begin(), adj[u].end());
  IT.Clear(1, 0, maxHei);
  IT.update(1, 0, maxHei, 0, maxHei, Line(a[u], a[u]));
  for (long long v : adj[u])
    if (v != dad && !Banish[v]) {
      DFS_get(u, v, a[v], a[v]);
      DFS_update(u, v, a[u] + a[v], a[u] + 2 * a[v]);
    }
}
void Centroid_Decompose(long long dad, long long u) {
  DFS_getnumChild(dad, u);
  total = numChild[u];
  long long centroid = getCentroid(dad, u);
  process(dad, centroid);
  Banish[centroid] = true;
  for (long long v : adj[centroid])
    if (v != dad && !Banish[v]) Centroid_Decompose(centroid, v);
}
void sol() {
  Centroid_Decompose(0, 1);
  cout << res << '\n';
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  if (fopen("input.txt", "r")) {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
  }
  cin >> n;
  for (long long i = 1; i < (long long)n; ++i) {
    long long u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (long long i = 1; i <= (long long)n; ++i) cin >> a[i];
  sol();
  return 0;
}
