#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 200000;
int n;
ll a[MAXN+1];
vector<int> adj[MAXN+1];
ll sumA[MAXN+1]; // sum of a[] in subtree
ll distSum[MAXN+1]; // weighted distance sum at each root
ll totalA = 0;
ll answer = LLONG_MIN;
// First DFS: compute sumA[u] and distSum[1] (rooted at 1)
void dfs1(int u, int p, int depth) {
sumA[u] = a[u];
distSum[1] += a[u] * depth;
for (int v : adj[u]) {
if (v == p) continue;
dfs1(v, u, depth + 1);
sumA[u] += sumA[v];
}
}
// Second DFS: reroot from u to v
void dfs2(int u, int p) {
// update answer at u
answer = max(answer, distSum[u]);
for (int v : adj[u]) {
if (v == p) continue;
// when rerooting from u -> v:
// nodes in v-subtree get distance -1 each (sumA[v])
// nodes outside v-subtree get distance +1 each (totalA - sumA[v])
distSum[v] = distSum[u] + totalA - 2*sumA[v];
dfs2(v, u);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
totalA += a[i];
}
for (int i = 0; i < n-1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
// 1) dfs1 computes sumA[] and distSum[1]
dfs1(1, 0, 0);
// 2) dfs2 reroots and fills distSum[u] for all u
dfs2(1, 0);
// Each cost is distSum[u], but original problem multiplies by a_v?
// Actually cost is sum_i dist(i,v)*a_i = distSum[v].
// If the problem wanted a_v * that, replace answer = max(answer, a[u]*distSum[u]);
cout << answer << "\n";
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnVzaW5nIGxsID0gbG9uZyBsb25nOwoKY29uc3QgaW50IE1BWE4gPSAyMDAwMDA7CgppbnQgbjsKbGwgYVtNQVhOKzFdOwp2ZWN0b3I8aW50PiBhZGpbTUFYTisxXTsKbGwgc3VtQVtNQVhOKzFdOyAgICAgIC8vIHN1bSBvZiBhW10gaW4gc3VidHJlZQpsbCBkaXN0U3VtW01BWE4rMV07ICAgLy8gd2VpZ2h0ZWQgZGlzdGFuY2Ugc3VtIGF0IGVhY2ggcm9vdApsbCB0b3RhbEEgPSAwOwpsbCBhbnN3ZXIgPSBMTE9OR19NSU47CgovLyBGaXJzdCBERlM6IGNvbXB1dGUgc3VtQVt1XSBhbmQgZGlzdFN1bVsxXSAocm9vdGVkIGF0IDEpCnZvaWQgZGZzMShpbnQgdSwgaW50IHAsIGludCBkZXB0aCkgewogICAgc3VtQVt1XSA9IGFbdV07CiAgICBkaXN0U3VtWzFdICs9IGFbdV0gKiBkZXB0aDsKICAgIGZvciAoaW50IHYgOiBhZGpbdV0pIHsKICAgICAgICBpZiAodiA9PSBwKSBjb250aW51ZTsKICAgICAgICBkZnMxKHYsIHUsIGRlcHRoICsgMSk7CiAgICAgICAgc3VtQVt1XSArPSBzdW1BW3ZdOwogICAgfQp9CgovLyBTZWNvbmQgREZTOiByZXJvb3QgZnJvbSB1IHRvIHYKdm9pZCBkZnMyKGludCB1LCBpbnQgcCkgewogICAgLy8gdXBkYXRlIGFuc3dlciBhdCB1CiAgICBhbnN3ZXIgPSBtYXgoYW5zd2VyLCBkaXN0U3VtW3VdKTsKICAgIGZvciAoaW50IHYgOiBhZGpbdV0pIHsKICAgICAgICBpZiAodiA9PSBwKSBjb250aW51ZTsKICAgICAgICAvLyB3aGVuIHJlcm9vdGluZyBmcm9tIHUgLT4gdjoKICAgICAgICAvLyBub2RlcyBpbiB2LXN1YnRyZWUgZ2V0IGRpc3RhbmNlIC0xIGVhY2ggKHN1bUFbdl0pCiAgICAgICAgLy8gbm9kZXMgb3V0c2lkZSB2LXN1YnRyZWUgZ2V0IGRpc3RhbmNlICsxIGVhY2ggKHRvdGFsQSAtIHN1bUFbdl0pCiAgICAgICAgZGlzdFN1bVt2XSA9IGRpc3RTdW1bdV0gKyB0b3RhbEEgLSAyKnN1bUFbdl07CiAgICAgICAgZGZzMih2LCB1KTsKICAgIH0KfQoKaW50IG1haW4oKXsKICAgIGlvczo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKICAgIGNpbi50aWUobnVsbHB0cik7CgogICAgY2luID4+IG47CiAgICBmb3IgKGludCBpID0gMTsgaSA8PSBuOyBpKyspIHsKICAgICAgICBjaW4gPj4gYVtpXTsKICAgICAgICB0b3RhbEEgKz0gYVtpXTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbi0xOyBpKyspIHsKICAgICAgICBpbnQgdSwgdjsKICAgICAgICBjaW4gPj4gdSA+PiB2OwogICAgICAgIGFkalt1XS5wdXNoX2JhY2sodik7CiAgICAgICAgYWRqW3ZdLnB1c2hfYmFjayh1KTsKICAgIH0KCiAgICAvLyAxKSBkZnMxIGNvbXB1dGVzIHN1bUFbXSBhbmQgZGlzdFN1bVsxXQogICAgZGZzMSgxLCAwLCAwKTsKCiAgICAvLyAyKSBkZnMyIHJlcm9vdHMgYW5kIGZpbGxzIGRpc3RTdW1bdV0gZm9yIGFsbCB1CiAgICBkZnMyKDEsIDApOwoKICAgIC8vIEVhY2ggY29zdCBpcyBkaXN0U3VtW3VdLCBidXQgb3JpZ2luYWwgcHJvYmxlbSBtdWx0aXBsaWVzIGJ5IGFfdj8KICAgIC8vIEFjdHVhbGx5IGNvc3QgaXMgc3VtX2kgZGlzdChpLHYpKmFfaSA9IGRpc3RTdW1bdl0uCiAgICAvLyBJZiB0aGUgcHJvYmxlbSB3YW50ZWQgYV92ICogdGhhdCwgcmVwbGFjZSBhbnN3ZXIgPSBtYXgoYW5zd2VyLCBhW3VdKmRpc3RTdW1bdV0pOwogICAgY291dCA8PCBhbnN3ZXIgPDwgIlxuIjsKICAgIHJldHVybiAwOwp9Cg==