// practice with Dukkha, coached by rainboy
#pragma GCC optimize("O3")
#include <algorithm>
#include <iostream>

using namespace std;

const int N = 80, M = N * (N - 1) / 2, INF = 0x3f3f3f3f;

int ii[N + 2];
int dp[M + 1][N + 2], dq[M + 1][N + 2];

int main() {
	int n; cin >> n;
	int m = n * (n - 1) / 2;
	int k = 0;
	for (int i = 1; i <= n; i++) {
		int a; cin >> a;
		if (a == 1)
			ii[++k] = i;
	}
	ii[k + 1] = n + 1;
	for (int d = 0; d <= m; d++)
		for (int i = 0; i <= n + 1; i++)
			dp[d][i] = INF;
	dp[0][0] = 0;
	for (int h = 1; h <= k + 1; h++) {
		for (int u = 0; u <= m; u++)
			for (int i = 0; i <= n + 1; i++) {
				int x = INF;
				int v = u - abs(i - ii[h]);
				if (v >= 0)
					for (int g = 0, j; (j = i - g - 1) >= 0; g++) {
						int y = dp[v][j] + g * (g - 1);
						if (x > y)
							x = y;
					}
				dq[u][i] = x;
			}
		for (int u = 0; u <= m; u++)
			for (int i = 0; i <= n + 1; i++)
				dp[u][i] = dq[u][i];
	}
	int x = INF;
	int y = (n - k) * (n - k - 1);
	for (int u = 0; u <= m; u++) {
		x = min(x, dp[u][n + 1]);
		cout << (y - x) / 2 << ' ';
	}
	cout << '\n';
	return 0;
}


// practice with Dukkha, coached by rainboy
#pragma GCC optimize("O3")
#include <algorithm>
#include <iostream>

using namespace std;

const int N = 80, M = N * (N - 1) / 2, INF = 0x3f3f;

int ii[N + 2];
short dp[M + 1][N + 2], dq[M + 1][N + 2];

int main() {
	int n; cin >> n;
	int m = n * (n - 1) / 2;
	int k = 0;
	for (int i = 1; i <= n; i++) {
		int a; cin >> a;
		if (a == 1)
			ii[++k] = i;
	}
	ii[k + 1] = n + 1;
	for (int d = 0; d <= m; d++)
		for (int i = 0; i <= n + 1; i++)
			dp[d][i] = INF;
	dp[0][0] = 0;
	for (int h = 1; h <= k + 1; h++) {
		for (int u = 0; u <= m; u++)
			for (int i = 0; i <= n + 1; i++) {
				int x = INF;
				int v = u - abs(i - ii[h]);
				if (v >= 0)
					for (int g = 0, j; (j = i - g - 1) >= 0; g++)
						x = min(x, dp[v][j] + g * (g - 1) / 2);
				dq[u][i] = x;
			}
		for (int u = 0; u <= m; u++)
			for (int i = 0; i <= n + 1; i++)
				dp[u][i] = dq[u][i];
	}
	short x = INF;
	int y = (n - k) * (n - k - 1) / 2;
	for (int u = 0; u <= m; u++) {
		x = min(x, dp[u][n + 1]);
		cout << y - x << ' ';
	}
	cout << '\n';
	return 0;
}


// practice with Dukkha, coached by rainboy
#pragma GCC optimize("O3")
#include <algorithm>
#include <iostream>

using namespace std;

const int N = 80, M = N * (N - 1) / 2, INF = 0x3f3f3f3f;

int ii[N + 2], dp[M + 1][N + 2], dq[M + 1][N + 2];

int main() {
	int n; cin >> n;
	int m = n * (n - 1) / 2;
	int k = 0;
	for (int i = 1; i <= n; i++) {
		int a; cin >> a;
		if (a == 1)
			ii[++k] = i;
	}
	ii[k + 1] = n + 1;
	for (int d = 0; d <= m; d++)
		for (int i = 0; i <= n + 1; i++)
			dp[d][i] = INF;
	dp[0][0] = 0;
	for (int h = 1; h <= k + 1; h++) {
		for (int u = 0; u <= m; u++)
			for (int i = 0; i <= n + 1; i++) {
				int x = INF;
				int v = u - abs(i - ii[h]);
				if (v >= 0)
					for (int g = 0, j; (j = i - g - 1) >= 0; g++)
						x = min(x, dp[v][j] + g * (g - 1));
				dq[u][i] = x;
			}
		for (int u = 0; u <= m; u++)
			for (int i = 0; i <= n + 1; i++)
				dp[u][i] = dq[u][i];
	}
	int x = INF;
	int y = (n - k) * (n - k - 1);
	for (int u = 0; u <= m; u++) {
		x = min(x, dp[u][n + 1]);
		cout << (y - x) / 2 << ' ';
	}
	cout << '\n';
	return 0;
}


// practice with Dukkha, coached by rainboy
#include <algorithm>
#include <iostream>

using namespace std;

const int N = 80, M = N * (N - 1) / 2, INF = 0x3f3f3f3f;

int ii[N + 2], dp[M + 1][N + 2], dq[M + 1][N + 2];

int main() {
	int n; cin >> n;
	int m = n * (n - 1) / 2;
	int k = 0;
	for (int i = 1; i <= n; i++) {
		int a; cin >> a;
		if (a == 1)
			ii[++k] = i;
	}
	ii[k + 1] = n + 1;
	for (int d = 0; d <= m; d++)
		for (int i = 0; i <= n + 1; i++)
			dp[d][i] = INF;
	dp[0][0] = 0;
	for (int h = 1; h <= k + 1; h++) {
		for (int u = 0; u <= m; u++)
			for (int i = 0; i <= n + 1; i++) {
				int x = INF;
				int v = u - abs(i - ii[h]);
				if (v >= 0)
					for (int g = 0, j; (j = i - g - 1) >= 0; g++)
						x = min(x, dp[v][j] + g * (g - 1) / 2);
				dq[u][i] = x;
			}
		for (int u = 0; u <= m; u++)
			for (int i = 0; i <= n + 1; i++)
				dp[u][i] = dq[u][i];
	}
	int x = INF;
	int y = (n - k) * (n - k - 1) / 2;
	for (int u = 0; u <= m; u++) {
		x = min(x, dp[u][n + 1]);
		cout << y - x << ' ';
	}
	cout << '\n';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 105;
int n, a[maxn], b[maxn], k, p[maxn], dp[maxn][maxn][maxn*(maxn-1)/2];
void chk_min(int &x, int y) {
    x = min(x, y);
}
int main() {
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> a[i];
    a[n] = 1;
    for (int i = 0; i <= n; i ++) {
        if (a[i] == 0) b[k] ++;
        else k ++;
    }
    partial_sum(b, b+k, p);
    memset(dp, 0x3f, sizeof(dp));
    dp[0][0][0] = 0;
    int l = p[k-1];
    for (int i = 0; i < k; i ++) {
        for (int j = 0; j <= l; j ++) {
            for (int s = 0; s <= n*(n-1)/2; s ++) {
                if (dp[i][j][s] == INF) continue;
                for (int q = j; q <= l; q ++) {
                    chk_min(dp[i+1][q][s + abs(q - p[i])], dp[i][j][s] + (q-j)*(q-j));
                }
            }
        }
    }
    int mn = INF;
    for (int s = 0; s <= n*(n-1)/2; s ++) {
        chk_min(mn, dp[k][l][s]);
        int val = l * l - mn;
        assert(val % 2 == 0);
        cout << val / 2 << " ";
    }
    return 0;
}


//#include <bits/stdc++.h>
#include <iostream>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI = acos(-1.0);
const int M = 1e5 + 7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[87], b[87];
/*
设1的个数为c，第i段0的个数为xi
ans = n*(n-1)/2 -  c*(c-1)/2   -  c*(n-c)/2         - \sum {xi * (xi-1)/2 }
	   所有对数     (1,1)的对数     (1,0)的对数   (0,0)且直接没有1的对数
*/
ll dp[83][83][83 * 83];
//安排好前i个1，最后一个1被安排到j处，花了k步 ，最后一项的结果最小是多少。
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n;
	cin >> n;
	int c = 0, sz = 0;//c - 1的个数
	for (int i = 1; i <= n; i++) {
		cin >> a[i], c += a[i];
		if (a[i]) b[++sz] = i;//第sz个1 在数组a的索引
	}

	ll ans = n * (n - 1) / 2 - c * (c - 1) / 2 - c * (n - c);

	memset(dp, 0x3f, sizeof(dp));

	ll tp = 0;
	for (int i = 0; i <= sz; i++) {
		if (i)tp += max(0, (b[i] - b[i - 1] - 1) * (b[i] - b[i - 1] - 2) / 2);
		dp[i][b[i]][0] = tp;
	}
	for (int i = 1; i <= sz; i++)
		for (int k = 1; k <= n; k++)
			for (int j = 0; j < k; j++)
				for (int l = 0; l <= n * (n - 1) / 2; l++)
					dp[i][k][abs(k - b[i]) + l] = min(dp[i][k][abs(k - b[i]) + l], dp[i - 1][j][l] + max(0, (k - j - 1) * (k - j - 2) / 2));

	ll mn = 2e18;
	for (int i = 0; i <= n * (n - 1) / 2; i++) {
		for (int j = 1; j <= n; j++) {
			mn = min(mn, dp[sz][j][i] + max(0, (n - j) * (n - j - 1) / 2));
		}
		if (sz == 0)mn = ans;
		cout << ans - mn << " ";
	}
	cout << endl;
	/*
	  9
0 1 0 0 1 0   1 0 0

	  */
	return 0;
}


#include <bits/stdc++.h>
//#include <iostream>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI = acos(-1.0);
const int M = 1e5 + 7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[87], b[87];
/*
设1的个数为c，第i段0的个数为xi
ans = n*(n-1)/2 -  c*(c-1)/2   -  c*(n-c)/2         - \sum {xi * (xi-1)/2 }
	   所有对数     (1,1)的对数     (1,0)的对数   (0,0)且直接没有1的对数
*/
ll dp[83][83][83 * 83];
//安排好前i个1，最后一个1被安排到j处，花了k步 ，最后一项的结果最小是多少。
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n;
	cin >> n;
	int c = 0, sz = 0;//c - 1的个数
	for (int i = 1; i <= n; i++) {
		cin >> a[i], c += a[i];
		if (a[i]) b[++sz] = i;//第sz个1 在数组a的索引
	}

	ll ans = n * (n - 1) / 2 - c * (c - 1) / 2 - c * (n - c);

	memset(dp, 0x3f, sizeof(dp));

	ll tp = 0;
	for (int i = 0; i <= sz; i++) {
		if (i)tp += max(0, (b[i] - b[i - 1] - 1) * (b[i] - b[i - 1] - 2) / 2);
		dp[i][b[i]][0] = tp;
	}
	for (int i = 1; i <= sz; i++)
		for (int k = 1; k <= n; k++)
			for (int j = 0; j < k; j++)
				for (int l = 0; l <= n * (n - 1) / 2; l++)
					dp[i][k][abs(k - b[i]) + l] = min(dp[i][k][abs(k - b[i]) + l], dp[i - 1][j][l] + max(0, (k - j - 1) * (k - j - 2) / 2));

	ll mn = 2e18;
	for (int i = 0; i <= n * (n - 1) / 2; i++) {
		for (int j = 1; j <= n; j++) {
			mn = min(mn, dp[sz][j][i] + max(0, (n - j) * (n - j - 1) / 2));
		}
		if (sz == 0)mn = ans;
		cout << ans - mn << " ";
	}
	cout << endl;
	/*
	  9
0 1 0 0 1 0   1 0 0

	  */
	return 0;
}


#pragma GCC optimize("O3","Ofast","unroll-loops","omit-frame-pointer","inline") //Optimization flags
#pragma GCC option("arch=native","tune=native","no-zero-upper") //Enable AVX
// #pragma GCC target("avx2") //Enable AVX

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int MAXN = 82;

int A[MAXN];

int dp[MAXN][MAXN][MAXN*(MAXN-1)/2];

int B[MAXN];

int pt = 1;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    for(int i = 0 ; i < MAXN ; i++)
    {
    	for(int j = 0 ; j < MAXN ; j++)
    	{
    		for(int k = 0 ; k < MAXN*(MAXN-1)/2 ; k++)
    		{
    			dp[i][j][k] = -1e18;
    		}
    	}
    }

    int N;
    cin >> N;

    int cont = 0;

    for(int i = 1 ; i <= N ; i++)
    {
    	cin >> A[i];
    	if(A[i] == 1)
    	{
    		B[pt] = i;
    		pt++;
    		cont++;
    	}
    }
    B[pt] = N+1;

    dp[0][0][0] = 0;

    for(int i = 1 ; i <= N+1 ; i++)
    {
    	for(int j = 1 ; j <= cont+1 ; j++)
    	{
    		for(int k = N*(N-1)/8 + 2 ; k >= 0 ; k--)
    		{
    			int val = k-abs(i-B[j]);
    			if(val < 0)break;

    			for(int x = 0 ; x < i ; x++)
    			{
    				dp[i][j][k] = max(dp[i][j][k], dp[x][j-1][val] + (x - (j-1)) * (i-x-1));
    			}
    		}
    	}
    }

    int temp = 0;

    for(int i = 0 ; i <= N*(N-1)/2 ; i++)
    {
    	cout << max(dp[N+1][cont+1][i], temp) << " ";
    	temp = max(temp, dp[N+1][cont+1][i]);
    }

    return 0;
}


#pragma GCC optimize("O3","Ofast","unroll-loops","omit-frame-pointer","inline") //Optimization flags
#pragma GCC option("arch=native","tune=native","no-zero-upper") //Enable AVX
#pragma GCC target("avx2","sse4") //Enable AVX

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int MAXN = 82;

int A[MAXN];

int dp[MAXN][MAXN][MAXN*(MAXN-1)/2];

int B[MAXN];

int pt = 1;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    for(int i = 0 ; i < MAXN ; i++)
    {
    	for(int j = 0 ; j < MAXN ; j++)
    	{
    		for(int k = 0 ; k < MAXN*(MAXN-1)/2 ; k++)
    		{
    			dp[i][j][k] = -1e18;
    		}
    	}
    }

    int N;
    cin >> N;

    int cont = 0;

    for(int i = 1 ; i <= N ; i++)
    {
    	cin >> A[i];
    	if(A[i] == 1)
    	{
    		B[pt] = i;
    		pt++;
    		cont++;
    	}
    }
    B[pt] = N+1;

    dp[0][0][0] = 0;

    for(int i = 1 ; i <= N+1 ; i++)
    {
    	for(int j = 1 ; j <= cont+1 ; j++)
    	{
    		for(int k = N*(N-1)/8 + 2 ; k >= 0 ; k--)
    		{
    			int val = k-abs(i-B[j]);
    			if(val < 0)break;

    			for(int x = 0 ; x < i ; x++)
    			{
    				dp[i][j][k] = max(dp[i][j][k], dp[x][j-1][val] + (x - (j-1)) * (i-x-1));
    			}
    		}
    	}
    }

    int temp = 0;

    for(int i = 0 ; i <= N*(N-1)/2 ; i++)
    {
    	cout << max(dp[N+1][cont+1][i], temp) << " ";
    	temp = max(temp, dp[N+1][cont+1][i]);
    }

    return 0;
}


#pragma GCC optimize("O3","Ofast","unroll-loops","omit-frame-pointer","inline") //Optimization flags
#pragma GCC option("arch=native","tune=native","no-zero-upper") //Enable AVX
#pragma GCC target("avx2") //Enable AVX

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int MAXN = 82;

int A[MAXN];

int dp[MAXN][MAXN][MAXN*(MAXN-1)/2];

int B[MAXN];

int pt = 1;

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    for(int i = 0 ; i < MAXN ; i++)
    {
    	for(int j = 0 ; j < MAXN ; j++)
    	{
    		for(int k = 0 ; k < MAXN*(MAXN-1)/2 ; k++)
    		{
    			dp[i][j][k] = -1e18;
    		}
    	}
    }

    int N;
    cin >> N;

    int cont = 0;

    for(int i = 1 ; i <= N ; i++)
    {
    	cin >> A[i];
    	if(A[i] == 1)
    	{
    		B[pt] = i;
    		pt++;
    		cont++;
    	}
    }
    B[pt] = N+1;

    dp[0][0][0] = 0;

    for(int i = 1 ; i <= N+1 ; i++)
    {
    	for(int j = 1 ; j <= cont+1 ; j++)
    	{
    		for(int k = N*(N-1)/8 + 2 ; k >= 0 ; k--)
    		{
    			int val = k-abs(i-B[j]);
    			if(val < 0)break;

    			for(int x = 0 ; x < i ; x++)
    			{
    				dp[i][j][k] = max(dp[i][j][k], dp[x][j-1][val] + (x - (j-1)) * (i-x-1));
    			}
    		}
    	}
    }

    int temp = 0;

    for(int i = 0 ; i <= N*(N-1)/2 ; i++)
    {
    	cout << max(dp[N+1][cont+1][i], temp) << " ";
    	temp = max(temp, dp[N+1][cont+1][i]);
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<int> Edges[200005];
vector<int> fromCh[200005];
bool Visit[200005];

class node
{
    public:
    int bw, upMax, ans;
} a[200005];

int dfs(int pos)
{
    int thisChild;
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    a[pos].upMax = 0;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
             thisChild = dfs(Edges[pos][i]);
             fromCh[pos][i] = thisChild;
             if (thisChild != -1) a[pos].upMax += thisChild;
        }
    }
    a[pos].upMax = a[pos].bw;
    return a[pos].upMax;
}

int dfs2(int pos, int fP)
{
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    if (fP != -1) a[pos].ans = a[pos].upMax + fP;
    else a[pos].ans = a[pos].upMax;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
            if (fromCh[pos][i] == -1) dfs2(Edges[pos][i], fp);
            else dfs2(Edges[pos][i], fp - fromCh[pos][i]);
        }
    }
    return 0;
}

int main()
{
    long long ans;
    int n, k, p, q;
    int i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) scanf("%d", &(a[i].bw));
    for (i = 1; i < n; i++) {
        scanf("%d %d", &p, &q);
        Edges[p].push_back(q);
        Edges[q].push_back(p);
        fromCh[p].push_back(0);
        fromCh[q].push_back(0);
    }
    dfs(1);
    for (i = 1; i <= n; i++) Visit[i] = 0;
    dfs2(1, 0);
    for (i = 1; i <= n; i++) printf("%d ", a[i].ans);
    printf("\n");
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<int> Edges[200005];
vector<int> fromCh[200005];
bool Visit[200005];

class node
{
    public:
    int bw, upMax, ans;
} a[200005];

int dfs(int pos)
{
    int thisChild;
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    a[pos].upMax = 0;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
             thisChild = dfs(Edges[pos][i]);
             fromCh[pos][i] = thisChild;
             if (thisChild != -1) a[pos].upMax += thisChild;
        }
    }
    a[pos].upMax += a[pos].bw;
    return a[pos].upMax;
}

int dfs2(int pos, int fP)
{
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    if (fP != -1) a[pos].ans = a[pos].upMax + fP;
    else a[pos].ans = a[pos].upMax;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
            if (fromCh[pos][i] == -1) dfs2(Edges[pos][i], a[pos].ans);
            else dfs2(Edges[pos][i], a[pos].ans - fromCh[pos][i]);
        }
    }
    return 0;
}

int main()
{
    long long ans;
    int n, k, p, q;
    int i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) scanf("%d", &(a[i].bw));
    for (i = 1; i < n; i++) {
        scanf("%d %d", &p, &q);
        Edges[p].push_back(q);
        Edges[q].push_back(p);
        fromCh[p].push_back(0);
        fromCh[q].push_back(0);
    }
    dfs(1);
    for (i = 1; i <= n; i++) Visit[i] = 0;
    dfs2(1, 0);
    for (i = 1; i <= n; i++) printf("%d ", a[i].ans);
    printf("\n");
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<int> Edges[200005];
vector<int> fromCh[200005];
bool Visit[200005];

class node
{
    public:
    int bw, upMax, ans;
} a[200005];

int dfs(int pos)
{
    int thisChild;
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    a[pos].upMax = 0;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
             thisChild = dfs(Edges[pos][i]);
             fromCh[pos][i] = thisChild;
             if (thisChild != -1) a[pos].upMax += thisChild;
        }
    }
    a[pos].upMax = a[pos].bw;
    return a[pos].upMax;
}

int dfs2(int pos, int fP)
{
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    if (fP != -1) a[pos].ans = a[pos].upMax + fP;
    else a[pos].ans = a[pos].upMax;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
            if (fromCh[pos][i] == -1) dfs2(Edges[pos][i], fP);
            else dfs2(Edges[pos][i], fP - fromCh[pos][i]);
        }
    }
    return 0;
}

int main()
{
    long long ans;
    int n, k, p, q;
    int i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) scanf("%d", &(a[i].bw));
    for (i = 1; i < n; i++) {
        scanf("%d %d", &p, &q);
        Edges[p].push_back(q);
        Edges[q].push_back(p);
        fromCh[p].push_back(0);
        fromCh[q].push_back(0);
    }
    dfs(1);
    for (i = 1; i <= n; i++) Visit[i] = 0;
    dfs2(1, 0);
    for (i = 1; i <= n; i++) printf("%d ", a[i].ans);
    printf("\n");
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<int> Edges[200005];
vector<int> fromCh[200005];
bool Visit[200005];

class node
{
    public:
    int bw, upMax, ans;
} a[200005];

int dfs(int pos)
{
    int thisChild;
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    a[pos].upMax = 0;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
             thisChild = dfs(Edges[pos][i]);
             fromCh[pos][i] = thisChild;
             if (thisChild != -1) a[pos].upMax += thisChild;
        }
    }
    a[pos].upMax = a[pos].bw;
    return a[pos].upMax;
}

int dfs2(int pos, fP)
{
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    if (fP != -1) a[pos].ans = a[pos].upMax + fP;
    else a[pos].ans = a[pos].upMax;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
            if (fromCh[pos][i] == -1) dfs2(Edges[pos][i], fp);
            else dfs2(Edges[pos][i], fp - fromCh[pos][i]);
        }
    }
    return 0;
}

int main()
{
    long long ans;
    int n, k, p, q;
    int i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) scanf("%d", &(a[i].bw));
    for (i = 1; i < n; i++) {
        scanf("%d %d", &p, &q);
        Edges[p].push_back(q);
        Edges[q].push_back(p);
        fromCh[p].push_back(0);
        fromCh[q].push_back(0);
    }
    dfs(1);
    for (i = 1; i <= n; i++) Visit[i] = 0;
    dfs2(1, 0);
    for (i = 1; i <= n; i++) printf("%d\n", a[i].ans);

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<int> Edges[200005];
vector<int> fromCh[200005];
bool Visit[200005];

class node
{
    public:
    int bw, upMax, ans;
} a[200005];

int dfs(int pos)
{
    int thisChild;
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    a[pos].upMax = 0;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
             thisChild = dfs(Edges[pos][i]);
             fromCh[pos][i] = thisChild;
             if (thisChild != -1) a[pos].upMax += thisChild;
        }
    }
    a[pos].upMax += a[pos].bw;
    return a[pos].upMax;
}

int dfs2(int pos, int fP)
{
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    if (fP != -1) a[pos].ans = a[pos].upMax + fP;
    else a[pos].ans = a[pos].upMax;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
            if (fromCh[pos][i] == -1) dfs2(Edges[pos][i], fP);
            else dfs2(Edges[pos][i], fP - fromCh[pos][i]);
        }
    }
    return 0;
}

int main()
{
    long long ans;
    int n, k, p, q;
    int i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) scanf("%d", &(a[i].bw));
    for (i = 1; i < n; i++) {
        scanf("%d %d", &p, &q);
        Edges[p].push_back(q);
        Edges[q].push_back(p);
        fromCh[p].push_back(0);
        fromCh[q].push_back(0);
    }
    dfs(1);
    for (i = 1; i <= n; i++) Visit[i] = 0;
    //dfs2(1, 0);
    for (i = 1; i <= n; i++) printf("%d ", a[i].ans);
    printf("\n");
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<int> Edges[200005];
vector<int> fromCh[200005];
bool Visit[200005];

class node
{
    public:
    int bw, upMax, ans;
} a[200005];

int dfs(int pos)
{
    int thisChild;
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    a[pos].upMax = 0;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
             thisChild = dfs(Edges[pos][i]);
             fromCh[pos][i] = thisChild;
             if (thisChild != -1) a[pos].upMax += thisChild;
        }
    }
    if (a[pos].bw) a[pos].upMax++;
    else a[pos].upMax--;
    return a[pos].upMax;
}

int dfs2(int pos, int fP)
{
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    if (fP != -1) a[pos].ans = a[pos].upMax + fP;
    else a[pos].ans = a[pos].upMax;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
            if (fromCh[pos][i] == -1) dfs2(Edges[pos][i], a[pos].ans);
            else dfs2(Edges[pos][i], a[pos].ans - fromCh[pos][i]);
        }
    }
    return 0;
}

int main()
{
    long long ans;
    int n, k, p, q;
    int i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) scanf("%d", &(a[i].bw));
    for (i = 1; i < n; i++) {
        scanf("%d %d", &p, &q);
        Edges[p].push_back(q);
        Edges[q].push_back(p);
        fromCh[p].push_back(0);
        fromCh[q].push_back(0);
    }
    dfs(1);
    for (i = 1; i <= n; i++) Visit[i] = 0;
    dfs2(1, 0);
    for (i = 1; i <= n; i++) printf("%d ", a[i].ans);
    printf("\n");
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<int> Edges[200005];
vector<int> fromCh[200005];
bool Visit[200005];

class node
{
    public:
    int bw, upMax, ans;
} a[200005];

int dfs(int pos)
{
    int thisChild;
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    a[pos].upMax = 0;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
             thisChild = dfs(Edges[pos][i]);
             fromCh[pos][i] = thisChild;
             if (thisChild != -1) a[pos].upMax += thisChild;
        }
    }
    a[pos].upMax += a[pos].bw;
    return a[pos].upMax;
}

int dfs2(int pos, int fP)
{
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    if (fP != -1) a[pos].ans = a[pos].upMax + fP;
    else a[pos].ans = a[pos].upMax;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
            if (fromCh[pos][i] == -1) dfs2(Edges[pos][i], fP);
            else dfs2(Edges[pos][i], fP - fromCh[pos][i]);
        }
    }
    return 0;
}

int main()
{
    long long ans;
    int n, k, p, q;
    int i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) scanf("%d", &(a[i].bw));
    for (i = 1; i < n; i++) {
        scanf("%d %d", &p, &q);
        Edges[p].push_back(q);
        Edges[q].push_back(p);
        fromCh[p].push_back(0);
        fromCh[q].push_back(0);
    }
    dfs(1);
    for (i = 1; i <= n; i++) Visit[i] = 0;
    dfs2(1, 0);
    for (i = 1; i <= n; i++) printf("%d ", a[i].ans);
    printf("\n");
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

vector<int> Edges[200005];
vector<int> fromCh[200005];
bool Visit[200005];

class node
{
    public:
    int bw, upMax, ans;
} a[200005];

int dfs(int pos)
{
    int thisChild;
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    a[pos].upMax = 0;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
             thisChild = dfs(Edges[pos][i]);
             fromCh[pos][i] = thisChild;
             if (thisChild != -1) a[pos].upMax += thisChild;
        }
    }
    a[pos].upMax = a[pos].bw;
    return a[pos].upMax;
}

int dfs2(int pos, int fP)
{
    int i, k; k = Edges[pos].size();
    Visit[pos] = true;
    if (fP != -1) a[pos].ans = a[pos].upMax + fP;
    else a[pos].ans = a[pos].upMax;
    for (i = 0; i < k; i++) {
        if (!Visit[Edges[pos][i]]) { // no parent
            if (fromCh[pos][i] == -1) dfs2(Edges[pos][i], fP);
            else dfs2(Edges[pos][i], fP - fromCh[pos][i]);
        }
    }
    return 0;
}

int main()
{
    long long ans;
    int n, k, p, q;
    int i, j;
    scanf("%d", &n);
    for (i = 1; i <= n; i++) scanf("%d", &(a[i].bw));
    for (i = 1; i < n; i++) {
        scanf("%d %d", &p, &q);
        Edges[p].push_back(q);
        Edges[q].push_back(p);
        fromCh[p].push_back(0);
        fromCh[q].push_back(0);
    }
    dfs(1);
    for (i = 1; i <= n; i++) Visit[i] = 0;
    //dfs2(1, 0);
    for (i = 1; i <= n; i++) printf("%d ", a[i].ans);
    printf("\n");
    return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define err cerr<<"OK"<<endl
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<int> g[200001];
std::vector<int> v(200001),res(200001,10000000);
int n;
vector<unordered_map<int,int>> dp(200001);

int dfs(int st,int par){
	if(par!=-1 && dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	int k=0;
	if(dp[st].find(par)!=dp[st].end())
		k = dp[st][par];
	if(res[st]!=10000000){
		return res[st]-k;
	}
	int ans=v[st];
	for(auto i:g[st]){
		if(i==par)
			continue;
		int val = dfs(i,st);
		if(val<0)
			val=0;
		dp[st][i]=val;
		ans += val;
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	dp.clear();
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		res[i]=dfs(i,-1);
	}

	for(int i=1;i<=n;++i)
		cout<<res[i]<<" ";

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define err cerr<<"OK"<<endl
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<int> g[200001];
std::vector<int> v(200001),res(200001,0),pr(200001,-1);
int n;

int dfs(int st,int par){
	pr[st]=par;
	int ans=v[st];
	for(auto i:g[st]){
		if(i==par)
			continue;
		int val = dfs(i,st);
		if(val<0)
			val=0;
		ans += val;
	}
	res[st]=ans;
	return ans;
}

void go(int st,int par){
	for(auto i:g[st]){
		if(i==par)
			continue;
		int k = res[st];
		// cout<<st<<" "<<k<<endl;
		if(res[i]>=0)
			res[i] = max({res[i],k});
		else
			res[i] = max(res[i],res[i]+k);
		go(i,st);
	}

}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	dfs(1,-1);

	for(int i=1;i<=n;++i)
	{
		cout<<res[i]<<" ";
	}
	cout<<endl;

	go(1,-1);

	for(int i=1;i<=n;++i)
	{
		cout<<res[i]<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define ll int
#define err cerr<<"OK"<<endl
#define all(v) v.begin(),v.end()
ll power(ll a,ll b){ll z=1;while(b){if(b&1){z*=a;z%=md;}a*=a;a%=md;b/=2;}return z%md;}
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<ll> g[200005];
std::vector<ll> v;
ll n;
map<ll,ll> dp[200005];

ll dfs(ll st,ll par){
	if(dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	ll ans=v[st];
	for(auto i:g[st]){
		if(i!=par){
			ll val = max(0,dfs(i,st));
			// cout<<st<<" "<<i<<"  "<<val<<endl;
			dp[st][i]=val;
			ans+=val;
		}
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	v.resize(n+1);
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		ll a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define err cerr<<"OK"<<endl
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<int> g[200001];
std::vector<int> v(200001);
int n;
vector<unordered_map<int,int>> dp(200001);

int dfs(int st,int par){
	if(st==par)
		return 0;
	if(par!=-1 && dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	int ans=v[st];
	if(g[st].size()==0)
		return ans;
	for(auto i:g[st]){
		if(i==par)
			continue;
		int val = dfs(i,st);
		if(val<0)
			val=0;
		dp[st][i]=val;
		ans += val;
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	dp.clear();
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define ll long long int
#define err cerr<<"OK"<<endl
#define all(v) v.begin(),v.end()
ll power(ll a,ll b){ll z=1;while(b){if(b&1){z*=a;z%=md;}a*=a;a%=md;b/=2;}return z%md;}
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<ll> g[200005];
std::vector<ll> v;
ll n;
map<ll,ll> dp[200005];

ll dfs(ll st,ll par){
	if(dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	ll ans=v[st];
	for(auto i:g[st]){
		if(i!=par){
			ll val = max(0LL,dfs(i,st));
			// cout<<st<<" "<<i<<"  "<<val<<endl;
			dp[st][i]=val;
			ans+=val;
		}
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	v.resize(n+1);
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		ll a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define ll int
#define err cerr<<"OK"<<endl
#define all(v) v.begin(),v.end()
ll power(ll a,ll b){ll z=1;while(b){if(b&1){z*=a;z%=md;}a*=a;a%=md;b/=2;}return z%md;}
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<ll> g[200005];
std::vector<ll> v;
ll n;
unordered_map<ll,ll> dp[200005];

ll dfs(ll st,ll par){
	if(dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	ll ans=v[st];
	for(auto i:g[st]){
		if(i!=par){
			ll val = max(0,dfs(i,st));
			// cout<<st<<" "<<i<<"  "<<val<<endl;
			dp[st][i]=val;
			ans+=val;
		}
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	v.resize(n+1);
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		ll a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define ll int
#define err cerr<<"OK"<<endl
#define all(v) v.begin(),v.end()
ll power(ll a,ll b){ll z=1;while(b){if(b&1){z*=a;z%=md;}a*=a;a%=md;b/=2;}return z%md;}
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<ll> g[200001];
std::vector<ll> v(200001);
ll n;
vector<unordered_map<ll,ll>> dp(200001);

ll dfs(ll st,ll par){
	if(par!=-1 && dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	ll ans=v[st];
	for(auto i:g[st]){
		if(i!=par){
			ll val = max(0,dfs(i,st));
			dp[st][i]=val;
			ans+=val;
		}
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		ll a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define err cerr<<"OK"<<endl
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<int> g[200001];
std::vector<int> v(200001);
int n;
vector<unordered_map<int,int>> dp(200001);

int dfs(int st,int par){
	if(st==par)
		return 0;
	if(par!=-1 && dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	int ans=v[st];
	if(g[st].size()==0)
		return ans;
	for(auto i:g[st]){
		if(i==par)
			continue;
		int val = dfs(i,st);
		if(val<0)
			val=0;
		dp[st][i]=val;
		ans += val;
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define err cerr<<"OK"<<endl
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<int> g[200001];
std::vector<int> v(200001),res(200001,0),pr(200001,-1);
int n;

int dfs(int st,int par){
	pr[st]=par;
	int ans=v[st];
	for(auto i:g[st]){
		if(i==par)
			continue;
		int val = dfs(i,st);
		if(val<0)
			val=0;
		ans += val;
	}
	res[st]=ans;
	return ans;
}

void go(int st,int par){
	for(auto i:g[st]){
		if(i==par)
			continue;
		int k = res[st];
		// cout<<st<<" "<<k<<endl;
		if(res[i]>=0)
			res[i] = max({res[i],k});
		else
			res[i] = max(res[i],res[i]+k);
		go(i,st);
	}

}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	dfs(1,-1);
	go(1,-1);

	for(int i=1;i<=n;++i)
	{
		cout<<res[i]<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define err cerr<<"OK"<<endl
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<int> g[200001];
std::vector<int> v(200001);
int n;
vector<unordered_map<int,int>> dp(200001);

int dfs(int st,int par){
	if(par!=-1 && dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	int ans=v[st];
	if(g[st].size()==0)
		return ans;
	for(auto i:g[st]){
		if(i==par)
			continue;
		int val = dfs(i,st);
		if(val<0)
			val=0;
		dp[st][i]=val;
		ans += val;
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define err cerr<<"OK"<<endl
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<int> g[200001];
std::vector<int> v(200001);
int n;
vector<unordered_map<int,int>> dp(200001);

int dfs(int st,int par){
	if(par!=-1 && dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	int ans=v[st];
	for(auto i:g[st]){
		if(i!=par){
			int val = dfs(i,st);
			if(val<0)
				val=0;
			dp[st][i]=val;
			ans += val;
		}
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define ll int
#define err cerr<<"OK"<<endl
#define all(v) v.begin(),v.end()
ll power(ll a,ll b){ll z=1;while(b){if(b&1){z*=a;z%=md;}a*=a;a%=md;b/=2;}return z%md;}
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<ll> g[200005];
std::vector<ll> v(200005);
ll n;
vector<unordered_map<ll,ll>> dp(200005);

ll dfs(ll st,ll par){
	if(par!=-1)
	if(dp[par].count(st))
		return dp[par][st];
	ll ans=v[st];
	for(auto i:g[st]){
		if(i!=par){
			ll val = max(0,dfs(i,st));
			dp[st][i]=val;
			ans+=val;
		}
	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		ll a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#include <pprint.hpp>
#endif
#define endl "\n";
#define pb push_back
#define md 1000000007
#define err cerr<<"OK"<<endl
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

std::vector<int> g[200001];
std::vector<int> v(200001);
int n;
vector<unordered_map<int,int>> dp(200001);

int dfs(int st,int par){
	if(par!=-1 && dp[par].find(st)!=dp[par].end())
		return dp[par][st];
	int ans=v[st];
	for(auto i:g[st]){
		if(i==par)
			continue;
			int val = dfs(i,st);
			if(val<0)
				val=0;
			dp[st][i]=val;
			ans += val;

	}
	return ans;
}

int main(){
	//You need to change array size!
	#ifndef LOCAL
	ios_base::sync_with_stdio(false);	cin.tie(NULL);
	#endif
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>v[i];
		if(v[i]==0)
			v[i]=-1;
	}

	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}

	for(int i=1;i<=n;++i){
		cout<<dfs(i,-1)<<" ";
	}

	return 0;
}


/*
 **	Generated by https://github.com/xalanq/cf-tool
 **	Author: Matsuri
 **	Time: 2020/03/12
 */
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5 + 555;
const int MOD = 1e9 + 7;
vector<int> V[maxn];
int a[maxn];
int ans[maxn];
int dp[maxn];
void dfs(int x, int fa) {
    dp[x] = a[x];
    for (int i : V[x]) {
        if (i != fa) {
            dfs(i, x);
            dp[x] += max(0, dp[i]);
        }
    }
}
void dfs2(int x, int fa) {
    for (int i : V[x]) {
        if (i != fa) {
            int a = dp[x];
            int b = dp[i];

            dp[x] -= max(0, dp[i]);

            dp[i] = ::a[i];
            for (int j : V[i]) {
                dp[i] += max(0, dp[j]);
            }
            ans[i] = dp[i];
            dfs2(i, x);

            dp[x] = a;
            dp[i] = b;
        }
    }
}
int32_t main() {
    srand(time(0));
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        if (!a[i])
            a[i] = -1;
    }
    int a, b;
    for (int i = 1; i < n; i++) {
        scanf("%d%d", &a, &b);
        V[a].push_back(b);
        V[b].push_back(a);
    }
    dfs(1, -1);
    ans[1] = dp[1];
    dfs2(1, -1);
    for (int i = 1; i <= n; i++)
        printf("%d ", ans[i]);
    return 0;
}


/*
 **	Generated by https://github.com/xalanq/cf-tool
 **	Author: Matsuri
 **	Time: 2020/03/12
 */
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5 + 555;
const int MOD = 1e9 + 7;
vector<int> V[maxn];
int a[maxn];
int ans[maxn];
int dp[maxn];
void dfs(int x, int fa) {
    dp[x] = a[x];
    for (int i : V[x]) {
        if (i != fa) {
            dfs(i, x);
            dp[x] += max(0, dp[i]);
        }
    }
}
void dfs2(int x, int fa) {
    for (int i : V[x]) {
        if (i != fa) {
            int b = dp[i];

            dp[x] = ::a[x];
            for (int j : V[x]) {
                if (j == i)
                    continue;
                dp[x] += max(0, dp[j]);
            }

            ans[i] = ::a[i];
            for (int j : V[i]) {
                ans[i] += max(0, dp[j]);
            }
            dfs2(i, x);
            dp[i] = b;
        }
    }
}
int32_t main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        if (!a[i])
            a[i] = -1;
    }
    int a, b;
    for (int i = 1; i < n; i++) {
        scanf("%d%d", &a, &b);
        V[a].push_back(b);
        V[b].push_back(a);
    }
    int root = rand() % n + 1;
    dfs(root, -1);
    ans[root] = dp[root];
    dfs2(root, -1);
    for (int i = 1; i <= n; i++)
        printf("%d ", ans[i]);
    return 0;
}


/*
 **	Generated by https://github.com/xalanq/cf-tool
 **	Author: Matsuri
 **	Time: 2020/03/12
 */
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5 + 555;
const int MOD = 1e9 + 7;
vector<int> V[maxn];
int a[maxn];
int ans[maxn];
int dp[maxn];
void dfs(int x, int fa) {
    dp[x] = a[x];
    for (int i : V[x]) {
        if (i != fa) {
            dfs(i, x);
            dp[x] += max(0, dp[i]);
        }
    }
}
void dfs2(int x, int fa) {
    for (int i : V[x]) {
        if (i != fa) {
            int a = dp[x];
            int b = dp[i];

            dp[x] -= max(0, dp[i]);

            dp[i] = ::a[i];
            for (int j : V[i]) {
                dp[i] += max(0, dp[j]);
            }
            ans[i] = dp[i];
            dfs2(i, x);

            dp[x] = a;
            dp[i] = b;
        }
    }
}
int32_t main() {
    srand(time(0));
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        if (!a[i])
            a[i] = -1;
    }
    int a, b;
    for (int i = 1; i < n; i++) {
        scanf("%d%d", &a, &b);
        V[a].push_back(b);
        V[b].push_back(a);
    }
    int root = rand() % n + 1;
    dfs(root, -1);
    ans[root] = dp[root];
    dfs2(root, -1);
    for (int i = 1; i <= n; i++)
        printf("%d ", ans[i]);
    return 0;
}


/*
 **	Generated by https://github.com/xalanq/cf-tool
 **	Author: Matsuri
 **	Time: 2020/03/12
 */
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5 + 555;
const int MOD = 1e9 + 7;
vector<int> V[maxn];
int a[maxn];
int ans[maxn];
int dp[maxn];
void dfs(int x, int fa) {
    dp[x] = a[x];
    for (int i : V[x]) {
        if (i != fa) {
            dfs(i, x);
            dp[x] += max(0, dp[i]);
        }
    }
}
void dfs2(int x, int fa) {
    for (int i : V[x]) {
        if (i != fa) {
            int b = dp[i];

            dp[x] = ::a[x];
            for (int j : V[x]) {
                if (j == i)
                    continue;
                dp[x] += max(0, dp[j]);
            }

            dp[i] = ::a[i];
            for (int j : V[i]) {
                dp[i] += max(0, dp[j]);
            }

            ans[i] = dp[i];
            dfs2(i, x);
            dp[i] = b;
        }
    }
}
int32_t main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        if (!a[i])
            a[i] = -1;
    }
    int a, b;
    for (int i = 1; i < n; i++) {
        scanf("%d%d", &a, &b);
        V[a].push_back(b);
        V[b].push_back(a);
    }
    int root = rand() % n + 1;
    dfs(root, -1);
    ans[root] = dp[root];
    dfs2(root, -1);
    for (int i = 1; i <= n; i++)
        printf("%d ", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5 + 555;
const int MOD = 1e9 + 7;
vector<int> V[maxn];
int a[maxn];
int ans[maxn];
int dp[maxn];
void dfs(int x, int fa) {
    dp[x] = a[x];
    for (int i : V[x]) {
        if (i != fa) {
            dfs(i, x);
            dp[x] += max(0, dp[i]);
        }
    }
}
void dfs2(int x, int fa) {
    for (int i : V[x]) {
        if (i != fa) {
            int a = dp[x];
            int b = dp[i];

            dp[x] = ::a[x];
            for (int j : V[x]) {
                if (j == i)
                    continue;
                dp[x] += max(0, dp[j]);
            }

            dp[i] = ::a[i];
            for (int j : V[i]) {
                dp[i] += max(0, dp[j]);
            }

            ans[i] = dp[i];
            dfs2(i, x);
            dp[x] = a;
            dp[i] = b;
        }
    }
}
int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (!a[i])
            a[i] = -1;
    }
    for (int i = 1; i < n; i++) {
        static int a, b;
        cin >> a >> b;
        V[a].push_back(b);
        V[b].push_back(a);
    }
    dfs(1, -1);
    ans[1] = dp[1];
    dfs2(1, -1);
    for (int i = 1; i <= n; i++)
        cout << ans[i] << ' ';
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5 + 555;
const int MOD = 1e9 + 7;
vector<int> V[maxn];
int a[maxn];
int ans[maxn];
int dp[maxn];
void dfs(int x, int fa) {
    dp[x] = a[x];
    for (int i : V[x]) {
        if (i != fa) {
            dfs(i, x);
            dp[x] += max(0, dp[i]);
        }
    }
}
void dfs2(int x, int fa) {
    for (int i : V[x]) {
        if (i != fa) {
            int b = dp[i];

            dp[x] = ::a[x];
            for (int j : V[x]) {
                if (j == i)
                    continue;
                dp[x] += max(0, dp[j]);
            }

            dp[i] = ::a[i];
            for (int j : V[i]) {
                dp[i] += max(0, dp[j]);
            }

            ans[i] = dp[i];
            dfs2(i, x);
            dp[i] = b;
        }
    }
}
int32_t main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        if (!a[i])
            a[i] = -1;
    }
    int a, b;
    for (int i = 1; i < n; i++) {
        scanf("%d%d", &a, &b);
        V[a].push_back(b);
        V[b].push_back(a);
    }
    int root = rand() % n + 1;
    dfs(root, -1);
    ans[root] = dp[root];
    dfs2(root, -1);
    for (int i = 1; i <= n; i++)
        printf("%d ", ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
const int inf = 2e9;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T> void smin(T& a, T val) {if (a > val) a = val;}template<class T> void smax(T& a, T val) {if (a < val) a = val;}
const int N = 2*(int)1e5 + 10;

int n, col[N], in[N], par[N], out[N], bstpar[N];
vector<int> v[N];

//if this is graph makes sure to loop for all the unvisited vertices, i.e, the graph may be unconnected
void dfs(int s, int p){
   in[s] = (col[s] == 1) ? 1 : -1;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s);
         if(in[i] >= 0){
            in[s] += in[i];
         }
      }
   }
}

void dfs2(int s, int p){
   // if(p != -1){
   //    int tt = out[p] + ((col[p] == 1) ? 1 : -1);
   //    for(auto it: v[p]){
   //       if(it == s or it == par[p])continue;
   //       if(in[it] >= 0)
   //          tt += in[it];
   //    }
   //    if(tt >= 0)
   //       out[s] = tt;
   // }
   for(auto i: v[s]){
      if(i != p){
         out[i] = (out[s]);// + ((col[s] == 1) ? 1 : -1);
         out[i] += in[s];
         if(in[i] >= 0)
            out[i] -= in[i];
         smax(out[i], 0);
      }
   }
   for(auto i: v[s]){
      if(i == p)continue;
      dfs2(i, s);
   }
}

void solve(){
   cin>>n;

   for (int i = 1; i <= n; ++i)
   {
      cin>>col[i];
   }

   for (int i = 0; i+1 < n; ++i)
   {
      int x, y;cin >> x >> y;
      v[x].push_back(y);
      v[y].push_back(x);
   }

   dfs(1, -1);
   dfs2(1, -1);

   for (int i = 1; i <= n; ++i)
   {
      cout << in[i] + out[i] << " ";
   }
}

int32_t main(){_

   int t = 1;
   //cin >> t;

   while(t--){
     solve();
     cout << endl;
   }

   return 0;
}


#include <bits/stdc++.h>
#define int long long
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
const int inf = 2e9;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T> void smin(T& a, T val) {if (a > val) a = val;}template<class T> void smax(T& a, T val) {if (a < val) a = val;}
const int N = 2*(int)1e5 + 10;

int n, col[N], in[N], par[N], out[N], bstpar[N];
vector<int> v[N];

//if this is graph makes sure to loop for all the unvisited vertices, i.e, the graph may be unconnected
void dfs(int s, int p){
   in[s] = (col[s] == 1) ? 1 : -1;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s);
         if(in[i] >= 0){
            in[s] += in[i];
         }
      }
   }
}

void dfs2(int s, int p){
   // if(p != -1){
   //    int tt = out[p] + ((col[p] == 1) ? 1 : -1);
   //    for(auto it: v[p]){
   //       if(it == s or it == par[p])continue;
   //       if(in[it] >= 0)
   //          tt += in[it];
   //    }
   //    if(tt >= 0)
   //       out[s] = tt;
   // }
   for(auto i: v[s]){
      if(i != p){
         out[i] = (out[s]);// + ((col[s] == 1) ? 1 : -1);
         out[i] += in[s];
         if(in[i] >= 0)
            out[i] -= in[i];
         smax(out[i], 0);
      }
   }
   for(auto i: v[s]){
      if(i == p)continue;
      dfs2(i, s);
   }
}

void solve(){
   cin>>n;

   for (int i = 1; i <= n; ++i)
   {
      cin>>col[i];
   }

   for (int i = 0; i+1 < n; ++i)
   {
      int x, y;cin >> x >> y;
      v[x].push_back(y);
      v[y].push_back(x);
   }

   dfs(1, -1);
   dfs2(1, -1);

   for (int i = 1; i <= n; ++i)
   {
      cout << in[i] + out[i] << " ";
   }
}

int32_t main(){_

   int t = 1;
   //cin >> t;

   while(t--){
     solve();
     cout << endl;
   }

   return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define int long long
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T> void smin(T& a, T val) {if (a > val) a = val;}template<class T> void smax(T& a, T val) {if (a < val) a = val;}
const int N = 2*(int)1e5 + 10;

int n, col[N], in[N], par[N], out[N];
vector<int> v[N];

//if this is graph makes sure to loop for all the unvisited vertices, i.e, the graph may be unconnected
void dfs(int s, int p){
   in[s] = (col[s] == 1) ? 1 : -1;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s);
         if(in[i] >= 0){
            in[s] += in[i];
         }
      }
   }
}

void dfs2(int s, int p){
   if(p != -1){
      int tt = out[p] + ((col[p] == 1) ? 1 : -1);
      // if(s == 7)
        // tr(s, out[s], out[p]);
      for(auto it: v[p]){
         if(it == s or it == par[p])continue;
         if(in[it] >= 0)
            tt += in[it];
      }
      if(tt >= 0)
         out[s] = tt;
   }
   for(auto i: v[s]){
      if(i != p){
         dfs2(i, s);
      }
   }
   int vv = -1;
   if(p != -1)vv = out[p];
   tr(s, in[s], out[s], vv);
}

void solve(){
   cin>>n;

   for (int i = 1; i <= n; ++i)
   {
      cin>>col[i];
   }

   for (int i = 0; i+1 < n; ++i)
   {
      int x, y;cin >> x >> y;
      v[x].push_back(y);
      v[y].push_back(x);
   }

   dfs(1, -1);
   dfs2(1, -1);

   for (int i = 1; i <= n; ++i)
   {
      cout << in[i] + out[i] << " ";
   }
}

int32_t main(){_

   int t = 1;
   //cin >> t;

   while(t--){
     solve();
     cout << endl;
   }

   return 0;
}


#pragma optimize("", off)
#pragma GCC optimize ("O3")
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma comment(linker, "/STACK:36777216")
#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T> void smin(T& a, T val) {if (a > val) a = val;}template<class T> void smax(T& a, T val) {if (a < val) a = val;}
const int N = 2*(int)1e5 + 10;

int n, col[N], in[N], par[N], out[N], bstpar[N];
vector<int> v[N];

//if this is graph makes sure to loop for all the unvisited vertices, i.e, the graph may be unconnected
void dfs(int s, int p){
   in[s] = (col[s] == 1) ? 1 : -1;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s);
         if(in[i] >= 0){
            in[s] += in[i];
         }
      }
   }
}

void dfs2(int s, int p){
   if(p != -1){
      int tt = out[p] + ((col[p] == 1) ? 1 : -1);
      for(auto it: v[p]){
         if(it == s or it == par[p])continue;
         if(in[it] >= 0)
            tt += in[it];
      }
      if(tt >= 0)
         out[s] = tt;
   }
   for(auto i: v[s]){
      if(i != p){
         dfs2(i, s);
      }
   }
}

void solve(){
   cin>>n;

   for (int i = 1; i <= n; ++i)
   {
      cin>>col[i];
   }

   for (int i = 0; i+1 < n; ++i)
   {
      int x, y;cin >> x >> y;
      v[x].push_back(y);
      v[y].push_back(x);
   }

   dfs(1, -1);
   dfs2(1, -1);

   for (int i = 1; i <= n; ++i)
   {
      cout << in[i] + out[i] << " ";
   }
}

int32_t main(){_

   int t = 1;
   //cin >> t;

   while(t--){
     solve();
     cout << endl;
   }

   return 0;
}


#include <bits/stdc++.h>
#define int long long
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
const int inf = 2e9;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T> void smin(T& a, T val) {if (a > val) a = val;}template<class T> void smax(T& a, T val) {if (a < val) a = val;}
const int N = 2*(int)1e5 + 10;

int n, col[N], in[N], par[N], out[N], bstpar[N];
vector<int> v[N];

//if this is graph makes sure to loop for all the unvisited vertices, i.e, the graph may be unconnected
void dfs(int s, int p){
   in[s] = (col[s] == 1) ? 1 : -1;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s);
         if(in[i] >= 0){
            in[s] += in[i];
         }
      }
   }
}

void dfs2(int s, int p){
   // if(p != -1){
   //    int tt = out[p] + ((col[p] == 1) ? 1 : -1);
   //    for(auto it: v[p]){
   //       if(it == s or it == par[p])continue;
   //       if(in[it] >= 0)
   //          tt += in[it];
   //    }
   //    if(tt >= 0)
   //       out[s] = tt;
   // }
   for(auto i: v[s]){
      if(i != p){
         out[i] = (out[s]);// + ((col[s] == 1) ? 1 : -1);
         out[i] += in[s];
         if(in[i] >= 0)
            out[i] -= in[i];
         smax(out[i], 0LL);
      }
   }
   for(auto i: v[s]){
      if(i == p)continue;
      dfs2(i, s);
   }
}

void solve(){
   cin>>n;

   for (int i = 1; i <= n; ++i)
   {
      cin>>col[i];
   }

   for (int i = 0; i+1 < n; ++i)
   {
      int x, y;cin >> x >> y;
      v[x].push_back(y);
      v[y].push_back(x);
   }

   dfs(1, -1);
   dfs2(1, -1);

   for (int i = 1; i <= n; ++i)
   {
      cout << in[i] + out[i] << " ";
   }
}

int32_t main(){_

   int t = 1;
   //cin >> t;

   while(t--){
     solve();
     cout << endl;
   }

   return 0;
}


#include <bits/stdc++.h>
#define int long long
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
const int inf = 2e9;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T> void smin(T& a, T val) {if (a > val) a = val;}template<class T> void smax(T& a, T val) {if (a < val) a = val;}
const int N = 2*(int)1e5 + 10;

int n, col[N], in[N], par[N], out[N], bstpar[N];
vector<int> v[N];

//if this is graph makes sure to loop for all the unvisited vertices, i.e, the graph may be unconnected
void dfs(int s, int p){
   in[s] = (col[s]);
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s);
         if(in[i] >= 0){
            in[s] += in[i];
         }
      }
   }
}

int ans[N];
#define dp in
void dfs2(int s, int p){
   for(auto i: v[s]){
      if(i == p)continue;
      int old1 = dp[s];
      int old2 = dp[i];
      dp[s] -= max(0LL, dp[i]);
      dp[i] += max(0LL, dp[s]);
      ans[i] = dp[i];
      dfs2(i, s);
      dp[s] = old1;
      dp[i] = old2;
   }
}

void solve(){
   cin>>n;

   for (int i = 1; i <= n; ++i)
   {
      cin>>col[i];
      col[i] = 2*col[i] - 1;
   }

   for (int i = 0; i+1 < n; ++i)
   {
      int x, y;cin >> x >> y;
      v[x].push_back(y);
      v[y].push_back(x);
   }

   dfs(1, -1);
   ans[1] = in[1];
   dfs2(1, -1);

   for (int i = 1; i <= n; ++i)
   {
      cout<<ans[i]<<" ";
   }
}

int32_t main(){_

   int t = 1;
   //cin >> t;

   while(t--){
     solve();
     cout << endl;
   }

   return 0;
}


#include <bits/stdc++.h>
using namespace std ;

#define ff       first
#define ss       second
#define pb       push_back

typedef long long        ll ;
typedef pair<int,pair<int,int>>    pii ;

const int N = 2e5+2 ;
const int mod = 1e9+7 ;

int color[N] ;
vector <int> G[N] ;
int ans[N] ;
int mx[N] ;

int dfs ( int u, int parent ) {
    mx[u] = color[u] ;
    for ( auto v:G[u] ) {
        if ( v!=parent ) {
            if ( dfs (v, u) >= 0 ) mx[u] += dfs(v, u) ;
        }
    }
    return mx[u] ;
}

void go ( int u, int parent, int carry ) {
    ans[u] = max (mx[u] + carry, mx[u]);
    for ( auto v:G[u] ) {
        if ( v!=parent ) go(v,u,mx[u]-max(0,mx[v])+carry) ;
    }
}

int main() {
    #ifdef LOCAL
    freopen("input.txt", "r",stdin) ;
    #endif // LOCAL
    ios_base::sync_with_stdio(0) ;
    cin.tie(0) ;cout.tie(0) ;
    int n ;
    cin >> n ;
    for ( int i = 0 ; i < n ; ++i ) {
        cin >> color[i] ;
        if ( color[i] == 0 ) color[i]-- ;
    }
    for ( int i = 0 ; i < n-1 ; ++i ) {
        int u, v ;
        cin >> u >> v ;
        u-- ; v--;
        G[u].pb ( v ) ;
        G[v].pb ( u ) ;
    }
    dfs(0,-1) ;
    go(0,-1,0) ;
    for ( int i = 0 ; i < n ; ++i ) cout << ans[i] << ' ' ;
    cout << '\n' ;
}


#include <bits/stdc++.h>
using namespace std ;

#define ff       first
#define ss       second
#define pb       push_back

typedef long long        ll ;
typedef pair<int,pair<int,int>>    pii ;

const int N = 2e5+2 ;
const int mod = 1e9+7 ;

int color[N] ;
vector <int> G[N] ;
int ans[N] ;
int mx[N] ;

int dfs ( int u, int parent ) {
    mx[u] = color[u] ;
    for ( auto v:G[u] ) {
        if ( v!=parent ) {
            if ( dfs (v, u) >= 0 ) mx[u] += dfs(v, u) ;
        }
    }
    return mx[u] ;
}

void go ( int u, int parent, int carry ) {
    ans[u] = max (mx[u] + carry, mx[u]);
    for ( auto v:G[u] ) {
        if ( v!=parent ) go(v,u,mx[u]-max(0,mx[v])+max(0,carry)) ;
    }
}

int main() {
    #ifdef LOCAL
    freopen("input.txt", "r",stdin) ;
    #endif // LOCAL
    ios_base::sync_with_stdio(0) ;
    cin.tie(0) ;cout.tie(0) ;
    int n ;
    cin >> n ;
    for ( int i = 0 ; i < n ; ++i ) {
        cin >> color[i] ;
        if ( color[i] == 0 ) color[i]-- ;
    }
    for ( int i = 0 ; i < n-1 ; ++i ) {
        int u, v ;
        cin >> u >> v ;
        u-- ; v--;
        G[u].pb ( v ) ;
        G[v].pb ( u ) ;
    }
    dfs(0,-1) ;
    go(0,-1,0) ;
    for ( int i = 0 ; i < n ; ++i ) cout << ans[i] << ' ' ;
    cout << '\n' ;
}


#include <bits/stdc++.h>
using namespace std ;

#define ff       first
#define ss       second
#define pb       push_back

typedef long long        ll ;
typedef pair<int,pair<int,int>>    pii ;

const int N = 2e5+2 ;
const int mod = 1e9+7 ;

int color[N] ;
vector <int> G[N] ;
int ans[N] ;
int mx[N] ;

int dfs ( int u, int parent ) {
    mx[u] = color[u] ;
    for ( auto v:G[u] ) {
        if ( v!=parent ) {
            if ( dfs (v, u) >= 0 ) mx[u] += dfs(v, u) ;
        }
    }
    return mx[u] ;
}

int go ( int u, int parent, int carry ) {
    ans[u] = max (mx[u] + carry, mx[u]);
    for ( auto v:G[u] ) {
        if ( v!=parent ) go(v,u,(ans[u] == mx[u]?mx[u]-max(0,mx[v]):carry+color[u])) ;
    }
}

int main() {
    #ifdef LOCAL
    freopen("input.txt", "r",stdin) ;
    #endif // LOCAL
    ios_base::sync_with_stdio(0) ;
    cin.tie(0) ;cout.tie(0) ;
    int n ;
    cin >> n ;
    for ( int i = 0 ; i < n ; ++i ) {
        cin >> color[i] ;
        if ( color[i] == 0 ) color[i]-- ;
    }
    for ( int i = 0 ; i < n-1 ; ++i ) {
        int u, v ;
        cin >> u >> v ;
        u-- ; v--;
        G[u].pb ( v ) ;
        G[v].pb ( u ) ;
    }
    dfs(0,-1) ;
    go(0,-1,0) ;
    for ( int i = 0 ; i < n ; ++i ) cout << ans[i] << ' ' ;
    cout << '\n' ;
}


#include <bits/stdc++.h>
using namespace std ;

#define ff       first
#define ss       second
#define pb       push_back

typedef long long        ll ;
typedef pair<int,pair<int,int>>    pii ;

const int N = 2e5+2 ;
const int mod = 1e9+7 ;

int color[N] ;
vector <int> G[N] ;
int ans[N] ;
int mx[N] ;

int dfs ( int u, int parent ) {
    mx[u] = color[u] ;
    for ( auto v:G[u] ) {
        if ( v!=parent ) {
            mx[u] += max (0,dfs(v, u)) ;
        }
    }
    return mx[u] ;
}

void go ( int u, int parent, int carry ) {
    ans[u] = max (mx[u] + carry, mx[u]);
    for ( auto v:G[u] ) {
        if ( v!=parent ) go(v,u,mx[u]-max(0,mx[v])+max(0,carry)) ;
    }
}

int main() {
    #ifdef LOCAL
    freopen("input.txt", "r",stdin) ;
    #endif // LOCAL
    ios_base::sync_with_stdio(0) ;
    cin.tie(0) ;cout.tie(0) ;
    int n ;
    cin >> n ;
    for ( int i = 0 ; i < n ; ++i ) {
        cin >> color[i] ;
        if ( color[i] == 0 ) color[i]-- ;
    }
    for ( int i = 0 ; i < n-1 ; ++i ) {
        int u, v ;
        cin >> u >> v ;
        u-- ; v--;
        G[u].pb ( v ) ;
        G[v].pb ( u ) ;
    }
    dfs(0,-1) ;
    go(0,-1,0) ;
    for ( int i = 0 ; i < n ; ++i ) cout << ans[i] << ' ' ;
    cout << '\n' ;
}


#include <bits/stdc++.h>
using namespace std ;

#define ff       first
#define ss       second
#define pb       push_back

typedef long long        ll ;
typedef pair<int,pair<int,int>>    pii ;

const int N = 2e5+2 ;
const int mod = 1e9+7 ;

int color[N] ;
vector <int> G[N] ;
int ans[N] ;
int mx[N] ;

int dfs ( int u, int parent ) {
    mx[u] = color[u] ;
    for ( auto v:G[u] ) {
        if ( v!=parent ) {
            if ( dfs (v, u) >= 0 ) mx[u] += dfs(v, u) ;
        }
    }
    return mx[u] ;
}

void go ( int u, int parent, int carry ) {
    ans[u] = max (mx[u] + carry, mx[u]);
    for ( auto v:G[u] ) {
        if ( v!=parent ) go(v,u,(ans[u] == mx[u]?mx[u]-max(0,mx[v]):carry+color[u])) ;
    }
}

int main() {
    #ifdef LOCAL
    freopen("input.txt", "r",stdin) ;
    #endif // LOCAL
    ios_base::sync_with_stdio(0) ;
    cin.tie(0) ;cout.tie(0) ;
    int n ;
    cin >> n ;
    for ( int i = 0 ; i < n ; ++i ) {
        cin >> color[i] ;
        if ( color[i] == 0 ) color[i]-- ;
    }
    for ( int i = 0 ; i < n-1 ; ++i ) {
        int u, v ;
        cin >> u >> v ;
        u-- ; v--;
        G[u].pb ( v ) ;
        G[v].pb ( u ) ;
    }
    dfs(0,-1) ;
    go(0,-1,0) ;
    for ( int i = 0 ; i < n ; ++i ) cout << ans[i] << ' ' ;
    cout << '\n' ;
}


#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define ALLR(v) std::rbegin(v), std::rend(v)
using ll = std::int64_t;
using ull = std::uint64_t;
using pii = std::pair<int, int>;
using tii = std::tuple<int, int, int>;
using pll = std::pair<ll, ll>;
using tll = std::tuple<ll, ll, ll>;
template <typename T> using vec = std::vector<T>;
template <typename T> using vvec = vec<vec<T>>;
template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return std::min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return std::max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return std::max(low, std::min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { return t = clamp(t, low, high); }
template <typename T> T make_v(T init) { return init; }
template <typename T, typename... Tail> auto make_v(T init, std::size_t s, Tail... tail) { auto v = std::move(make_v(init, tail...)); return vec<decltype(v)>(s, v); }
template <typename T, std::size_t Head, std::size_t ...Tail> struct multi_dem_array { using type = std::array<typename multi_dem_array<T, Tail...>::type, Head>; };
template <typename T, std::size_t Head> struct multi_dem_array<T, Head> { using type = std::array<T, Head>; };
template <typename T, std::size_t ...Args> using mdarray = typename multi_dem_array<T, Args...>::type;
namespace init__ { struct InitIO { InitIO() { std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(30); } } init_io; }

namespace graph {

using Node = ll;
using Weight = ll;
using Edge = std::pair<Node, Weight>;

template <bool Directed>
struct Graph : public vvec<Edge> {
    using vvec<Edge>::vvec;

    void add_edge(Node f, Node t, Weight w = 1) {
        (*this)[f].emplace_back(t, w);
        if (!Directed) (*this)[t].emplace_back(f, w);
    }

    Graph<Directed> build_inv() const {
        Graph<Directed> ret(this->size());
        for (Node i = 0; i < this->size(); i++) {
            for (const Edge &e : (*this)[i]) {
                Node j;
                Weight w;
                std::tie(j, w) = e;
                if (!Directed && j < i) continue;
                ret.add_edge(j, i, w);
            }
        }

        return ret;
    }
};

}

struct Solver {
    ll n;
    const graph::Graph<false> &tree;
    const vec<ll> &a;
    vvec<ll> dp1, ldp, rdp;
    vec<ll> ans;

    Solver(const graph::Graph<false> &tree, const vec<ll> &a)
        : n(tree.size()), tree(tree), a(a), dp1(n), ldp(n), rdp(n), ans(n)
    {
        for (ll i = 0; i < n; i++) {
            auto sz = tree[i].size();
            dp1[i].resize(sz);
            ldp[i].resize(sz + 1);
            rdp[i].resize(sz + 1);
        }
    }

    ll dfs1(ll cur, ll pre) {
        ll ret = 0;
        for (ll i = 0; i < tree[cur].size(); i++) {
            ll nxt = tree[cur][i].first;
            if (pre == nxt) continue;
            ll tmp = dfs1(nxt, cur);
            dp1[cur][i] = tmp;
            ret += std::max<ll>(tmp, 0);
        }
        ll addv = (a[cur] ? 1 : -1);
        ans[cur] += ret + addv;
        ret = var_max(ret + addv, addv, (ll)0);
        return ret;
    }

    void calc_lrdp(ll cur, ll par, ll pval) {
        auto &lv = ldp[cur], &rv = rdp[cur];
        ll sz = tree[cur].size();
        for (ll i = 0; i < tree[cur].size(); i++) {
            ll nxt = tree[cur][i].first;
            if (nxt == par) {
                dp1[cur][i] = pval;
                break;
            }
        }
        for (ll i = 0; i < sz; i++) {
            ll val = dp1[cur][i];
            lv[i + 1] = lv[i] + val;
        }
        for (ll i = 0; i < sz; i++) {
            ll val = dp1[cur][sz - (i + 1)];
            rv[i + 1] = rv[i] + val;
        }
    }

    void dfs2(ll cur, ll par, ll pval) {
        calc_lrdp(cur, par, pval);
        ll sz = tree[cur].size();
        for (ll i = 0; i < tree[cur].size(); i++) {
            ll nxt = tree[cur][i].first;
            if (nxt == par) continue;
            ll addv = ldp[cur][i] + rdp[cur][sz - (i + 1)];
            if (a[cur]) addv++;
            else addv = std::max<ll>(0, addv - 1);
            ans[nxt] += addv;
            dfs2(nxt, cur, addv);
        }
    }

    const vec<ll>& solve() {
        dfs1(0, -1);
        dfs2(0, -1, -1);
        return ans;
    }
};

int main() {
    ll n;
    std::cin >> n;
    vec<ll> a(n);
    for (auto &&e : a) std::cin >> e;
    graph::Graph<false> tree(n);
    for (ll i = 0; i < n - 1; i++) {
        ll a, b;
        std::cin >> a >> b;
        a--; b--;
        tree.add_edge(a, b);
    }

    Solver solver(tree, a);
    auto ans = solver.solve();
    for (ll i = 0; i < n; i++) std::cout << ans[i] << " \n"[i + 1 == n];
    return 0;
}


#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define ALLR(v) std::rbegin(v), std::rend(v)
using ll = std::int64_t;
using ull = std::uint64_t;
using pii = std::pair<int, int>;
using tii = std::tuple<int, int, int>;
using pll = std::pair<ll, ll>;
using tll = std::tuple<ll, ll, ll>;
template <typename T> using vec = std::vector<T>;
template <typename T> using vvec = vec<vec<T>>;
template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return std::min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return std::max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return std::max(low, std::min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { return t = clamp(t, low, high); }
template <typename T> T make_v(T init) { return init; }
template <typename T, typename... Tail> auto make_v(T init, std::size_t s, Tail... tail) { auto v = std::move(make_v(init, tail...)); return vec<decltype(v)>(s, v); }
template <typename T, std::size_t Head, std::size_t ...Tail> struct multi_dem_array { using type = std::array<typename multi_dem_array<T, Tail...>::type, Head>; };
template <typename T, std::size_t Head> struct multi_dem_array<T, Head> { using type = std::array<T, Head>; };
template <typename T, std::size_t ...Args> using mdarray = typename multi_dem_array<T, Args...>::type;
namespace init__ { struct InitIO { InitIO() { std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(30); } } init_io; }

namespace graph {

using Node = ll;
using Weight = ll;
using Edge = std::pair<Node, Weight>;

template <bool Directed>
struct Graph : public vvec<Edge> {
    using vvec<Edge>::vvec;

    void add_edge(Node f, Node t, Weight w = 1) {
        (*this)[f].emplace_back(t, w);
        if (!Directed) (*this)[t].emplace_back(f, w);
    }

    Graph<Directed> build_inv() const {
        Graph<Directed> ret(this->size());
        for (Node i = 0; i < this->size(); i++) {
            for (const Edge &e : (*this)[i]) {
                Node j;
                Weight w;
                std::tie(j, w) = e;
                if (!Directed && j < i) continue;
                ret.add_edge(j, i, w);
            }
        }

        return ret;
    }
};

}

struct Solver {
    ll n;
    const graph::Graph<false> &tree;
    const vec<ll> &a;
    vvec<ll> dp1, ldp, rdp;
    vec<ll> ans;

    Solver(const graph::Graph<false> &tree, const vec<ll> &a)
        : n(tree.size()), tree(tree), a(a), dp1(n), ldp(n), rdp(n), ans(n)
    {
        for (ll i = 0; i < n; i++) {
            auto sz = tree[i].size();
            dp1[i].resize(sz);
            ldp[i].resize(sz + 1);
            rdp[i].resize(sz + 1);
        }
    }

    ll dfs1(ll cur, ll pre) {
        ll ret = 0;
        for (ll i = 0; i < tree[cur].size(); i++) {
            ll nxt = tree[cur][i].first;
            if (pre == nxt) continue;
            ll tmp = dfs1(nxt, cur);
            dp1[cur][i] = tmp;
            ret += std::max<ll>(tmp, 0);
        }
        ll addv = (a[cur] ? 1 : -1);
        ans[cur] += ret + addv;
        ret = std::max(ret + addv, addv);
        return ret;
    }

    void calc_lrdp(ll cur, ll par, ll pval) {
        auto &lv = ldp[cur], &rv = rdp[cur];
        ll sz = tree[cur].size();
        for (ll i = 0; i < sz; i++) {
            ll nxt = tree[cur][i].first;
            if (nxt == par) dp1[cur][i] = pval;
            ll val = dp1[cur][i];
            lv[i + 1] = lv[i] + val;
        }
        for (ll i = 0; i < sz; i++) {
            ll val = dp1[cur][sz - (i + 1)];
            rv[i + 1] = rv[i] + val;
        }
    }

    void dfs2(ll cur, ll par, ll pval) {
        calc_lrdp(cur, par, pval);
        ll sz = tree[cur].size();
        for (ll i = 0; i < tree[cur].size(); i++) {
            ll nxt = tree[cur][i].first;
            if (nxt == par) continue;
            ll addv = ldp[cur][i] + rdp[cur][sz - (i + 1)];
            if (a[cur]) addv++;
            else addv = std::max<ll>(0, addv - 1);
            ans[nxt] += addv;
            dfs2(nxt, cur, addv);
        }
    }

    const vec<ll>& solve() {
        dfs1(0, -1);
        dfs2(0, -1, -1);
        return ans;
    }
};

int main() {
    ll n;
    std::cin >> n;
    vec<ll> a(n);
    for (auto &&e : a) std::cin >> e;
    graph::Graph<false> tree(n);
    for (ll i = 0; i < n - 1; i++) {
        ll a, b;
        std::cin >> a >> b;
        a--; b--;
        tree.add_edge(a, b);
    }

    Solver solver(tree, a);
    auto ans = solver.solve();
    for (ll i = 0; i < n; i++) std::cout << ans[i] << " \n"[i + 1 == n];
    return 0;
}


#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define ALLR(v) std::rbegin(v), std::rend(v)
using ll = std::int64_t;
using ull = std::uint64_t;
using pii = std::pair<int, int>;
using tii = std::tuple<int, int, int>;
using pll = std::pair<ll, ll>;
using tll = std::tuple<ll, ll, ll>;
template <typename T> using vec = std::vector<T>;
template <typename T> using vvec = vec<vec<T>>;
template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return std::min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return std::max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return std::max(low, std::min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { return t = clamp(t, low, high); }
template <typename T> T make_v(T init) { return init; }
template <typename T, typename... Tail> auto make_v(T init, std::size_t s, Tail... tail) { auto v = std::move(make_v(init, tail...)); return vec<decltype(v)>(s, v); }
template <typename T, std::size_t Head, std::size_t ...Tail> struct multi_dem_array { using type = std::array<typename multi_dem_array<T, Tail...>::type, Head>; };
template <typename T, std::size_t Head> struct multi_dem_array<T, Head> { using type = std::array<T, Head>; };
template <typename T, std::size_t ...Args> using mdarray = typename multi_dem_array<T, Args...>::type;
namespace init__ { struct InitIO { InitIO() { std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(30); } } init_io; }

namespace graph {

using Node = ll;
using Weight = ll;
using Edge = std::pair<Node, Weight>;

template <bool Directed>
struct Graph : public vvec<Edge> {
    using vvec<Edge>::vvec;

    void add_edge(Node f, Node t, Weight w = 1) {
        (*this)[f].emplace_back(t, w);
        if (!Directed) (*this)[t].emplace_back(f, w);
    }

    Graph<Directed> build_inv() const {
        Graph<Directed> ret(this->size());
        for (Node i = 0; i < this->size(); i++) {
            for (const Edge &e : (*this)[i]) {
                Node j;
                Weight w;
                std::tie(j, w) = e;
                if (!Directed && j < i) continue;
                ret.add_edge(j, i, w);
            }
        }

        return ret;
    }
};

}

struct Solver {
    ll n;
    const graph::Graph<false> &tree;
    const vec<ll> &a;
    vvec<ll> dp1, ldp, rdp;
    vec<ll> ans;

    Solver(const graph::Graph<false> &tree, const vec<ll> &a)
        : n(tree.size()), tree(tree), a(a), dp1(n), ldp(n), rdp(n), ans(n)
    {
        for (ll i = 0; i < n; i++) {
            auto sz = tree[i].size();
            dp1[i].resize(sz);
            ldp[i].resize(sz + 1);
            rdp[i].resize(sz + 1);
        }
    }

    ll dfs1(ll cur, ll pre) {
        ll ret = 0;
        for (ll i = 0; i < tree[cur].size(); i++) {
            ll nxt = tree[cur][i].first;
            if (pre == nxt) continue;
            ll tmp = dfs1(nxt, cur);
            dp1[cur][i] = tmp;
            ret += std::max<ll>(tmp, 0);
        }
        ll addv = (a[cur] ? 1 : -1);
        ans[cur] += ret + addv;
        ret = var_max(ret + addv, addv, (ll)0);
        return ret;
    }

    void calc_lrdp(ll cur, ll par, ll pval) {
        auto &lv = ldp[cur], &rv = rdp[cur];
        ll sz = tree[cur].size();
        for (ll i = 0; i < sz; i++) {
            ll nxt = tree[cur][i].first;
            if (nxt == par) dp1[cur][i] = pval;
            ll val = dp1[cur][i];
            lv[i + 1] = lv[i] + val;
        }
        for (ll i = 0; i < sz; i++) {
            ll val = dp1[cur][sz - (i + 1)];
            rv[i + 1] = rv[i] + val;
        }
    }

    void dfs2(ll cur, ll par, ll pval) {
        calc_lrdp(cur, par, pval);
        ll sz = tree[cur].size();
        for (ll i = 0; i < tree[cur].size(); i++) {
            ll nxt = tree[cur][i].first;
            if (nxt == par) continue;
            ll addv = ldp[cur][i] + rdp[cur][sz - (i + 1)];
            if (a[cur]) addv++;
            else addv = std::max<ll>(0, addv - 1);
            ans[nxt] += addv;
            dfs2(nxt, cur, addv);
        }
    }

    const vec<ll>& solve() {
        dfs1(0, -1);
        dfs2(0, -1, -1);
        return ans;
    }
};

int main() {
    ll n;
    std::cin >> n;
    vec<ll> a(n);
    for (auto &&e : a) std::cin >> e;
    graph::Graph<false> tree(n);
    for (ll i = 0; i < n - 1; i++) {
        ll a, b;
        std::cin >> a >> b;
        a--; b--;
        tree.add_edge(a, b);
    }

    Solver solver(tree, a);
    auto ans = solver.solve();
    for (ll i = 0; i < n; i++) std::cout << ans[i] << " \n"[i + 1 == n];
    return 0;
}


#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define ALLR(v) std::rbegin(v), std::rend(v)
using ll = std::int64_t;
using ull = std::uint64_t;
using pii = std::pair<int, int>;
using tii = std::tuple<int, int, int>;
using pll = std::pair<ll, ll>;
using tll = std::tuple<ll, ll, ll>;
template <typename T> using vec = std::vector<T>;
template <typename T> using vvec = vec<vec<T>>;
template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return std::min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return std::max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return std::max(low, std::min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { return t = clamp(t, low, high); }
template <typename T> T make_v(T init) { return init; }
template <typename T, typename... Tail> auto make_v(T init, std::size_t s, Tail... tail) { auto v = std::move(make_v(init, tail...)); return vec<decltype(v)>(s, v); }
template <typename T, std::size_t Head, std::size_t ...Tail> struct multi_dem_array { using type = std::array<typename multi_dem_array<T, Tail...>::type, Head>; };
template <typename T, std::size_t Head> struct multi_dem_array<T, Head> { using type = std::array<T, Head>; };
template <typename T, std::size_t ...Args> using mdarray = typename multi_dem_array<T, Args...>::type;
namespace init__ { struct InitIO { InitIO() { std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(30); } } init_io; }

namespace graph {

using Node = ll;
using Weight = ll;
using Edge = std::pair<Node, Weight>;

template <bool Directed>
struct Graph : public vvec<Edge> {
    using vvec<Edge>::vvec;

    void add_edge(Node f, Node t, Weight w = 1) {
        (*this)[f].emplace_back(t, w);
        if (!Directed) (*this)[t].emplace_back(f, w);
    }

    Graph<Directed> build_inv() const {
        Graph<Directed> ret(this->size());
        for (Node i = 0; i < this->size(); i++) {
            for (const Edge &e : (*this)[i]) {
                Node j;
                Weight w;
                std::tie(j, w) = e;
                if (!Directed && j < i) continue;
                ret.add_edge(j, i, w);
            }
        }

        return ret;
    }
};

}

void max_a(ll &ret, ll ai) {
    if (ai) ret = std::max<ll>(1, ret + 1);
    else ret = std::max<ll>(0, ret - 1);
}

ll dfs(ll cur, ll pre, const graph::Graph<false> &tree, vec<std::map<ll, ll>> &cnts, const vec<ll> &a) {
    if (cnts[pre].find(cur) != cnts[pre].end()) {
        ll ret = cnts[pre][cur];
        return ret;
    }
    ll ret = 0;
    for (auto &&e : tree[cur]) {
        ll nxt = e.first;
        if (pre == nxt) continue;
        ret += std::max<ll>(0, dfs(nxt, cur, tree, cnts, a));
    }

    max_a(ret, a[cur]);
    cnts[pre][cur] = ret;
    return ret;
}

int main() {
    ll n;
    std::cin >> n;
    vec<ll> a(n);
    for (ll &e : a) std::cin >> e;
    graph::Graph<false> tree(n);
    for (ll i = 1; i < n; i++) {
        ll a, b;
        std::cin >> a >> b;
        tree.add_edge(a - 1, b - 1);
    }

    vec<std::map<ll, ll>> cnts(n);
    for (ll cur = 0; cur < n; cur++) for (auto &&e : tree[cur]) {
        ll nxt = e.first;
        dfs(nxt, cur, tree, cnts, a);
    }
    for (ll i = 0; i < n; i++) {
        ll ans = 0;
        for (auto &&e : cnts[i]) ans += std::max<ll>(0, e.second);
        ans += (a[i] ? 1 : -1);
        std::cout << ans << " \n"[i + 1 == n];
    }
    return 0;
}


#include <bits/stdc++.h>
#define ALL(v) std::begin(v), std::end(v)
#define ALLR(v) std::rbegin(v), std::rend(v)
using ll = std::int64_t;
using ull = std::uint64_t;
using pii = std::pair<int, int>;
using tii = std::tuple<int, int, int>;
using pll = std::pair<ll, ll>;
using tll = std::tuple<ll, ll, ll>;
template <typename T> using vec = std::vector<T>;
template <typename T> using vvec = vec<vec<T>>;
template <typename T> const T& var_min(const T &t) { return t; }
template <typename T> const T& var_max(const T &t) { return t; }
template <typename T, typename... Tail> const T& var_min(const T &t, const Tail&... tail) { return std::min(t, var_min(tail...)); }
template <typename T, typename... Tail> const T& var_max(const T &t, const Tail&... tail) { return std::max(t, var_max(tail...)); }
template <typename T, typename... Tail> void chmin(T &t, const Tail&... tail) { t = var_min(t, tail...); }
template <typename T, typename... Tail> void chmax(T &t, const Tail&... tail) { t = var_max(t, tail...); }
template <typename T> const T& clamp(const T &t, const T &low, const T &high) { return std::max(low, std::min(high, t)); }
template <typename T> void chclamp(T &t, const T &low, const T &high) { return t = clamp(t, low, high); }
template <typename T> T make_v(T init) { return init; }
template <typename T, typename... Tail> auto make_v(T init, std::size_t s, Tail... tail) { auto v = std::move(make_v(init, tail...)); return vec<decltype(v)>(s, v); }
template <typename T, std::size_t Head, std::size_t ...Tail> struct multi_dem_array { using type = std::array<typename multi_dem_array<T, Tail...>::type, Head>; };
template <typename T, std::size_t Head> struct multi_dem_array<T, Head> { using type = std::array<T, Head>; };
template <typename T, std::size_t ...Args> using mdarray = typename multi_dem_array<T, Args...>::type;
namespace init__ { struct InitIO { InitIO() { std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); std::cout << std::fixed << std::setprecision(30); } } init_io; }

namespace graph {

using Node = ll;
using Weight = ll;
using Edge = std::pair<Node, Weight>;

template <bool Directed>
struct Graph : public vvec<Edge> {
    using vvec<Edge>::vvec;

    void add_edge(Node f, Node t, Weight w = 1) {
        (*this)[f].emplace_back(t, w);
        if (!Directed) (*this)[t].emplace_back(f, w);
    }

    Graph<Directed> build_inv() const {
        Graph<Directed> ret(this->size());
        for (Node i = 0; i < this->size(); i++) {
            for (const Edge &e : (*this)[i]) {
                Node j;
                Weight w;
                std::tie(j, w) = e;
                if (!Directed && j < i) continue;
                ret.add_edge(j, i, w);
            }
        }

        return ret;
    }
};

}

void max_a(ll &ret, ll ai) {
    if (ai) ret = std::max<ll>(1, ret + 1);
    else ret = std::max<ll>(0, ret - 1);
}

ll dfs(ll cur_i, ll pre, const graph::Graph<false> &tree, vvec<ll> &cnts, const vec<ll> &a) {
    if (cnts[pre][cur_i] != -1) return cnts[pre][cur_i];

    ll ret = 0;
    ll cur = tree[pre][cur_i].first;
    for (ll i = 0; i < tree[cur].size(); i++) {
        ll nxt = tree[cur][i].first;
        if (pre == nxt) continue;
        ret += std::max<ll>(0, dfs(i, cur, tree, cnts, a));
    }

    max_a(ret, a[cur]);
    cnts[pre][cur_i] = ret;
    return ret;
}

int main() {
    ll n;
    std::cin >> n;
    vec<ll> a(n);
    for (ll &e : a) std::cin >> e;
    graph::Graph<false> tree(n);
    for (ll i = 1; i < n; i++) {
        ll a, b;
        std::cin >> a >> b;
        tree.add_edge(a - 1, b - 1);
    }

    vvec<ll> cnts(n);
    for (ll i = 0; i < n; i++) cnts[i].resize(tree[i].size(), -1);
    for (ll cur = 0; cur < n; cur++) for (ll i = 0; i < tree[cur].size(); i++) dfs(i, cur, tree, cnts, a);
    for (ll i = 0; i < n; i++) {
        ll ans = 0;
        for (ll e : cnts[i]) ans += std::max<ll>(0, e);
        ans += (a[i] ? 1 : -1);
        std::cout << ans << " \n"[i + 1 == n];
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <queue>

using namespace std;

int dfs(vector<vector<int>>& tree, vector<int>& colors, int vertex, int parent) {
	int maxdiff = colors[vertex] ? 1 : -1;
	for (int child : tree[vertex]) {
		if (child == parent) continue;
		maxdiff += max(0, dfs(tree, colors, child, vertex));
	}
	return maxdiff;
}

int main() {
	int num, c, a, b;
	cin >> num;
	vector<int> colors(num + 1);
	for (int i=0; i<num; i++) {
		cin >> c;
		colors[i+1] = c;
	}
	vector<vector<int>> tree(num + 1);
	for (int i=0; i<num-1; i++) {
		cin >> a >> b;
		tree[a].push_back(b);
		tree[b].push_back(a);
	}

	vector<int> diffs;

	for (int i=1; i<num+1; i++)
		diffs.push_back(dfs(tree, colors, i, -1));

	for (auto i : diffs)
		cout << i << " ";
	cout << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int dfs(map<pair<int,int>, int>& cache, vector<vector<int>>& tree, vector<int>& colors, int vertex, int parent) {
	auto it = cache.find({parent, vertex});
	if (it != cache.end())
		return it->second;
	int maxdiff = colors[vertex] ? 1 : -1;
	for (int child : tree[vertex]) {
		if (child == parent) continue;
		maxdiff += max(0, dfs(cache, tree, colors, child, vertex));
	}
	cache.insert({{parent, vertex}, maxdiff});
	return maxdiff;
}

int main() {
	int num, c, a, b;
	cin >> num;
	vector<int> colors(num + 1);
	for (int i=0; i<num; i++) {
		cin >> c;
		colors[i+1] = c;
	}
	vector<vector<int>> tree(num + 1);
	for (int i=0; i<num-1; i++) {
		cin >> a >> b;
		tree[a].push_back(b);
		tree[b].push_back(a);
	}

	vector<int> diffs;

	map<pair<int,int>, int> cache;

	for (int i=1; i<num+1; i++)
		diffs.push_back(dfs(cache, tree, colors, i, -1));

	for (auto i : diffs)
		cout << i << " ";
	cout << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int dfs(vector<int>& res, vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	int maxdiff = colors[vertex] ? 1 : -1;
	for (int child : tree[vertex]) {
		maxdiff += max(0, dfs(res, tree, colors, child));
	}
	res[vertex] = maxdiff;
	return maxdiff;
}

void update(vector<int>& res, vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	for (int child : tree[vertex]) {
		if (res[child] < 0)
			res[child] += (res[vertex] >= 0 ? res[vertex] : 0);
		else
			res[child] = (res[vertex] > 0 ? res[vertex] : res[child]);
		update(res, tree, colors, child);
	}
}

int main() {
	int num, c, a, b;
	cin >> num;
	vector<int> colors(num + 1);
	for (int i=0; i<num; i++) {
		cin >> c;
		colors[i+1] = c;
	}
	vector<vector<int>> tree(num + 1);
	vector<int> ind(num + 1);
	for (int i=0; i<num-1; i++) {
		cin >> a >> b;
		tree[a].push_back(b);
		ind[b]++;
	}

	vector<int> res(num + 1);
	int root = 1;
	for (; root<ind.size(); root++) {
		if (ind[root] == 0)
			break;
	}

	dfs(res, tree, colors, root);
	update(res, tree, colors, root);

	for (int i=1; i<res.size(); i++)
		cout << res[i] << " ";
	cout << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int dfs(vector<int>& res, vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	int maxdiff = colors[vertex] ? 1 : -1;
	for (int child : tree[vertex]) {
		maxdiff += max(0, dfs(res, tree, colors, child));
	}
	res[vertex] = maxdiff;
	return maxdiff;
}

void update(vector<int>& res, vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	for (int child : tree[vertex]) {
		if (res[child] < 0)
			res[child] += res[vertex] >= 0 ? res[vertex] : 0;
		else
			res[child] = res[vertex] >= 0 ? res[vertex] : res[child];
		update(res, tree, colors, child);
	}
}

int main() {
	int num, c, a, b;
	cin >> num;
	vector<int> colors(num + 1);
	for (int i=0; i<num; i++) {
		cin >> c;
		colors[i+1] = c;
	}
	vector<vector<int>> tree(num + 1);
	vector<int> ind(num + 1);
	for (int i=0; i<num-1; i++) {
		cin >> a >> b;
		tree[a].push_back(b);
		ind[b]++;
	}

	vector<int> res(num + 1);
	int root = 1;
	for (; root<ind.size(); root++) {
		if (ind[root] == 0)
			break;
	}

	dfs(res, tree, colors, root);
	update(res, tree, colors, root);

	for (int i=1; i<res.size(); i++)
		cout << res[i] << " ";
	cout << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int dfs(vector<int>& res, vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	int maxdiff = colors[vertex] ? 1 : -1;
	for (int child : tree[vertex]) {
		maxdiff += max(0, dfs(res, tree, colors, child));
	}
	res[vertex] = maxdiff;
	return maxdiff;
}

void update(vector<int>& res, vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	for (int child : tree[vertex]) {
		if (res[child] <= 0)
			res[child] += (res[vertex] >= 0 ? res[vertex] : 0);
		else
			res[child] = max(res[vertex], res[child]);
		update(res, tree, colors, child);
	}
}

int main() {
	int num, c, a, b;
	cin >> num;
	vector<int> colors(num + 1);
	for (int i=0; i<num; i++) {
		cin >> c;
		colors[i+1] = c;
	}
	vector<vector<int>> tree(num + 1);
	vector<int> ind(num + 1);
	for (int i=0; i<num-1; i++) {
		cin >> a >> b;
		tree[a].push_back(b);
		ind[b]++;
	}

	vector<int> res(num + 1);
	int root = 1;
	for (; root<ind.size(); root++) {
		if (ind[root] == 0)
			break;
	}

	dfs(res, tree, colors, root);
	update(res, tree, colors, root);

	for (int i=1; i<res.size(); i++)
		cout << res[i] << " ";
	cout << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int dfs(vector<int>& res, vector<int>& seen, vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	int maxdiff = colors[vertex] ? 1 : -1;
	seen[vertex] = 1;
	for (int child : tree[vertex]) {
		if (!seen[child])
			maxdiff += max(0, dfs(res, seen, tree, colors, child));
	}
	res[vertex] = maxdiff;
	return maxdiff;
}

void update(vector<int>& res, vector<int>& seen, vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	seen[vertex] = 1;
	for (int child : tree[vertex]) {
		if (seen[child]) continue;
		if (res[child] <= 0)
			res[child] += max(res[vertex], 0);
		else
			res[child] = max(res[vertex], res[child]);
		update(res, seen, tree, colors, child);
	}
}

int main() {
	int num, c, a, b;
	cin >> num;
	vector<int> colors(num + 1);
	for (int i=0; i<num; i++) {
		cin >> c;
		colors[i+1] = c;
	}
	vector<vector<int>> tree(num + 1);
	for (int i=0; i<num-1; i++) {
		cin >> a >> b;
		tree[a].push_back(b);
		tree[b].push_back(a);
	}

	vector<int> seen(num + 1), res(num + 1);
	dfs(res, seen, tree, colors, 1);
	fill(seen.begin(), seen.end(), 0);
	update(res, seen, tree, colors, 1);

	for (int i=1; i<res.size(); i++)
		cout << res[i] << " ";
	cout << endl;
}


#include <iostream>
#include <vector>
#include <queue>

using namespace std;

int dfs(vector<vector<int>>& tree, vector<int>& colors, int vertex, int parent) {
	int val = colors[vertex] ? 1 : -1;
	int maxval = 0;
	for (int child : tree[vertex]) {
		if (child == parent) continue;
		maxval = max(maxval, dfs(tree, colors, child, vertex));
	}
	maxval = max(0, maxval);
	return val + maxval;
}

int calc(vector<vector<int>>& tree, vector<int>& colors, int vertex) {
	int maxdiff = colors[vertex] ? 1 : -1;
	for (int child : tree[vertex]) {
		maxdiff += max(0, dfs(tree, colors, child, vertex));
	}
	return maxdiff;
}

int main() {
	int num, c, a, b;
	cin >> num;
	vector<int> colors(num + 1);
	for (int i=0; i<num; i++) {
		cin >> c;
		colors[i+1] = c;
	}
	vector<vector<int>> tree(num + 1);
	for (int i=0; i<num-1; i++) {
		cin >> a >> b;
		tree[a].push_back(b);
		tree[b].push_back(a);
	}

	vector<int> diffs;

	for (int i=1; i<num+1; i++)
		diffs.push_back(calc(tree, colors, i));

	for (auto i : diffs)
		cout << i << " ";
	cout << endl;
}


/*
 * Author: lanzhiguanhuang
 * Time: 2020-03-13 13:31:19
**/

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define rep(i, a, n) for(int i=a;i<n;++i)
#define repd(i, a, n) for(int i=a;i<=n;++i)

int n, u, v;

vector<int> ccnt;
vector<int> R;
vector<vector<int>> E;
vector<int> C;
vector<int> res;

void dfsU(int root, unordered_set<int> visited, int pcnt) {
  if (pcnt < 0) pcnt = 0;

  int cnt = -1;
  if (C[root] == 1) cnt = 1;
  cnt += pcnt;

  for (auto c : E[root]) {
    if (!visited.count(c)) {
      cnt += ccnt[c];
    }
  }

  res[root] = cnt;
  for (auto c : E[root]) {
    if (!visited.count(c)) {
      visited.insert(c);

      dfsU(c, visited, cnt - ccnt[c]);
    }
  }
}

int dfsD(int root, unordered_set<int> visited) {
  int ss = C[root] == 1 ? 1 : -1;
  for (auto c : E[root]) {
    if (!visited.count(c)) {
      visited.insert(c);
      int cnt = dfsD(c, visited);
      ss += cnt;
    }
  }
  if (ss < 0) ss = 0;
  ccnt[root] = ss;
  return ss;
}

void solve() {
  unordered_set<int> visited;
  visited.insert(0);
  dfsD(0, visited);

  visited.clear();
  visited.insert(0);
  dfsU(0, visited, 0);

  for (auto cnt : res) {
    cout << cnt << ' ';
  }
  cout << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> n;
  ccnt.resize(n);
  res.resize(n);
  E.resize(n);

  int cc;
  rep(i, 0, n) {
    cin >> cc;
    C.push_back(cc);
  }
  rep(i, 0, n - 1) {
    cin >> u >> v;
    E[u - 1].push_back(v - 1);
    E[v - 1].push_back(u - 1);
  }
  solve();

  return 0;
}


/*
 * Author: lanzhiguanhuang
 * Time: 2020-03-13 13:31:19
**/

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define rep(i, a, n) for(int i=a;i<n;++i)
#define repd(i, a, n) for(int i=a;i<=n;++i)

int n, u, v;

vector<int> L;
vector<int> R;
vector<vector<int>> E;
vector<int> C;
vector<int> res;

void dfsU(int root, unordered_set<int> visited, int pcnt) {
  if (pcnt < 0) pcnt = 0;
  int lcnt = L[root];
  int rcnt = R[root];
  int cnt = -1;
  if (C[root] == 1) cnt = 1;
  cnt += lcnt + rcnt + pcnt;
  res[root] = cnt;
  bool flag = true;
  for (auto c : E[root]) {
    if (!visited.count(c)) {
      visited.insert(c);
      if (flag) {
        flag = false;
        // L child
        dfsU(c, visited, cnt - lcnt);
      } else {
        // R child
        dfsU(c, visited, cnt - rcnt);
      }
    }
  }
}

int dfsD(int root, unordered_set<int> visited) {
  bool flag = true;
  L[root] = 0;
  R[root] = 0;
  for (auto c : E[root]) {
    if (!visited.count(c)) {
      visited.insert(c);
      int cnt = dfsD(c, visited);
      if (flag) {
        L[root] = cnt;
        flag = false;
      } else {
        R[root] = cnt;
      }
    }
  }
  int res = C[root] == 1 ? 1 : -1;
  res += L[root];
  res += R[root];
  return max(res, 0);
}

void solve() {
  int root;
  for (int i = 0; i < n; ++i) {
    if (E[i].size() < 3) {
      root = i;
      break;
    }
  }
  unordered_set<int> visited;
  visited.insert(root);
  dfsD(root, visited);

  visited.clear();
  visited.insert(root);
  dfsU(root, visited, 0);

  for (auto cnt : res) {
    cout << cnt << ' ';
  }
  cout << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  cin >> n;
  R.resize(n);
  L.resize(n);
  res.resize(n);
  E.resize(n);

  int cc;
  rep(i, 0, n) {
    cin >> cc;
    C.push_back(cc);
  }
  rep(i, 0, n - 1) {
    cin >> u >> v;
    E[u - 1].push_back(v - 1);
    E[v - 1].push_back(u - 1);
  }
  solve();

  return 0;
}