#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
typedef tuple<int,int,int> i3;

int n, k, a[100005];
vector<int> adj[100005];
vector<ii> dp[100005];
int res[100005];


void dfs(int u, int p = -1){
    dp[u].resize(k, ii(0,0));
    dp[u][0] = ii(a[u], 0);
    for(int v : adj[u]){
        if(v == p) continue;
        dfs(v, u);
        for(int j = 0; j+1 < k; j++){
            dp[u][j+1].first ^= dp[v][j].first;
            dp[u][j+1].second ^= dp[v][j].second;
        }
        dp[u][0].first ^= dp[v][k-1].second;
        dp[u][0].second ^= dp[v][k-1].first;
    }
}

void solve(int u, int p, vector<ii> aux){
    ii par = aux.back();
    rotate(aux.begin(), aux.begin() + k - 1, aux.end());
    swap(aux[0].first, aux[0].second);

    vector<ii> cur_xor = aux;
    // merging with u
    for(int j = 0; j < k; j++){
        cur_xor[j].first ^= dp[u][j].first;
        cur_xor[j].second ^= dp[u][j].second;
    }

    int xorzinho = 0;
    for(int j = 0; j < k; j++)
        xorzinho ^= cur_xor[j].second;
    
    res[u] = (xorzinho != 0);

    for(int v : adj[u]){
        if(v == p) continue;

        // take off the contribution from subtree of v
        vector<ii> nxt_xor = cur_xor;
        {
            for(int j = 1; j < k; j++){
                nxt_xor[j].first ^= dp[v][j-1].first;
                nxt_xor[j].second ^= dp[v][j-1].second;
            }
            nxt_xor[0].first ^= dp[v][k-1].second;
            nxt_xor[0].second ^= dp[v][k-1].first;
        }

        solve(v, u, nxt_xor);
    }
}

int main(){
 
    cout.sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> k;
    for(int i = 0; i < n-1; i++){
        int u, v; cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    for(int i = 1; i <= n; i++)
        cin >> a[i];

    
    dfs(1);
    solve(1, -1, vector<ii>(k, ii(0,0)));

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

	return 0;
}