#include <bits/stdc++.h>
using namespace std;
vector<int> v[150005];
int Size[150005];
int forbid[150005];
int val[150005];
vector<int> stk;
void dfs(int first, int f) {
  Size[first] = 1;
  stk.push_back(first);
  for (auto it : v[first]) {
    if (it != f && !forbid[it]) {
      dfs(it, first);
      Size[first] += Size[it];
    }
  }
}
bool cmp(const int &a, const int &b) { return Size[a] < Size[b]; }
int find_cen(int first) {
  stk.clear();
  dfs(first, 0);
  sort(stk.begin(), stk.end(), cmp);
  for (auto it : stk) {
    if (Size[it] >= Size[first] / 2) {
      return it;
    }
  }
}
long long ans;
vector<pair<long long, long long> > vv;
void dfs2(int first, int f, long long sum, long long sum2, long long len) {
  sum += val[first];
  sum2 += sum;
  vv.push_back(make_pair(len, sum2));
  for (auto it : v[first]) {
    if (it != f && !forbid[it]) {
      dfs2(it, first, sum, sum2, len + 1);
    }
  }
}
void dfs3(int first, int f, long long sum, long long sum2, long long len) {
  sum += val[first];
  sum2 += val[first] * len;
  vv.push_back(make_pair(sum, sum2));
  for (auto it : v[first]) {
    if (it != f && !forbid[it]) {
      dfs3(it, first, sum, sum2, len + 1);
    }
  }
}
struct DATA {
  long long first, second, st;
};
int op;
bool operator<(const DATA &p, const DATA &q) {
  if (op == 0)
    return p.first < q.first;
  else
    return p.st < q.st;
}
void go(int first) {
  int cen = find_cen(first);
  set<DATA> s;
  for (int t = 0; t < 2; t++) {
    s.insert({0, 0, -1000000000});
    for (auto first : v[cen]) {
      if (forbid[first]) continue;
      dfs2(first, cen, val[cen], val[cen], 2);
      op = 1;
      for (auto p : vv) {
        if (s.empty()) break;
        auto it = prev(s.upper_bound({0, 0, p.first}));
        ans = max(ans, p.first * it->first + it->second + p.second);
      }
      vv.clear();
      dfs3(first, cen, 0, 0, 1);
      op = 0;
      for (auto p : vv) {
        auto it = s.lower_bound({p.first, p.second, 0});
        if (it != s.end() && it->first == p.first) {
          if (it->second > p.second)
            continue;
          else {
            s.erase(*it);
            it = s.lower_bound({p.first, p.second, 0});
          }
        }
        while (it != s.end()) {
          DATA d = *it;
          auto it2 = next(it);
          s.erase(it);
          it = it2;
          long long st = (p.second - d.second) / (d.first - p.first);
          d.st = st;
          if (it == s.end() || it->st > st) {
            s.insert(d);
            break;
          }
        }
        it = s.lower_bound({p.first, p.second, 0});
        int st = -1e9;
        while (it != s.begin()) {
          DATA d = *prev(it);
          st = (d.second - p.second) / (p.first - d.first);
          if (st <= d.st) {
            s.erase(d);
          } else {
            break;
          }
        }
        if (it == s.end() || it->st > st) s.insert({p.first, p.second, st});
      }
      vv.clear();
    }
    reverse(v[cen].begin(), v[cen].end());
    s.clear();
  }
  forbid[cen] = 1;
  for (auto it : v[cen]) {
    if (!forbid[it]) {
      go(it);
    }
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int first, second;
    scanf("%d %d", &first, &second);
    v[first].push_back(second);
    v[second].push_back(first);
  }
  for (int i = 1; i <= n; i++) scanf("%d", &val[i]);
  go(1);
  printf("%lld\n", ans);
}
