#include <bits/stdc++.h>   using namespace std;   inline int read() {     static char buf[1 << 21], *p1, *p2;     int f = 0, c = 1;     char ch =         (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)              ? EOF              : *p1++);     while (ch <  0  || ch >  9 ) {       if (ch ==  - ) c = -1;       ch =           (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)                ? EOF                : *p1++);     }     while (ch >=  0  && ch <=  9 ) {       f = f * 10 + ch -  0 ;       ch =           (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)                ? EOF                : *p1++);     }     return c * f;   }   const int M = 3e5 + 10;   struct node {     long long k, b;     inline long long operator()(const long long &x) { return x * k + b; }     node(long long x = 0, long long y = 0) { k = x, b = y; }   } e, f[M * 4];   vector<int> v[M];   int fa[M], siz[M], mx[M], dep[M], belong[M], vis[M];   long long v1[M], v2[M], st[M], l[M], a[M], s[M];   int sz, n, x, y, md, top, rt;   long long ans;   void build(int o, int l, int r) {     f[o] = (node){0, 0};     if (l == r) return;     build((o << 1), l, ((l + r) >> 1));     build((o << 1 | 1), ((l + r) >> 1) + 1, r);   }   long long ask(int o, int l, int r, long long x) {     long long ans = f[o](x);     if (l == r) return ans;     if (x <= ((l + r) >> 1))       return max(ans, ask((o << 1), l, ((l + r) >> 1), x));     else       return max(ans, ask((o << 1 | 1), ((l + r) >> 1) + 1, r, x));   }   void insert(int o, int l, int r, node x) {     if (f[o](((l + r) >> 1)) < x(((l + r) >> 1))) swap(f[o], x);     if (l == r) return;     if (x.k < f[o].k)       insert((o << 1), l, ((l + r) >> 1), x);     else       insert((o << 1 | 1), ((l + r) >> 1) + 1, r, x);   }   void getroot(int x, int fa) {     siz[x] = 1;     mx[x] = 0;     for (int i = 0; i < v[x].size(); ++i) {       int y = v[x][i];       if (y == fa || vis[y]) continue;       getroot(y, x);       siz[x] += siz[y];       mx[x] = max(mx[x], siz[y]);     }     mx[x] = max(mx[x], sz - siz[x]);     if (mx[x] < mx[rt]) rt = x;   }   void dfs(int x, int fa, long long val1, long long val2, long long sum,            int from) {     if (x != rt && !from) from = x;     dep[x] = dep[fa] + 1;     md = max(md, dep[x]);     int f = 0;     siz[x] = 1;     for (int i = 0; i < v[x].size(); ++i) {       int y = v[x][i];       if (y == fa || vis[y]) continue;       dfs(y, x, val1 + sum + a[y], val2 + a[y] * dep[x], sum + a[y], from);       siz[x] += siz[y];       f = 1;     }     if (!f) {       st[++top] = x, v1[top] = val1, v2[top] = val2, s[top] = sum - a[rt],       l[top] = dep[x], belong[top] = from;     }   }   void dfz(int x) {     vis[x] = 1;     top = 0;     md = 0;     dfs(x, 0, a[x], 0, a[x], 0);     st[++top] = x;     v1[top] = a[x], l[top] = 1, v2[top] = s[top] = belong[top] = 0;     build(1, 1, md);     belong[top + 1] = belong[0] = -1;     for (int i = 1; i <= top;) {       int j = i;       while (belong[j] == belong[i])         ans = max(ans, ask(1, 1, md, l[j]) + v1[j]), ++j;       j = i;       while (belong[j] == belong[i]) insert(1, 1, md, node(s[j], v2[j])), ++j;       i = j;     }     build(1, 1, md);     for (int i = top; i >= 1;) {       int j = i;       while (belong[j] == belong[i])         ans = max(ans, ask(1, 1, md, l[j]) + v1[j]), --j;       j = i;       while (belong[i] == belong[j]) insert(1, 1, md, node(s[j], v2[j])), --j;       i = j;     }     for (int i = 0; i < v[x].size(); ++i) {       int y = v[x][i];       if (vis[y]) continue;       sz = siz[y];       rt = 0;       getroot(y, x);       dfz(rt);     }   }   int main() {     n = read();     for (int i = 1; i < n; ++i) {       x = read();       y = read();       v[x].push_back(y);       v[y].push_back(x);     }     for (int i = 1; i <= n; ++i) a[i] = read();     siz[0] = mx[0] = sz = n;     getroot(1, 0);     dfz(rt);     cout << ans;     return 0;   }