#include <bits/stdc++.h>
using namespace std;
#define int long long int
#define double long double
inline int power(int a, int b) {
int x = 1;
while (b) {
if (b & 1) x *= a;
a *= a;
b >>= 1;
}
return x;
}
const int M = 1000000007;
const int N = 3e5+9;
const int INF = 2e9+1;
const int LINF = 2000000000000000001;
//_ ***************************** START Below *******************************
vector<vector<int>> edges;
vector<int> coins;
//? Approach 1 : Eager deleting leaf nodes
//* We instantly delete leaf nodes
//? Algo : Topo Sort == Leaf Pruning + Smart BFS
//* Topo Sort :
//* Gurantees traversal from Leaf Nodes => Inside of graph / Tree
//* Here we are performing Multi Source BFS from Leaf nodes
//* Hence we are processing child -> parent (reverse direction)
void consistency1(int n) {
vector<vector<int>> graph(n);
for(int i=0; i<n-1; i++){
int x = edges[i][0], y = edges[i][1];
graph[x].push_back(y);
graph[y].push_back(x);
}
int removed = 0;
vector<int> degree(n);
queue<int> q;
//* Step 0 : Multi Source BFS to recursively delete all leave nodes with 0's
for(int i=0; i<n; i++){
degree[i] = graph[i].size();
if(degree[i] == 1 && coins[i] == 0){
q.push(i);
}
}
while(!q.empty()){
removed++;
auto ch = q.front(); q.pop();
int parent = -1;
//* We are processing reverse i.e. child -> parent edge
//* (not parent -> child edge )
for(auto& par : graph[ch]){
degree[par]--;
parent = par;
if(degree[par] == 1 && coins[par] == 0){
q.push(par);
}
}
//* Since we are processing child -> parent edge
//* We need find parent of child and delete from both side
if(parent != -1){
auto ch_to_delete = find(graph[parent].begin(), graph[parent].end(), ch);
graph[parent].erase(ch_to_delete);
auto par_to_delete = find(graph[ch].begin(), graph[ch].end(), parent);
graph[ch].erase(par_to_delete );
}
}
//* Step1 : Multi source BFS to delete all leaf nodes with 1's
//* After deleting all 0's leaf nodes, we are guranteed to have leaf nodes with all 1's
for(int i=0; i<n; i++){
degree[i] = graph[i].size();
if(degree[i] == 1 ){
q.push(i);
}
}
while(!q.empty()){
removed++;
auto ch = q.front(); q.pop();
int parent = -1;
for(auto& par : graph[ch]){
degree[par]--;
parent = par;
}
if(parent != -1){
auto ch_to_delete = find(graph[parent].begin(), graph[parent].end(), ch);
graph[parent].erase(ch_to_delete);
auto par_to_delete = find(graph[ch].begin(), graph[ch].end(), parent);
graph[ch].erase(par_to_delete );
}
}
//* Step 2 : Multi source BFS to delete all leaf nodes with 1's or 0's (dont matter)
//* This leaf might contain 0 or 1
for(int i=0; i<n; i++){
degree[i] = graph[i].size();
if(degree[i] == 1 ){
q.push(i);
}
}
while(!q.empty()){
removed++;
auto ch = q.front(); q.pop();
int parent = -1;
for(auto& par : graph[ch]){
degree[par]--;
parent = par;
}
if(parent != -1){
auto ch_to_delete = find(graph[parent].begin(), graph[parent].end(), ch);
graph[parent].erase(ch_to_delete);
auto par_to_delete = find(graph[ch].begin(), graph[ch].end(), parent);
graph[ch].erase(par_to_delete );
}
}
int left = n - removed;
if(left <= 0) cout << 0 << " ";
else cout << 2 * (left - 1) << " ";
}
//? Approach 2 : lazy deleting leaf nodes
// void consistency2(int n) {
// vector<vector<int>> graph(n);
// for(int i=0; i<n-1; i++){
// int x = edges[i][0], y = edges[i][1];
// graph[x].push_back(y);
// graph[y].push_back(x);
// }
// int removed = 0;
// vector<int> degree(n);
// queue<int> q;
// vector<bool> deleted(n);
// //* Step 0 : Multi Source BFS to recursively delete all leave nodes
// for(int i=0; i<n; i++){
// degree[i] = graph[i].size();
// if(degree[i] == 1 && coins[i] == 0){
// q.push(i);
// }
// }
// while(!q.empty()){
// auto ch = q.front(); q.pop();
// deleted[ch] = true;
// removed++;
// for(auto& par : graph[ch]){
// if(deleted[par]) continue;
// degree[par]--;
// if(degree[par] == 1 && coins[par] == 0){
// q.push(par);
// }
// }
// }
// //* Step1 : Multi source BFS to delete all leaf nodes with 1's
// //* After deleting all 0's leaf nodes, we are guranteed to have leaf nodes with all 1's
// for(int i=0; i<n; i++){
// degree[i] = graph[i].size();
// if(degree[i] == 1 && !deleted[i] ){
// q.push(i);
// }
// }
// while(!q.empty()){
// auto ch = q.front(); q.pop();
// deleted[ch] = true;
// removed++;
// for(auto& par : graph[ch]){
// if(deleted[par]) continue;
// degree[par]--;
// if(degree[par] == 1){
// q.push(par);
// }
// }
// }
// //* Step 2 : Multi source BFS to delete all leaf nodes with 1's or 0's (dont matter)
// //* This leaf might contain 0 or 1
// for(int i=0; i<n; i++){
// degree[i] = graph[i].size();
// if(degree[i] == 1 ){
// q.push(i);
// }
// }
// while(!q.empty()){
// auto ch = q.front(); q.pop();
// deleted[ch] = true;
// removed++;
// for(auto& par : graph[ch]){
// if(deleted[par]) continue;
// degree[par]--;
// if(deleted[par] == 1){
// q.push(par);
// }
// }
// }
// int left = n - removed;
// if(left <= 0) cout << 0 << " ";
// else cout << 2 * (left - 1) << " ";
// }
void solve() {
int n;
cin >> n;
coins.resize(n);
edges.resize(n-1);
for(int i=0; i<n; i++) cin >> coins[i];
for(int i=0; i<n-1; i++){
int x, y;
cin >> x >> y;
edges[i] = {x, y};
}
consistency1(n);
consistency2(n);
cout << endl;
}
int32_t main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}