#include <bits/stdc++.h>
using namespace std;
long long dot(complex<long long> a, complex<long long> b) {
  return (conj(a) * b).real();
}
long long f(complex<long long> a, long long real) { return dot(a, {real, 1}); }
const long long maxn = 2e5;
complex<long long> line[4 * maxn];
bool usedT[4 * maxn];
void line_clear(int v = 1, long long l = 0, long long r = maxn) {
  if (!usedT[v]) return;
  usedT[v] = false;
  line[v] = complex<long long>(0ll, 0ll);
  if (l < r - 1) {
    int m = (l + r) / 2;
    line_clear(v * 2, l, m);
    line_clear(v * 2 + 1, m, r);
  }
}
void add_line(complex<long long> nw, int v = 1, long long l = 0,
              long long r = maxn) {
  usedT[v] = true;
  int m = (l + r) / 2;
  bool lef = f(nw, l) > f(line[v], l);
  bool mid = f(nw, m) > f(line[v], m);
  if (mid) {
    swap(line[v], nw);
  }
  if (r - l == 1) {
    return;
  } else if (lef != mid) {
    add_line(nw, 2 * v, l, m);
  } else {
    add_line(nw, 2 * v + 1, m, r);
  }
}
long long get(int real, int v = 1, long long l = 0, long long r = maxn) {
  int m = (l + r) / 2;
  if (r - l == 1) {
    return f(line[v], real);
  } else if (real < m) {
    return max(f(line[v], real), get(real, 2 * v, l, m));
  } else {
    return max(f(line[v], real), get(real, 2 * v + 1, m, r));
  }
}
vector<int> graph[150010];
int visited_cen[150010];
long long subtrees[150010];
long long a[150010];
int n;
void subtree_comp(int u, int p) {
  int total = 1;
  for (int v : graph[u]) {
    if (v != p && visited_cen[v] == 0) {
      subtree_comp(v, u);
      total += subtrees[v];
    }
  }
  subtrees[u] = total;
}
int findCentroid(int u, int p, int tree_size) {
  for (int v : graph[u]) {
    if (v != p && subtrees[v] > tree_size / 2 && visited_cen[v] == 0)
      return findCentroid(v, u, tree_size);
  }
  return u;
}
struct leaf {
  long long length;
  long long sum;
  long long sumSumD;
  long long sumSumU;
};
vector<leaf> leaves;
vector<vector<leaf> > leaves2;
long long length[150010];
long long sum[150010];
long long sumSumD[150010];
long long sumSumU[150010];
void dfs(int u, int p) {
  for (int v : graph[u]) {
    if (v != p && visited_cen[v] == 0) {
      length[v] = length[u] + 1;
      sum[v] = sum[u] + a[v];
      sumSumD[v] = sumSumD[u] + sum[v];
      sumSumU[v] = length[v] * a[v] + sumSumU[u];
      dfs(v, u);
    }
  }
  if (subtrees[u] == 1)
    leaves.push_back(leaf{length[u], sum[u], sumSumD[u], sumSumU[u]});
}
void dfs_clear(int u, int p) {
  sum[u] = 0;
  sumSumD[u] = 0;
  sumSumU[u] = 0;
  length[u] = 0;
  for (int v : graph[u]) {
    if (v != p && visited_cen[v] == 0) dfs_clear(v, u);
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int real, imag;
    cin >> real >> imag;
    graph[real].push_back(imag);
    graph[imag].push_back(real);
  }
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  subtree_comp(1, 0);
  queue<int> q;
  q.push(findCentroid(1, 0, subtrees[1]));
  long long ans = 0;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    if (visited_cen[u] == 1) continue;
    subtree_comp(u, 0);
    for (int v : graph[u]) {
      if (visited_cen[v] == 1) continue;
      length[v] = 2;
      sum[v] = a[v];
      sumSumD[v] = a[v];
      sumSumU[v] = 2 * a[v] + a[u];
      dfs(v, u);
      vector<leaf> temp;
      for (leaf l : leaves) {
        temp.push_back(l);
      }
      leaves2.push_back(temp);
      leaves.clear();
    }
    if (leaves2.size() == 0)
      ans = max(ans, a[u]);
    else if (leaves2.size() == 1) {
      for (leaf l : leaves2[0]) {
        ans = max(ans, max(l.sumSumU, l.sumSumD + l.length * a[u]));
      }
    }
    for (int i = 0; i < leaves2.size(); i++) {
      for (leaf l : leaves2[i]) {
        ans = max(ans, get(l.length - 1) + l.sumSumD);
      }
      for (leaf l : leaves2[i]) {
        add_line(complex<long long>(l.sum + a[u], l.sumSumU));
      }
    }
    line_clear();
    for (int i = leaves2.size() - 1; i >= 0; i--) {
      for (leaf l : leaves2[i]) {
        ans = max(ans, get(l.length - 1) + l.sumSumD);
      }
      for (leaf l : leaves2[i]) {
        add_line(complex<long long>(l.sum + a[u], l.sumSumU));
      }
    }
    leaves2.clear();
    line_clear();
    dfs_clear(u, 0);
    visited_cen[u] = 1;
    for (int v : graph[u]) {
      if (visited_cen[v] == 0) q.push(findCentroid(v, 0, subtrees[v]));
    }
  }
  cout << ans << endl;
}
