#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1.5e5;
__int128_t very_big;
struct Line {
  long long k, c;
  Line() = default;
  Line(long long k, long long c) : k(k), c(c) {}
  long long get(int x) { return k * x + c; }
};
struct Node {
  Node *left = nullptr, *right = nullptr;
  Line cur = {0, 0};
};
Node *Li_Chao;
Node *get_left(Node *v) {
  if (v->left) {
    return v->left;
  }
  return v->left = new Node;
}
Node *get_right(Node *v) {
  if (v->right) {
    return v->right;
  }
  return v->right = new Node;
}
void reset() { Li_Chao = new Node; }
void add(Line l, Node *v = Li_Chao, int vl = 0, int vr = MAXN) {
  int vm = (vl + vr) / 2;
  bool left = l.get(vl) > v->cur.get(vl);
  bool mid = l.get(vm) > v->cur.get(vm);
  if (mid) {
    swap(l, v->cur);
  }
  if (vr - vl == 1) {
    return;
  }
  if (left != mid) {
    add(l, get_left(v), vl, vm);
  } else {
    add(l, get_right(v), vm, vr);
  }
}
long long get(int x, Node *v = Li_Chao, int vl = 0, int vr = MAXN) {
  long long ans = v->cur.get(x);
  if (vr - vl == 1) {
    return ans;
  }
  int vm = (vl + vr) / 2;
  if (x < vm) {
    return max(ans, get(x, get_left(v), vl, vm));
  } else {
    return max(ans, get(x, get_left(v), vl, vm));
  }
}
vector<int> g[MAXN];
bitset<MAXN> used;
int cost[MAXN];
int cur_size;
int find_centroid(int v, int &centroid, int prev = -1) {
  int sum = 1;
  for (auto &u : g[v]) {
    if (!used[u] && u != prev) {
      sum += find_centroid(u, centroid, v);
    }
  }
  if (centroid == -1 && (2 * sum >= cur_size || prev == -1)) {
    centroid = v;
  }
  return sum;
}
long long ans = 0;
void dfs1(int v, int prev = -1, int depth = 1, long long sum = 0,
          long long f = 0) {
  sum += cost[v];
  f += depth * 1LL * cost[v];
  ans = max(ans, f);
  add(Line(sum, f));
  for (auto &u : g[v]) {
    if (u != prev && !used[u]) {
      dfs1(u, v, depth + 1, sum, f);
    }
  }
}
void dfs2(int v, int prev = -1, int depth = 1, long long sum = 0,
          long long f = 0) {
  sum += cost[v];
  f += sum;
  ans = max(ans, get(depth) + f);
  for (auto &u : g[v]) {
    if (!used[u] && u != prev) {
      dfs2(u, v, depth + 1, sum, f);
    }
  }
}
void solve(int size, int v = 0) {
  cur_size = size;
  int centroid = -1;
  find_centroid(v, centroid);
  used[centroid] = true;
  reset();
  add(Line(cost[centroid], cost[centroid]));
  for (auto &u : g[centroid]) {
    if (!used[u]) {
      dfs2(u);
      dfs1(u, centroid, 2, cost[centroid], cost[centroid]);
    }
  }
  reset();
  add(Line(cost[centroid], cost[centroid]));
  for (int i = (int)(g[centroid].size()) - 1; i >= 0; i--) {
    int u = g[centroid][i];
    if (!used[u]) {
      dfs2(u);
      dfs1(u, centroid, 2, cost[centroid], cost[centroid]);
    }
  }
  for (auto &u : g[centroid]) {
    if (!used[u]) {
      solve(size / 2, u);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n;
  cin >> n;
  for (int i = 1; i < n; i++) {
    int v, u;
    cin >> v >> u;
    g[v - 1].emplace_back(u - 1);
    g[u - 1].emplace_back(v - 1);
  }
  for (int i = 0; i < n; i++) {
    cin >> cost[i];
  }
  solve(n);
  cout << ans << '\n';
  return 0;
}
