#include<iostream>
#include<string>
#include<vector>
#include<utility>
#include<algorithm>
#include<map>
#include<set>
#include<cstdlib>
#include<cmath>
#include<numeric>
#include<iomanip>
#include<functional>
#include<cstdlib>
#include<queue>
#include<deque>
#include <iterator>     // std::back_inserter
const double PI = acos(-1);
using namespace std;
using ll =long long;
#define rep(i,n)for(ll i=0;i<(n);i++)
const int mod = 1000000007;
const ll inf = 1e18 + 1;
int ctoi(char c) {
	if (c >= '0' && c <= '9') {
		return c - '0';
	}
	return 0;
}

ll gcd(ll a, ll b) {
	if (a % b == 0) {
		return b;
	}
	else {
		return gcd(b, a % b);
	}
}
ll lcm(ll a, ll b) {
	return a * b / gcd(a, b);
};
//fixed << setprecision(2)
template<class T> inline bool chmin(T& a, T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template<class T> inline bool chmax(T& a, T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

/*�R���r�l�[�V����*/

//ll f[101010], rf[101010];
//ll inv(ll x) {
//	ll res = 1;
//	ll k = mod - 2;
//	ll y = x;
//	while (k) {
//		if (k & 1) res = (res * y) % mod;
//		y = (y * y) % mod;
//		k /= 2;
//	}
//	return res;
//}
//void init() {
//	f[0] = 1;
//	for (ll i = 1; i < 101010;i++) f[i] = (f[i - 1] * i) % mod;
//	for(ll i = 0; i < 101010; i++) rf[i] = inv(f[i]);
//}
////---------------------------------------------------------------------------------------------------
//ll C(int n, int k) {
//	ll a = f[n]; // = n!
//	ll b = rf[n - k]; // = (n-k)!
//	ll c = rf[k]; // = k!
//
//	ll bc = (b * c) % mod;
//
//	return (a * bc) % mod;
//}

///*�R���r�l�[�V����*/
//
///*Union Find*/
//#define MAX_N 200000
//#define MAX_M 200000
//vector<ll>par(MAX_N);
//vector<ll>ran(MAX_N);
//void init(ll N) {
//	rep(i, N) {
//		par[i] = i;
//		ran[i] = 0;
//	}
//}
//ll find(ll x) {
//	if (par[x] == x) {
//		return x;
//	}
//	else {
//		return par[x] = find(par[x]);
//	}
//}
////x��y�̑�����W���𕹍�
//void unite(ll x,ll y) {
//	x = find(x);
//	y = find(y);
//	if (x == y)return;
//	if (ran[x] < ran[y]) {
//		par[x] = y;
//
//	}
//	else {
//		par[y] = x;
//		if (ran[x] == ran[y])ran[x]++;
//	}
//}
//bool same(ll x, ll y) {
//	return find(x) == find(y);
//}
///*Union Find*/
///������=�啶��+32
struct edge {
	vector<int>to;
	ll cost;
	int p;
	ll w;
	int col;
};

int main() {
	int N;
	cin >> N;
	vector<pair<int, pair<int, ll>>>Q(N - 1);
	vector<ll> w(N - 1);
	rep(i, N - 1) {
		cin >> Q[i].first >> Q[i].second.first >> Q[i].second.second;
	}
	sort(Q.begin(), Q.end());
	vector<edge>G(N);
	rep(i, N - 1) {
		G[Q[i].first - 1].to.push_back(Q[i].second.first - 1);
		G[Q[i].second.first - 1].to.push_back(Q[i].first - 1);
		G[Q[i].second.first - 1].p = Q[i].first - 1;
		G[Q[i].second.first - 1].w = Q[i].second.second;
	}
	G[0].cost = 0;
	G[0].p = -1;
	G[0].w = 0;
	queue<int>Qu;
	queue<int>Qu2;
	vector<bool> A(N, true);
	for (int i = 0; i < G[0].to.size(); i++) {
		Qu.push(G[0].to[i]);
		Qu2.push(0);
		A[G[0].to[i]] = false;
	}
	int v;
	while (!Qu.empty()) {
		v = Qu.front();
		Qu.pop();
		G[v].cost = G[Qu2.front()].cost + G[v].w;
		Qu2.pop();
		for (int i = 0; i < G[v].to.size(); i++) {
			if (A[G[v].to[i]]) {
				Qu.push(G[v].to[i]);
				Qu2.push(v);
				A[G[v].to[i]] = false;
			}
		}
	}
	G[0].col = 0;
	vector<bool>B(N, true);
	for (int i = 0; i < G[0].to.size(); i++) {
		Qu.push(G[0].to[i]);
		Qu2.push(0);
		B[G[0].to[i]] = false;
	}

	while (!Qu.empty()) {
		v = Qu.front();
		Qu.pop();
		if (labs(G[v].cost - G[Qu2.front()].cost) % 2 == 0) {
			if (G[Qu2.front()].col == 0) {
				G[v].col = 0;
			}
			else {
				G[v].col = 1;
			}
		}
		else {
			if (G[Qu2.front()].col == 0) {

				G[v].col = 1;
			}
			else {
				G[v].col = 0;
			}
		}
		Qu2.pop();
		for (int i = 0; i < G[v].to.size(); i++) {
			if (B[G[v].to[i]]) {
				Qu.push(G[v].to[i]);
				Qu2.push(v);
				B[G[v].to[i]] = false;
			}
		}
	}
	rep(i, N) {
		cout << G[i].col << endl;
	}

}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef tuple<int,int,int> tii;
#define rep(i,s,n) for(int i=(int)(s);i<(int)(n);i++)

struct edge{
  ll to,cost;
  edge(ll x,ll y){
    to = x;
    cost = y;
  }
};
int main(){
  ll N; cin >> N;
  vector<edge> list[N+1];
  ll dist[N+1];
  memset(dist,-1,sizeof(dist));
  for(ll i=0;i<N;i++){
    ll v,u,w; cin >> v >> u >> w;
    list[v].push_back({u,w});
    list[u].push_back({v,w});
  }
  dist[1] = 0;
  queue<ll> que;
  que.push(1);
  while(!que.empty()){
    ll v = que.front(); que.pop();
    cout << v << endl;
    for(ll i=0;i<list[v].size();i++){
      edge e = list[v][i];
      if(dist[e.to]==-1||dist[e.to]>dist[v]+e.cost){
        dist[e.to] = dist[v]+e.cost;
        que.push(e.to);
      }
    }
  }
  for(int i=1;i<=N;i++){
    if(dist[i]%2==0) cout << 0 << endl;
    else cout << 1 << endl;
  }
}


#include<bits/stdc++.h>
using namespace std;
vector<int>tree[100005];
bool visited[100005];
int color[100005];
void dfs(int curr,bool c){
	visited[curr] = true;
	color[curr] = c;
	for(int i=0; i<tree[curr].size(); i++){
		int nxt = tree[curr][i];
		if(!visited[nxt]) dfs(nxt,!c);
	}
}
int main(){
	int n;
	cin>>n;
	for(int i=1; i<n; i++){
		int a,b,w;
		cin>>a>>b>>w;
		tree[a].push_back(b);
		tree[b].push_back(a);
	}
	dfs(1,0);
	for(int i=1; i<=n; i++) cout<<color[i]<<'\n';
}


// AtCoder ABC126: D - Even Relation
// 2019.9.8 bal4u

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if 1
int getchar_unlocked(void);
int putchar_unlocked(int c);
#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)
#else
#define gc() getchar()
#define pc(c) putchar(c)
#endif

int in() {   // 非負整数の入力
	int n = 0, c = gc();
	do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
	return n;
}

#define MAX 100005
int N;
char col[MAX];
int hi[MAX], *to[MAX], *w[MAX];

void dfs(int now, int par, int c) {
	int i, j;
	col[now] = c;
	for (i = 0; i < hi[now]; i++) if ((j = to[now][i]) != par) {
		if (w[now][i] & 1) dfs(j, now, !c);
		else               dfs(j, now, c);
	}
}

int main()
{
	int i, k, u, v;
	int *memo, sz;

	N = in();
	memo = malloc(N*3*sizeof(int));
	sz = 0; for (i = 1; i < N; i++) {
		memo[sz++] = u = in()-1, memo[sz++] = v = in()-1, memo[sz++] = in();
		hi[u]++, hi[v]++;
	}
	for (i = 0; i < N; i++) if (hi[i]) {
		to[i] = malloc(hi[i]*sizeof(int));
		w[i] = malloc(hi[i]*sizeof(int));
	}
	memset(hi, 0, sizeof(hi));
	i = 0; while (i < sz) {
		u = memo[i++], v = memo[i++];
		k = hi[u]++, to[u][k] = v, w[u][k] = memo[i];
		k = hi[v]++, to[v][k] = u, w[v][k] = memo[i++];
	}
	dfs(0, -1, 0);
	for (i = 0; i < N; i++) pc(col[i]+'0'), pc('\n');
	return 0;
}


#include <stdio.h>
#include <stdbool.h>
typedef long long ll;

ll parent[100005];
ll diff_weight[100005];

void init(ll nmemb);
ll root(ll x);
ll weight(ll x);
ll diff(ll x, ll y);
bool isSameGroup(ll x, ll y);
void unite(ll x, ll y, ll w);
ll groubSize(ll x);

void init(ll nmemb) {
    for (ll i = 0; i < nmemb; i++) {
        parent[i] = -1;
        diff_weight[i] = 0;
    }
}

ll root(ll x) {
    if (parent[x] < 0) {
        return x;
    }

    // 累積和的に重みを再計算
    ll r = root(parent[x]);
    diff_weight[x] += diff_weight[parent[x]];
    parent[x] = r;

    return parent[x];
}

ll weight(ll x) {
    root(x);
    return diff_weight[x];
}

ll diff(ll x, ll y) {
    return weight(y) - weight(x);
}

bool isSameGroup(ll x, ll y) {
    return root(x) == root(y);
}

    /**
     * x->yの重みをwとして併合.
     * 即ち, weight(y) = weight(x) + w が成り立つ
     * x, yが既に同じグループのときは何もしない
     */
void unite(ll x, ll y, ll w) {
    if (isSameGroup(x, y)) {
        return;
    }

    w += weight(x);
    w -= weight(y);
    x = root(x);
    y = root(y);

    parent[y] = x;
    diff_weight[y] = w;
}

ll groubSize(ll x) {
    return -parent[root(x)];
}

ll n;
ll u, v, w;

int main()
{
    scanf("%lld", &n);
    init(n);

    for (int i = 0; i < n - 1; i++) {
        scanf("%lld %lld %lld", &u, &v, &w);

        unite(u, v, w);
    }

    printf("0\n");
    for (int i = 2; i <= n; i++) {
        if (diff(1, i) & 1) {
            printf("1\n");
        }
        else {
            printf("0\n");
        }
    }

    return 0;
}


#include <stdio.h>
#include <stdbool.h>

int parent[100005];
int diff_weight[100005];

void init(int nmemb) {

    for (int i = 0; i < nmemb; i++) {
        parent[i] = -1;
        diff_weight[i] = 0;
    }
}

int root(int x) {
    if (parent[x] < 0) {
        return x;
    }

    // 累積和的に重みを再計算
    int r = root(parent[x]);
    diff_weight[x] += diff_weight[parent[x]];
    parent[x] = r;

    return parent[x];
}

int weight(int x) {
    root(x);
    return diff_weight[x];
}

int diff(int x, int y) {
    return weight(y) - weight(x);
}

bool isSameGroup(int x, int y) {
    return root(x) == root(y);
}

void unite(int x, int y, int w) {
    if (isSameGroup(x, y)) {
        return;
    }

    w += weight(x);
    w -= weight(y);
    x = root(x);
    y = root(y);

    parent[y] = x;
    diff_weight[y] = w;
}

int groubSize(int x) {
    return -parent[root(x)];
}

int main()
{
    init(100005);

    int n;
    int u, v, w;

    scanf("%d", &n);
    for (int i = 0; i < n - 1; i++) {
        scanf("%d %d %d", &u, &v, &w);

        unite(u, v, w);
    }

    printf("1\n");
    for (int i = 2; i <= n; i++) {
        if (diff(1, i) % 2 == 0) {
            printf("1\n");
        }
        else {
            printf("0\n");
        }
    }

    return 0;
}


#include<stdio.h>

int main() {
   int N, K;
   scanf("%d %d", &N, &K);
   double p = 0;
   for(int i = 1; i <= N; i++){
      double r = 1.0/N;
      double j = i;
      while(K > j) {
         j = j * 2;
         r = r / 2;
      }
      p += r;
   }
   printf("%lf", p);
}


#include <stdio.h>
#include <stdlib.h>

typedef struct {
  long color;
	long connected;
} S_VERTICE;

int main(void){

  long n;
  scanf("%ld", &n);
	long u[n-1],v[n-1],w[n-1];
	for (long i = 0; i < n-1; i++) {
		scanf("%ld %ld %ld", &u[i], &v[i], &w[i]);
	}
	long ***tree;
  tree = (long ***)malloc(sizeof (long**) * (n+1));
  for (long i = 0; i < n+1; i++) {
    tree[i] = (long **)malloc(sizeof (long*) * (n+1));
		for (long j = 0; j < n+1; j++) {
			tree[i][j] = (long *)malloc(sizeof (long) * 2);
			tree[i][j][0] = 0;
			tree[i][j][1] = 0;
		}
  }
	for (long i = 0; i < n-1; i++) {
		tree[u[i]][0][0]++;
		tree[u[i]][tree[u[i]][0][0]][0] = v[i];
		tree[u[i]][tree[u[i]][0][0]][1] = w[i]%2;
		tree[v[i]][0][0]++;
		tree[v[i]][tree[v[i]][0][0]][0] = u[i];
		tree[v[i]][tree[v[i]][0][0]][1] = w[i]%2;
	}
	S_VERTICE vertices[n+1];
  for (long i = 1; i <= n; i++) {
    vertices[i].color = 0;
    vertices[i].connected = 0;
  }
	vertices[1].color = -1;
	long cur = 1;
	while (cur != 0) {
		tree[0][cur][0]++;
		if (tree[0][cur][0] <= tree[cur][0][0]) {
			if (tree[cur][tree[0][cur][0]][0] == vertices[cur].connected) {
				continue;
			}
			if (tree[cur][tree[0][cur][0]][1] == 0) {
				vertices[tree[cur][tree[0][cur][0]][0]].color = vertices[cur].color;
			} else {
				vertices[tree[cur][tree[0][cur][0]][0]].color = vertices[cur].color*(-1);
			}
			vertices[tree[cur][tree[0][cur][0]][0]].connected = cur;
			cur = tree[cur][tree[0][cur][0]][0];
		} else {
			cur = vertices[cur].connected;
		}
	}
	for (long i = 1; i <= n; i++) {
		if (vertices[i].color == -1) {
			printf("0\n");
		} else {
			printf("1\n");
		}
	}

  return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
#define INF 1e16
#define rep(i, n) for(int i = 0; i < (int)(n); ++i)
#define REP(i, n) for(int i = 1; i < (int)(n); ++i)
using namespace std;
typedef pair<long long, int> P;

int main() {
    int N;
    cin >> N;
    vector<vector<pair<int, long long>>> Graph(N);
    rep(i, N - 1) {
        int u, v;
        long long w;
        cin >> u >> v >> w;
        Graph[u - 1].push_back(make_pair(v - 1, w));
        Graph[v - 1].push_back(make_pair(u - 1, w));
    }

    vector<long long> dist(N, INF);
    vector<bool> used(N, false);
    priority_queue<P, vector<P>, greater<P>> pq;
    dist[0] = 0;
    pq.push(make_pair(0LL, 0));
    while (pq.size() > 0) {
        int ver = pq.top().second;
        long long cost = pq.top().first;
        pq.pop();
        if (used[ver]) continue;
        for (auto x : Graph[ver]) {
            int v = x.first;
            long long alt = cost + x.second;
            if (alt < dist[v]) {
                dist[v] = alt;
                pq.push(make_pair(alt, v));
            }
        }
        used[ver] = true;
    }

    rep(i, N) cout << dist[i] % 2 << endl;
    return 0;
}


var GET=(function(){function f(s){return new g(s);}function g(s){this._s=s.trim().split("\n");this._y=0;}g.prototype.a=function(f){var s=this._s, y=this._y, r;if(typeof s[y]==="string")s[y]=s[y].split(" ").reverse();r=s[y].pop();if(!s[y].length)this._y++;return f?r:+r;};g.prototype.l=function(f){var s=this._s[this._y++].split(" ");return f?s:s.map(a=>+a);};g.prototype.m=function(n,f){var r=this._s.slice(this._y,this._y+=n).map(a=>a.split(" "));return f?r:r.map(a=>a.map(a=>+a));};g.prototype.r=function(n,f){var r=this._s.slice(this._y,this._y+=n);return f?r:r.map(a=>+a);};return f;})();
var o=GET(require("fs").readFileSync("/dev/stdin","utf8"));
function xArray(v){var a=arguments,l=a.length,r="Array(a["+--l+"]).fill(0).map(x=>{return "+v+";})";while(--l)r="Array(a["+l+"]).fill(0).map(x=>"+r+")";return eval(r);}
function unionFind(n){this.a=Array(n+1).fill(-1);this.w=Array(n+1).fill(0);}
unionFind.prototype={
  root:function(i){if(this.a[i]<0)return i;var r=this.root(this.a[i]);this.w[i]+=this.w[this.a[i]];return this.a[i]=r;},
  same:function(x,y){return this.root(x)===this.root(y);},
  unite:function(x,y,w){w+=this.weight(x);w-=this.weight(y);x=this.root(x);y=this.root(y);if(x===y)return false;if(this.a[y]<this.a[x]){this.a[y]+=this.a[x];this.a[x]=y;return this.w[x]=-w;}this.a[x]+=this.a[y];this.a[y]=x;return this.w[y]=w;},
  size:function(i){return -this.a[this.root(i)];},
  weight:function(i){this.root(i);return this.w[i];},
  diff:function(x,y){return this.weight(x)-this.weight(y);},
}

console.log(main());
function main(){
  var n = o.a();
  var uf = new unionFind(n);
  for(var i = 1; i < n; i++){
    var t = o.l();
    var v1 = t[0]-1;
    var v2 = t[1]-1;
    var w = t[2];
    uf.unite(v1,v2,w&1);
  }

  var ans = [0];
  for(var i = 1; i < n; i++){
    ans[i] = 0;
    if(uf.diff(0,i) & 1)ans[i] = 1;
  }
  return ans.join("\n");
}


module.exports=function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=1)}([function(e,t,r){"use strict";e.exports=class{constructor(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.size=e.length,this.items=e,this.ind=0}enq(e){this.size+=1,this.items.push(e)}deq(){var e=this.items[this.ind];return this.size-=1,this.ind+=1,e}clear(){this.items=[],this.size=0,this.ind=0}}},function(e,t,r){"use strict";var n=r(2);r(3)(n.readFileSync("/dev/stdin","utf8"))},function(e,t){e.exports=require("fs")},function(e,t,r){"use strict";var n=r(4),i=r(5);e.exports=function(e){var t=new n(e);i(t)}},function(e,t,r){"use strict";var n=r(0);e.exports=class{constructor(e){var t=e.trim().split(/\s+/g);this.inp=new n(t)}inr(){return this.inp.deq()}in(){return parseInt(this.inp.deq(),10)}fin(){this.inp.clear()}}},function(e,t,r){"use strict";var n=r(0);e.exports=function(e){for(var t=e.in(),r=new Array(t),i=0;i<t;i++)r[i]=[];for(var o=0;o<t-1;o++){var s=e.in()-1,u=e.in()-1,c=e.in();r[s].push({v:u,c:c}),r[u].push({v:s,c:c})}var a=new Array(t).fill(-1);a[0]=0;var f=new n;for(f.enq(0);f.size>0;)for(var l=f.deq(),p=r[l].length,v=0;v<p;v++){var d=r[l][v];-1==a[d.v]&&(a[d.v]=a[l]+d.c,f.enq(d.v))}for(var h=new Array(t),y=0;y<t;y++)h[y]=a[y]%2?0:1;console.log(h.join("\n"))}}]);


console.log(function(args){
  const [[N],...tmp] = args.trim().split('\n').map( r=>r.split(' ').map(v=>v|0) );
  const tree = Array.from({length:N},_=>[]);
  for ( let i = 0; i < N-1; i++ ) {
    const [u,v,w] = tmp[i];
    tree[u-1].push([v-1,w&1]);
    tree[v-1].push([u-1,w&1]);
  }
  const color = Array.from({length:N},_=>NaN);
  color[0] = 0;
  const stack = [0];
  while ( stack.length ) {
    const u = stack.pop();
    for ( const [v,w] of tree[u] ) {
      if ( isFinite(color[v]) ) continue;
      stack.push(v);
      if ( w ) color[v] = ~color[u]&1;
      else color[v] = color[u];
    }
  }
  return color.join('\n');
}(require('fs').readFileSync('/dev/stdin', 'utf8')));


//↓見なくていいよ！ここから--------------------------------------------------
var read = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
var obj;
var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
  obj = init(inLine);
  console.error("\n");
  var start = Date.now();
  Main();
  var end = Date.now() - start;
  myerr("time : " + (end) + "ms");
  myerr("memory : " + Math.round(process.memoryUsage().heapTotal / 1024) + "KB");
});
function makeClone(obj){return JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
  var returnObj = {
    list : input, index : 0, max : input.length,
    hasNext : function(){return (this.index < this.max);},
    next : function(){if(!this.hasNext()){throw "ArrayIndexOutOfBoundsException これ以上ないよ";}else{var returnInput = this.list[this.index];this.index++;return returnInput;}}
  };
  return returnObj;
}
function myout(s){console.log(s);}
function myerr(s){console.error("debug:" + require("util").inspect(s,false,null));}
//[no]要素の扱い。数値型
//不明値、異常時:引数そのまま返す 1:数値へ変換
//2:半角SPで分割 4:半角SPで分割し、数値配列へ
//6:1文字で分割  7:1文字で分割し、数値配列へ
//8:半角SPで結合 9:改行で結合 0:文字なしで結合
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 4:return i.split(" ").map(Number);case 6:return i.split("");case 7:return i.split("").map(Number);case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}catch(e){return i;}}

//↑見なくていいよ！ここまで--------------------------------------------------
function Main(){
	var N = nextInt();
	var list = new Array(N);
	for(var i = 0; i < N; i++){
		list[i] = {
			child : {},
			color : -1,
			access : false
		};
	}
	for(var i = 0; i < N - 1; i++){
		var tmp = nextIntArray();
		list[tmp[0] - 1].child[tmp[1] - 1] = tmp[2];
		list[tmp[1] - 1].child[tmp[0] - 1] = tmp[2];
	}

	var queue = [0];
	list[0].access = true;
	list[0].color = 0;
	while(queue.length > 0){
		var tmp = queue.shift();
		var child = list[tmp].child;
		var keys = Object.keys(child);
		for(var i = 0; i< keys.length; i++){
			if(!list[keys[i]].access){
				if(child[keys[i]] % 2 == 1){
					list[keys[i]].color = (list[tmp].color == 1) ? 0 : 1;
				}else{
					list[keys[i]].color = list[tmp].color;
				}
				list[keys[i]].access = true;
				queue.push(keys[i]);
			}
		}
	}
	var output = new Array(N);
	for(var i = 0; i < N; i++){
		output[i] = list[i].color;
	}
	myout(myconv(output,9));
}


Main(myin());
function myin(){return require("fs").readFileSync("/dev/stdin", "utf8").trim();}
function myout(t){console.log(t);}//standard output
function myerr(t){console.error(t);}//standard error
//[no]param
//不明値:何もしない  1:数値へ変換  2:半角SPで分割  3:改行で分割  4:半角SPで分割し、数値配列へ
//5:改行で分割し、数値配列へ  6:1文字に分割  7:1文字に分割し、数値配列へ
//8:半角SPで結合　9:改行で結合　0:文字なしで結合
function myconv(i,no){switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 3:return i.split("\n");case 4:return i.split(" ").map((a)=>Number(a));case 5:return i.split("\n").map((a)=>Number(a));case 6:return i.split("");case 7:return i.split("").map((a)=>Number(a));case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}
function Main(input) {
  input = myconv(input,3);
  var N = myconv(input[0],1);
  input.shift();
  var list = new Array(N);
  for(var i = 0; i < N; i++){
    list[i] = temple();
  }
  for(var i = 0; i < N-1; i++){
    var tmp = myconv(input[i],4);
    list[tmp[0]-1]["children"][tmp[1]-1] = tmp[2] % 2;
    list[tmp[1]-1]["children"][tmp[0]-1] = tmp[2] % 2;
  }
  try{
  	dfs(0,null,0);
  }catch(e){
    myout(e);
    return;
  }
  function dfs(ima,oya,kyori){
    if(oya != null){
      if(kyori % 2 == 0){
        list[ima]["color"] = list[oya]["color"];
      }else{
        if(list[oya]["color"] == 1){
           list[ima]["color"] = 0;
        }else{
           list[ima]["color"] = 1;
        }
      }
    }
    var children = Array.from(Object.keys(list[ima]["children"]));
    for(var i = 0; i < children.length; i++){
      if(children[i] != oya){
        var tmpKyori = list[ima]["children"][children[i]];
        dfs(children[i],ima,tmpKyori);
      }
    }
  }
  var output = new Array(N);
  for(var i = 0; i < N; i++){
    output[i] = list[i]["color"];
  }
  myout(output.join("\n"));
}

function temple(){
  var obj = {};
  obj["children"] = {};
  obj["color"] = 0;
  return obj;
}


Main(myin());
function myin(){return require("fs").readFileSync("/dev/stdin", "utf8").trim();}
function myout(t){console.log(t);}//standard output
function myerr(t){console.error(t);}//standard error
//[no]param
//不明値:何もしない  1:数値へ変換  2:半角SPで分割  3:改行で分割  4:半角SPで分割し、数値配列へ
//5:改行で分割し、数値配列へ  6:1文字に分割  7:1文字に分割し、数値配列へ
//8:半角SPで結合　9:改行で結合　0:文字なしで結合
function myconv(i,no){switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 3:return i.split("\n");case 4:return i.split(" ").map((a)=>Number(a));case 5:return i.split("\n").map((a)=>Number(a));case 6:return i.split("");case 7:return i.split("").map((a)=>Number(a));case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}
function Main(input) {
  input = myconv(input,3);
  var N = myconv(input[0],1);
  input.shift();
  var list = new Array(N);
  for(var i = 0; i < N; i++){
    list[i] = temple();
  }
  for(var i = 0; i < N-1; i++){
    var tmp = myconv(input[i],4);
    list[tmp[0]-1]["children"][tmp[1]-1] = tmp[2] % 2;
    list[tmp[1]-1]["children"][tmp[0]-1] = tmp[2] % 2;
  }
  try{
  	dfs(0,null,0);
  }catch(e){
    myout(e);
    return;
  }
  function dfs(ima,oya,kyori){
    if(oya != null){
      if(kyori % 2 == 0){
        list[ima]["color"] = list[oya]["color"];
      }else{
        if(list[oya]["color"] == 1){
           list[ima]["color"] = 0;
        }else{
           list[ima]["color"] = 1;
        }
      }
    }
    var children = Array.from(Object.keys(list[ima]["children"]));
    for(var i = 0; i < children.length; i++){
      if(children[i] != oya){
        var tmpKyori = list[ima]["children"][children[i]];
        dfs(children[i],ima,tmpKyori);
      }
    }
  }
  var output = new Array(N);
  for(var i = 0; i < N; i++){
    output[i] = list[i]["color"];
  }
  myout(list);
}

function temple(){
  var obj = {};
  obj["children"] = {};
  obj["color"] = 0;
  return obj;
}


package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
)

// -----------------------------------------------------------------------------

// IO helper functions

// Returns next token from input.  It must be initialized by SetInput()
// before the first call.
var nextToken func() ([]byte, error)
var nextLine func() ([]byte, error)

// Holds a buffer for output.  It must be initialized by SetOutput().
// All IO fucntions (read*() and [e]print*()) should write to OutputWriter
// instead of this.
var OutputBuffer *bufio.Writer

// Holds an io.Writer.  It must be initialized by SetOutput()
var OutputWriter io.Writer

// Set IO functions for interactive input/output.
func SetInteractive(w io.Writer, r io.Reader) {
	SetUnbefferedInput(r)
	OutputBuffer = nil
	OutputWriter = w
}

// Setup OutputBuffer and OutputWriter.
func SetOutput(w io.Writer) {
	OutputBuffer = bufio.NewWriter(w)
	OutputWriter = OutputBuffer
}

// Flushes OutputBuffer
func Flush() {
	if OutputBuffer != nil {
		OutputBuffer.Flush()
	}
}

// Returns true if c is a white space
func IsSpace(c byte) bool {
	switch c {
	case '\t', '\n', '\v', '\f', '\r', ' ':
		return true
	}
	return false
}

func IsNewLine(c byte) bool {
	switch c {
	case '\n', '\r':
		return true
	}
	return false
}

// Setup nextToken with input buffer.
func SetInput(r io.Reader) {
	buf := new(bytes.Buffer)
	var b []byte

	var i int
	rest := func() ([]byte, error) {
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		return b[j:i], nil
	}
	initial := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextToken = rest
		return rest()
	}
	nextToken = initial

	restLn := func() ([]byte, error) {
		for i < len(b) && IsNewLine(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsNewLine(b[i]) {
			i++
		}
		return b[j:i], nil
	}

	initialLn := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextLine = restLn
		return restLn()
	}
	nextLine = initialLn
}

// Setup nextToken without input buffer.
func SetUnbefferedInput(r io.Reader) {
	buf := bufio.NewReader(r)
	var b []byte

	var i int
	nextToken = func() ([]byte, error) {
		var err error
		if i == len(b) {
			b, err = buf.ReadBytes('\n')
			if err != nil {
				return nil, err
			}
			i = 0
			j := len(b) - 1
			for 0 <= j && IsSpace(b[j]) {
				j--
			}
			b = b[0 : j+1]
		}
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		if i == j {
			return nil, io.ErrUnexpectedEOF
		}
		return b[j:i], nil
	}
}

// -----------------------------------------------------------------------------

// IO functions

// Reads next token and return it as []byte
func readb() []byte {
	b, err := nextToken()
	if err != nil {
		panic(err)
	}
	return b
}

// Reads next token and return it as string
func reads() string {
	return string(readb())
}

// Read next line as []byte
func readbln() []byte {
	b, err := nextLine()
	if err != nil {
		panic(err)
	}
	return b
}

// Read next line as string
func readsln() string {
	return string(readbln())
}

// Reads next token and return it as int64
func readll() int64 {
	i, err := strconv.ParseInt(reads(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// Reads next token and return it as int
func readi() int {
	return int(readll())
}

// Reads next token and return it as float64
func readf() float64 {
	f, err := strconv.ParseFloat(reads(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// Write args to OutputWriter with the format f
func printf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(OutputWriter, f, args...)
}

// Write args to OutputWriter without format
func println(args ...interface{}) (int, error) {
	return fmt.Fprintln(OutputWriter, args...)
}

// Write args to stderr with the format f
func eprintf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(os.Stderr, f, args...)
}

// Write args to stderr without format
func eprintln(args ...interface{}) (int, error) {
	return fmt.Fprintln(os.Stderr, args...)
}

// -----------------------------------------------------------------------------

// Simple math functions

const (
	// big prime
	INF  = 1000000007
	INF2 = 1000000009
	INF3 = 998244353
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func minll(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func maxll(a, b int64) int64 {
	if a < b {
		return b
	}
	return a
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func absll(a int64) int64 {
	if a < 0 {
		return -a
	}
	return a
}

// egcd(a, b) returns d, x, y:
//   d is gcd(a,b)
//   x, y are  integers that satisfy ax + by = d
func egcd(a, b int) (int, int, int) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcd(b, a%b)
	return d, y, x - a/b*y
}

func egcdll(a, b int64) (int64, int64, int64) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcdll(b, a%b)
	return d, y, x - a/b*y
}

func gcd(a, b int) int {
	d, _, _ := egcd(a, b)
	return d
}

func gcdll(a, b int64) int64 {
	d, _, _ := egcdll(a, b)
	return d
}

// set up IO functions
func init() {
	// for non-interactive
	SetInput(os.Stdin)
	SetOutput(os.Stdout)

	// Enable below when interactive.  Its ok to leave above intact.
	// SetInteractive(os.Stdout, os.Stdin)
}

func main() {
	defer Flush()

	N := readi()
	G := make([][]Edge, N)
	for i := 0; i < N-1; i++ {
		u := readi() - 1
		v := readi() - 1
		w := readi()
		G[u] = append(G[u], Edge{v, w})
		G[v] = append(G[v], Edge{u, w})
	}

	C := make([]int, N)
	dfs(G, C, 0, 0)
	for _, v := range C {
		println(v % 2)
	}
}

func dfs(G [][]Edge, C []int, d, u int) {
	C[u] = d%2 + 1
	for _, e := range G[u] {
		v := e.to
		w := e.cost
		if 0 < C[v] {
			continue
		}
		dfs(G, C, d+w, v)
	}
}

type Edge struct {
	to, cost int
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type edge struct {
	v, w int
}

func solve() {
	n := getInt()
	graph := make([][]edge, n)
	for i := 0; i < n-1; i++ {
		u, v, w := getInt()-1, getInt()-1, getInt()
		graph[u] = append(graph[u], edge{v, w})
		graph[v] = append(graph[v], edge{u, w})
	}

	ans := make([]int, n)
	for i := range ans {
		ans[i] = -1
	}
	ans[0] = 0

	var dfs func(int)
	dfs = func(now int) {
		for _, next := range graph[now] {
			if ans[next.v] != -1 {
				continue
			}

			if next.w%2 == 0 {
				ans[next.v] = ans[now]
			} else {
				ans[next.v] = (ans[now] ^ 1)
			}
			dfs(next.v)
		}
	}
	dfs(0)

	for _, a := range ans {
		fmt.Fprintln(wr, a)
	}
}

// -----------------------------------------

const (
	inf = 1 << 60
	// mod = 1000000007
)

var (
	sc = bufio.NewScanner(os.Stdin)
	wr = bufio.NewWriter(os.Stdout)
)

func main() {
	maxBufSize := int(1e8)
	sc.Buffer(make([]byte, 4096), maxBufSize)
	sc.Split(bufio.ScanWords)
	solve()
	wr.Flush()
}

func getInt() (ret int) {
	sc.Scan()
	ret, err := strconv.Atoi(sc.Text())
	if err != nil {
		panic(err)
	}
	return
}

func getIntSlice(n int) (ret []int) {
	ret = make([]int, n)
	for i := range ret {
		ret[i] = getInt()
	}
	return
}

func getString() (ret string) {
	sc.Scan()
	ret = sc.Text()
	return
}

func getRunes() (ret []rune) {
	ret = []rune(getString())
	return
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func out(x ...interface{}) {
	fmt.Println(x...)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

// min, max, asub, absなど基本関数
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func asub(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

func lowerBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] >= x
	})
	return idx
}

func upperBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] > x
	})
	return idx
}

type edge struct {
	to, cost int
}

var node [][]edge

var res []int

func dfs(v, prev, cost int) {
	if prev != -1 {
		res[v] = res[prev] + cost
	}
	for _, e := range node[v] {
		if e.to == prev {
			continue
		}
		dfs(e.to, v, e.cost)
	}
}

func main() {
	sc.Split(bufio.ScanWords)

	N := getInt()
	node = make([][]edge, N)
	for i := 0; i < N-1; i++ {
		u, v, w := getInt()-1, getInt()-1, getInt()
		node[u] = append(node[u], edge{v, w})
		node[v] = append(node[v], edge{u, w})
	}

	res = make([]int, N)
	dfs(0, -1, 0)
	// out(res)
	w := bufio.NewWriter(os.Stdout)
	defer w.Flush()
	for i := 0; i < N; i++ {
		fmt.Fprintln(w, res[i]%2)
	}
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type Path struct {
	To  int
	Len int
}

var (
	paths   map[int][]Path
	sc      = bufio.NewScanner(os.Stdin)
	ans     []int
	visited []bool
)

func init() {
	sc.Split(bufio.ScanWords)
	paths = map[int][]Path{}
	ans = make([]int, 101010)
	visited = make([]bool, 101010)
}

func input() int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return i
}

func dfs(node int, before int) {
	visited[node] = true

	for i := 0; i < len(paths[node]); i++ {
		nxtPath := paths[node][i]
		if visited[nxtPath.To] {
			continue
		}

		var nxtCol int
		if nxtPath.Len == 0 {
			nxtCol = before
		} else {
			nxtCol = (before + 1) % 2
		}

		ans[nxtPath.To] = nxtCol
		dfs(nxtPath.To, nxtCol)
	}
}

func main() {
	var n int
	fmt.Scan(&n)

	for i := 0; i < n-1; i++ {
		var f, t, l int
		f = input() - 1
		t = input() - 1
		l = input()

		paths[f] = append(paths[f], Path{
			To:  t,
			Len: l % 2,
		})

		paths[t] = append(paths[t], Path{
			To:  f,
			Len: l % 2,
		})
	}

	//start dfs
	visited[0] = true
	dfs(paths[0][0].To, 0)

	for _, v := range ans[:n] {
		fmt.Println(v)
	}
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type Path struct {
	To  int
	Len int
}

var (
	paths   map[int][]Path
	sc      = bufio.NewScanner(os.Stdin)
	ans     []int
	visited []bool
)

func init() {
	sc.Split(bufio.ScanWords)
	paths = map[int][]Path{}
	ans = make([]int, 101010)
	visited = make([]bool, 101010)
}

func input() int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return i
}

func dfs(node int, before int) {
	visited[node] = true

	for i := 0; i < len(paths[node]); i++ {
		nxtPath := paths[node][i]
		if visited[nxtPath.To] {
			continue
		}

		var nxtCol int
		if nxtPath.Len == before {
			nxtCol = before
		} else {
			nxtCol = (before + 1) % 2
		}

		ans[nxtPath.To] = nxtCol
		dfs(nxtPath.To, nxtCol)
	}
}

func main() {
	var n int
	fmt.Scan(&n)

	for i := 0; i < n-1; i++ {
		var f, t, l int
		f = input() - 1
		t = input() - 1
		l = input()

		paths[f] = append(paths[f], Path{
			To:  t,
			Len: l % 2,
		})

		paths[t] = append(paths[t], Path{
			To:  f,
			Len: l % 2,
		})
	}

	//start dfs
	visited[0] = true
	dfs(0, 0)

	for _, v := range ans[:n] {
		fmt.Println(v)
	}
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type Path struct {
	To  int
	Len int
}

var (
	paths   map[int][]Path
	sc      = bufio.NewScanner(os.Stdin)
	ans     []int
	visited []bool
)

func init() {
	sc.Split(bufio.ScanWords)
	paths = map[int][]Path{}
	ans = make([]int, 101010)
	visited = make([]bool, 101010)
}

func input() int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return i
}

func dfs(node int, before int) {
	if visited[node] {
		return
	}

	visited[node] = true

	for i := 0; i < len(paths[node]); i++ {
		nxtPath := paths[node][i]
		if visited[nxtPath.To] {
			continue
		}
		var nxtCol int
		if nxtPath.Len == before {
			nxtCol = before
		} else {
			nxtCol = (before + 1) % 2
		}

		ans[nxtPath.To] = nxtCol
		dfs(nxtPath.To, nxtCol)
	}
}

func main() {
	var n int
	fmt.Scan(&n)

	for i := 0; i < n-1; i++ {
		var f, t, l int
		f = input() - 1
		t = input() - 1
		l = input()

		paths[f] = append(paths[f], Path{
			To:  t,
			Len: l % 2,
		})

		paths[t] = append(paths[t], Path{
			To:  f,
			Len: l % 2,
		})
	}

	//start dfs
	visited[0] = true
	dfs(paths[0][0].To, 0)

	for _, v := range ans[:n] {
		fmt.Println(v)
	}
}


N,*uvws=$<.read.split.map(&:to_i)

h = {}
uvws.each_slice(3) do |u,v,w|
    h[u] ||= []
    h[u] << [u,v,w%2]
    h[v] ||= []
    h[v] << [v,u,w%2]
end

arr = Array.new(N+1,-1)
arr[1] = 0

q = h[1]
until q.empty?
    u,v,w = q.shift
    next if arr[v] != -1
    if w == 0
        arr[v] = arr[u]
    else
        arr[v] = 1-arr[u]
    end
    q.push(*h[v])
    # h[v].each do |x|
    #     q << x
    # end
end

puts arr[1..-1]


N,*uvws=$<.read.split.map(&:to_i)

h = {}
uvws.each_slice(3) do |u,v,w|
    h[u] ||= []
    h[u] << [u,v,w%2]
    h[v] ||= []
    h[v] << [v,u,w%2]
end

arr = Array.new(N+1,-1)
arr[1] = 0

q = h[1]
until q.empty?
    u,v,w = q.shift
    next if arr[v] != -1
    if w == 0
        arr[v] = arr[u]
    else
        arr[v] = 1-arr[u]
    end
    h[v].each do |x|
        q << x
    end
end

puts arr[1..-1]


N,*uvws=$<.read.split.map(&:to_i)

h = {}
uvws.each_slice(3) do |u,v,w|
    h[u] ||= []
    h[u] << [u,v,w%2]
    h[v] ||= []
    h[v] << [v,u,w%2]
end

arr = Array.new(N+1,-1)
arr[1] = 0

q = h[1]
until q.empty?
    u,v,w = q.shift
    next if arr[v] != -1
    if w == 0
        arr[v] = arr[u]
    else
        arr[v] = 1-arr[u]
    end
    # q.push(*h[v]) # Array#+= だとTLEになるので.pushを使う
    q.concat(h[v])
end

puts arr[1..-1]


n = gets.to_i
dp = Array.new(n + 1) { Array.new(n + 1, 0) }
g = Hash.new
res = Array.new(n)
(n - 1).times do
  u, v, w = gets.chomp.split.map(&:to_i)
  dp[u][v] = dp[v][u] = w % 2
  g[u] ||= []
  g[u] << v
  g[v] ||= []
  g[v] << u
end

q = [1]
res[0] = 0
while !q.empty?
  u = q.pop
  g[u].each do |v|
    next if !res[v - 1].nil?
    res[v - 1] = (res[u - 1] + dp[u][v]) % 2
    q << v
  end
end
puts res


N,*uvws=$<.read.split.map(&:to_i)

h = {}
uvws.each_slice(3) do |u,v,w|
    h[u] ||= []
    h[u] << [u,v,w%2]
    h[v] ||= []
    h[v] << [v,u,w%2]
end

arr = Array.new(N+1,-1)
arr[1] = 0

q = h[1]
until q.empty?
    u,v,w = q.shift
    next if arr[v] != -1
    if w == 0
        arr[v] = arr[u]
    else
        arr[v] = 1-arr[u]
    end
    q = q + h[v]
    # h[v].each do |x|
    #     q << x
    # end
end

puts arr[1..-1]


N,*uvws=$<.read.split.map(&:to_i)

h = {}
uvws.each_slice(3) do |u,v,w|
    h[u] ||= []
    h[u] << [u,v,w%2]
    h[v] ||= []
    h[v] << [v,u,w%2]
end

arr = Array.new(N+1,-1)
arr[1] = 0

# p h

q = h[1]
until q.empty?
    u,v,w = q.shift
    next if arr[v] != -1
    if w == 0
        arr[v] = arr[u]
    else
        arr[v] = 1-arr[u]
    end
    q += h[v] if arr[v] != -1
end

puts arr[1..-1]


use std::io::*;
use utils::*;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = CpReader::new(i);
    let n = i.read::<usize>();

    let mut edges = VecVec32::new(n, (n - 1) * 2);
    for _ in 0..n - 1 {
        let (u, v, w) = i.read::<(usize, usize, usize)>();
        let (u, v, w) = (u - 1, v - 1, (w % 2) as u8);
        edges.push(u, (v as u32, w));
        edges.push(v, (u as u32, w));
    }
    let mut ds = vec![0; n];
    let mut q = vec![(0u32, 0u32)];
    while let Some((i0, i1)) = q.pop() {
        let d = ds[i1 as usize];
        for &(i2, w) in edges.get(i1 as usize) {
            if i2 != i0 {
                ds[i2 as usize] = d ^ w;
                q.push((i1, i2));
            }
        }
    }
    for d in ds {
        writeln!(o, "{}", d).unwrap();
    }
}

mod utils {
    use super::*;

    pub struct CpReader<R: BufRead> {
        r: R,
        b: Vec<u8>,
    }
    impl<R: BufRead> CpReader<R> {
        pub fn new(r: R) -> Self {
            CpReader {
                r: r,
                b: Vec::new(),
            }
        }
        pub fn read_word(&mut self) -> &[u8] {
            self.b.clear();
            let mut consume = 0;
            loop {
                self.r.consume(consume);
                let b = self.r.fill_buf().unwrap();
                assert!(b.len() != 0);
                if let Some(p) = b.iter().position(|&x| x == b' ' || x == b'\n') {
                    self.b.extend_from_slice(&b[..p]);
                    consume = p + 1;
                    break;
                }
                self.b.extend_from_slice(b);
                consume = b.len();
            }
            self.r.consume(consume);
            &self.b
        }
        pub fn read_word_str(&mut self) -> &str {
            unsafe { std::str::from_utf8_unchecked(self.read_word()) }
        }

        pub fn read<T: CpRead>(&mut self) -> T {
            T::cp_read(self)
        }
    }
    pub trait CpRead {
        fn cp_read<R: BufRead>(r: &mut CpReader<R>) -> Self;
    }

    impl CpRead for u64 {
        fn cp_read<R: BufRead>(r: &mut CpReader<R>) -> Self {
            read_u64_fast(&mut r.r)
        }
    }
    impl CpRead for i64 {
        fn cp_read<R: BufRead>(r: &mut CpReader<R>) -> Self {
            read_i64_fast(&mut r.r)
        }
    }

    macro_rules! cp_read_tuple {
        ($($t:ident),*) => {
            impl<$($t: CpRead),*> CpRead for ($($t),*) {
                fn cp_read<R: BufRead>(r: &mut CpReader<R>) -> Self {
                    ($($t::cp_read(r)),*)
                }
            }
        };
    }

    macro_rules! cp_read_cast {
        ($t_self:ty, $t_read:ty) => {
            impl CpRead for $t_self {
                fn cp_read<R: BufRead>(r: &mut CpReader<R>) -> Self {
                    <$t_read>::cp_read(r) as $t_self
                }
            }
        };
    }
    macro_rules! cp_read_parse {
        ($t:ty) => {
            impl CpRead for $t {
                fn cp_read<R: BufRead>(r: &mut CpReader<R>) -> Self {
                    r.read_word_str().parse().unwrap()
                }
            }
        };
    }

    cp_read_cast!(usize, u64);
    cp_read_cast!(u32, u64);
    cp_read_cast!(u16, u64);
    cp_read_cast!(i32, i64);
    cp_read_cast!(i16, i64);
    cp_read_cast!(i8, i64);

    cp_read_parse!(f64);

    cp_read_tuple!(T1, T2);
    cp_read_tuple!(T1, T2, T3);
    cp_read_tuple!(T1, T2, T3, T4);
    cp_read_tuple!(T1, T2, T3, T4, T5);

    fn read_u64_fast<R: BufRead>(r: &mut R) -> u64 {
        let mut value = 0;
        loop {
            let mut idx = 0;
            let buf_len;
            {
                let buf = r.fill_buf().unwrap();
                buf_len = buf.len();
                assert!(buf_len != 0);
                while idx < buf_len && b'0' <= buf[idx] && buf[idx] <= b'9' {
                    value = value * 10 + (buf[idx] - b'0') as u64;
                    idx += 1;
                }
            }
            if idx < buf_len {
                r.consume(idx + 1);
                return value;
            }
            r.consume(idx);
        }
    }
    fn read_i64_fast<R: BufRead>(r: &mut R) -> i64 {
        let (consume, sign) = match r.fill_buf().unwrap()[0] {
            b'+' => (true, 1),
            b'-' => (true, -1),
            _ => (false, 1),
        };
        if consume {
            r.consume(1);
        }
        read_u64_fast(r) as i64 * sign
    }

    pub struct VecVec32<T> {
        hs: Vec<u32>,
        vs: Vec<(T, u32)>,
    }
    #[allow(dead_code)]
    impl<T> VecVec32<T> {
        #[inline]
        pub fn new(len: usize, capacity: usize) -> Self {
            assert!(capacity < u32::max_value() as usize);
            VecVec32 {
                hs: vec![0; len],
                vs: Vec::with_capacity(capacity),
            }
        }

        #[inline]
        pub fn push(&mut self, idx: usize, value: T) {
            self.vs.push((value, self.hs[idx]));
            self.hs[idx] = self.vs.len() as u32;
        }

        #[inline]
        pub fn len(&self) -> usize {
            self.hs.len()
        }

        #[inline]
        pub fn get(&self, idx: usize) -> VecVec32Iter<T> {
            VecVec32Iter {
                s: self,
                i: self.hs[idx],
            }
        }
    }
    pub struct VecVec32Iter<'a, T: 'a> {
        s: &'a VecVec32<T>,
        i: u32,
    }
    impl<'a, T: 'a> Iterator for VecVec32Iter<'a, T> {
        type Item = &'a T;

        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            if self.i == 0 {
                None
            } else {
                let i = self.i as usize - 1;
                self.i = self.s.vs[i].1;
                Some(&self.s.vs[i].0)
            }
        }
    }

}


use std::io::*;
use std::str::FromStr;
use utils::*;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = CpReader::new(i);
    let n = i.read::<usize>();

    let mut edges = VecVec32::new(n, (n - 1) * 2);
    for _ in 0..n - 1 {
        let (u, v, w) = i.read3::<usize, usize, usize>();
        let (u, v, w) = (u - 1, v - 1, (w % 2) as u8);
        edges.push(u, (v as u32, w));
        edges.push(v, (u as u32, w));
    }
    let mut ds = vec![0; n];
    let mut q = vec![(0u32, 0u32)];
    while let Some((i0, i1)) = q.pop() {
        let d = ds[i1 as usize];
        for &(i2, w) in edges.get(i1 as usize) {
            if i2 != i0 {
                ds[i2 as usize] = d ^ w;
                q.push((i1, i2));
            }
        }
    }
    for d in ds {
        writeln!(o, "{}", d).unwrap();
    }
}

mod utils {
    use super::*;

    pub struct CpReader<R: BufRead> {
        r: R,
        s: String,
    }

    macro_rules! fn_read {
        { $f:ident($($t:ident),*) } => {
            #[allow(dead_code)]
            pub fn $f<$($t: FromStr),*>(&mut self) -> ($($t),*) {
                let i = &mut self.read_line().split(' ');
                ($(read_next::<$t,_>(i)),*)
            }
        };
    }

    impl<R: BufRead> CpReader<R> {
        pub fn new(r: R) -> Self {
            CpReader {
                r: r,
                s: String::new(),
            }
        }
        pub fn read_line(&mut self) -> &str {
            self.s.clear();
            self.r.read_line(&mut self.s).unwrap();
            self.s.trim()
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_line().parse().ok().unwrap()
        }
        fn_read! { read2(T1, T2) }
        fn_read! { read3(T1, T2, T3) }
        fn_read! { read4(T1, T2, T3, T4) }
        fn_read! { read5(T1, T2, T3, T4, T5) }
    }
    fn read_next<'a, T: FromStr, I: Iterator<Item = &'a str>>(i: &mut I) -> T {
        i.next().unwrap().parse().ok().unwrap()
    }

    pub struct VecVec32<T> {
        hs: Vec<u32>,
        vs: Vec<(T, u32)>,
    }
    #[allow(dead_code)]
    impl<T> VecVec32<T> {
        #[inline]
        pub fn new(len: usize, capacity: usize) -> Self {
            assert!(capacity < u32::max_value() as usize);
            VecVec32 {
                hs: vec![0; len],
                vs: Vec::with_capacity(capacity),
            }
        }

        #[inline]
        pub fn push(&mut self, idx: usize, value: T) {
            self.vs.push((value, self.hs[idx]));
            self.hs[idx] = self.vs.len() as u32;
        }

        #[inline]
        pub fn len(&self) -> usize {
            self.hs.len()
        }

        #[inline]
        pub fn get(&self, idx: usize) -> VecVec32Iter<T> {
            VecVec32Iter {
                s: self,
                i: self.hs[idx],
            }
        }
    }
    pub struct VecVec32Iter<'a, T: 'a> {
        s: &'a VecVec32<T>,
        i: u32,
    }
    impl<'a, T: 'a> Iterator for VecVec32Iter<'a, T> {
        type Item = &'a T;

        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            if self.i == 0 {
                None
            } else {
                let i = self.i as usize - 1;
                self.i = self.s.vs[i].1;
                Some(&self.s.vs[i].0)
            }
        }
    }

}


use std::io::*;
use std::str::FromStr;
use utils::*;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = CpReader::new(i);
    let n = i.read::<usize>();

    let mut edges = VecVec32::new(n, (n - 1) * 2);
    for _ in 0..n - 1 {
        let (u, v, w) = i.read3::<usize, usize, usize>();
        let (u, v, w) = (u - 1, v - 1, (w % 2) as u8);
        edges.push(u, (v as u32, w));
        edges.push(v, (u as u32, w));
    }
    let mut ds = vec![0; n];
    let mut q = vec![(0u32, 0u32, 0)];
    while let Some((i0, i1, d)) = q.pop() {
        ds[i1 as usize] = d;
        for &(i2, w) in edges.get(i1 as usize) {
            if i2 != i0 {
                q.push((i1, i2, d ^ w));
            }
        }
    }
    for d in ds {
        writeln!(o, "{}", d).unwrap();
    }
}

mod utils {
    use super::*;

    pub struct CpReader<R: BufRead> {
        r: R,
        s: String,
    }

    macro_rules! fn_read {
        { $f:ident($($t:ident),*) } => {
            #[allow(dead_code)]
            pub fn $f<$($t: FromStr),*>(&mut self) -> ($($t),*) {
                let i = &mut self.read_line().split(' ');
                ($(read_next::<$t,_>(i)),*)
            }
        };
    }

    impl<R: BufRead> CpReader<R> {
        pub fn new(r: R) -> Self {
            CpReader {
                r: r,
                s: String::new(),
            }
        }
        pub fn read_line(&mut self) -> &str {
            self.s.clear();
            self.r.read_line(&mut self.s).unwrap();
            self.s.trim()
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_line().parse().ok().unwrap()
        }
        fn_read! { read2(T1, T2) }
        fn_read! { read3(T1, T2, T3) }
        fn_read! { read4(T1, T2, T3, T4) }
        fn_read! { read5(T1, T2, T3, T4, T5) }
    }
    fn read_next<'a, T: FromStr, I: Iterator<Item = &'a str>>(i: &mut I) -> T {
        i.next().unwrap().parse().ok().unwrap()
    }

    pub struct VecVec32<T> {
        hs: Vec<u32>,
        vs: Vec<(T, u32)>,
    }
    #[allow(dead_code)]
    impl<T> VecVec32<T> {
        #[inline]
        pub fn new(len: usize, capacity: usize) -> Self {
            assert!(capacity < u32::max_value() as usize);
            VecVec32 {
                hs: vec![0; len],
                vs: Vec::with_capacity(capacity),
            }
        }

        #[inline]
        pub fn push(&mut self, idx: usize, value: T) {
            self.vs.push((value, self.hs[idx]));
            self.hs[idx] = self.vs.len() as u32;
        }

        #[inline]
        pub fn len(&self) -> usize {
            self.hs.len()
        }

        #[inline]
        pub fn get(&self, idx: usize) -> VecVec32Iter<T> {
            VecVec32Iter {
                s: self,
                i: self.hs[idx],
            }
        }
    }
    pub struct VecVec32Iter<'a, T: 'a> {
        s: &'a VecVec32<T>,
        i: u32,
    }
    impl<'a, T: 'a> Iterator for VecVec32Iter<'a, T> {
        type Item = &'a T;

        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            if self.i == 0 {
                None
            } else {
                let i = self.i as usize - 1;
                self.i = self.s.vs[i].1;
                Some(&self.s.vs[i].0)
            }
        }
    }

}


use proconio::{fastout, input, marker::Usize1};
use std::cmp::Ordering;
use std::collections::BinaryHeap;
#[derive(Copy, Clone, Eq, PartialEq)]
struct State {
    cost: usize,
    pos: usize,
}

impl Ord for State {
    fn cmp(&self, other: &State) -> Ordering {
        other
            .cost
            .cmp(&self.cost)
            .then_with(|| self.pos.cmp(&other.pos))
    }
}

impl PartialOrd for State {
    fn partial_cmp(&self, other: &State) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
#[derive(Copy, Clone, Eq, PartialEq)]

pub struct Edge {
    to: usize,
    cost: usize,
}

impl Edge {
    fn new(to: usize, cost: usize) -> Edge {
        Edge { to, cost }
    }
}

pub struct AdjList {
    dim: usize,
    list: Vec<Vec<Edge>>,
}

impl AdjList {
    pub fn new(d: usize) -> AdjList {
        AdjList {
            dim: d,
            list: vec![vec![]; d],
        }
    }

    pub fn dim(&self) -> usize {
        self.dim
    }

    pub fn add_edge(&mut self, from: usize, to: usize, cost: usize) {
        self.list.get_mut(from).unwrap().push(Edge::new(to, cost));
    }

    pub fn add_undirected_edge(&mut self, from: usize, to: usize, cost: usize) {
        self.list.get_mut(from).unwrap().push(Edge::new(to, cost));
        self.list.get_mut(to).unwrap().push(Edge::new(from, cost));
    }

    pub fn out_edges(&mut self, vertex: usize) -> Vec<Edge> {
        self.list.get_mut(vertex).unwrap().to_vec()
    }

    pub fn in_edges(&mut self, v: usize) -> Vec<usize> {
        let mut res = vec![];
        for l in 0..self.dim() {
            if let Some(list) = self.list.get(l) {
                if list.contains(&Edge::new(v, 0)) {
                    res.push(l);
                }
            }
        }

        res
    }

    fn shortest_paths(&self, start: usize) -> Vec<usize> {
        let mut dist: Vec<_> = (0..self.list.len()).map(|_| 1_000_000_000_000).collect();
        let mut heap = BinaryHeap::new();
        dist[start] = 0;
        heap.push(State {
            cost: 0,
            pos: start,
        });
        while let Some(State { cost, pos }) = heap.pop() {
            if cost > dist[pos] {
                continue;
            }
            for edge in &self.list[pos] {
                let next = State {
                    cost: cost + edge.cost,
                    pos: edge.to,
                };
                if next.cost < dist[next.pos] {
                    heap.push(next);
                    dist[next.pos] = next.cost;
                }
            }
        }
        dist
    }
}

#[fastout]
fn main() {
    input! {
        n:usize,
    }

    let mut g = AdjList::new(n);
    for i in 0..n - 1 {
        input! {
            u:Usize1,
            v:Usize1,
            w:usize,
        }
        g.add_undirected_edge(u, v, w);
    }

    let dist = g.shortest_paths(0);

    for i in 0..n {
        println!("{}", dist[i] % 2);
    }
}


use proconio::{fastout, input, marker::Usize1};
use std::cmp::Ordering;
use std::collections::BinaryHeap;
use std::usize::MAX;
#[derive(Copy, Clone, Eq, PartialEq)]
struct State {
    cost: usize,
    pos: usize,
}

impl Ord for State {
    fn cmp(&self, other: &State) -> Ordering {
        other
            .cost
            .cmp(&self.cost)
            .then_with(|| self.pos.cmp(&other.pos))
    }
}

impl PartialOrd for State {
    fn partial_cmp(&self, other: &State) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
#[derive(Copy, Clone, Eq, PartialEq)]

pub struct Edge {
    to: usize,
    cost: usize,
}

impl Edge {
    fn new(to: usize, cost: usize) -> Edge {
        Edge { to, cost }
    }
}

pub struct AdjList {
    dim: usize,
    list: Vec<Vec<Edge>>,
}

impl AdjList {
    pub fn new(d: usize) -> AdjList {
        AdjList {
            dim: d,
            list: vec![vec![]; d],
        }
    }

    pub fn dim(&self) -> usize {
        self.dim
    }

    pub fn add_edge(&mut self, from: usize, to: usize, cost: usize) {
        self.list.get_mut(from).unwrap().push(Edge::new(to, cost));
    }

    pub fn add_undirected_edge(&mut self, from: usize, to: usize, cost: usize) {
        self.list.get_mut(from).unwrap().push(Edge::new(to, cost));
        self.list.get_mut(to).unwrap().push(Edge::new(from, cost));
    }

    pub fn out_edges(&mut self, vertex: usize) -> Vec<Edge> {
        self.list.get_mut(vertex).unwrap().to_vec()
    }

    pub fn in_edges(&mut self, v: usize) -> Vec<usize> {
        let mut res = vec![];
        for l in 0..self.dim() {
            if let Some(list) = self.list.get(l) {
                if list.contains(&Edge::new(v, 0)) {
                    res.push(l);
                }
            }
        }

        res
    }

    fn shortest_paths(&self, start: usize) -> Vec<usize> {
        let mut dist: Vec<_> = (0..self.list.len()).map(|_| usize::MAX).collect();
        let mut heap = BinaryHeap::new();
        dist[start] = 0;
        heap.push(State {
            cost: 0,
            pos: start,
        });
        while let Some(State { cost, pos }) = heap.pop() {
            if cost > dist[pos] {
                continue;
            }
            for edge in &self.list[pos] {
                let next = State {
                    cost: cost + edge.cost,
                    pos: edge.to,
                };
                if next.cost < dist[next.pos] {
                    heap.push(next);
                    dist[next.pos] = next.cost;
                }
            }
        }
        dist
    }
}

#[fastout]
fn main() {
    input! {
        n:usize,
    }

    let mut g = AdjList::new(n);
    for i in 0..n - 1 {
        input! {
            u:Usize1,
            v:Usize1,
            w:usize,
        }
        g.add_undirected_edge(u, v, w);
    }

    let dist = g.shortest_paths(0);

    for i in 0..n {
        println!("{}", dist[i] % 2);
    }
}


use proconio::{fastout, input, marker::Usize1};
use std::cmp::Ordering;
use std::collections::BinaryHeap;
#[derive(Copy, Clone, Eq, PartialEq)]
struct State {
    cost: usize,
    pos: usize,
}

impl Ord for State {
    fn cmp(&self, other: &State) -> Ordering {
        other
            .cost
            .cmp(&self.cost)
            .then_with(|| self.pos.cmp(&other.pos))
    }
}

impl PartialOrd for State {
    fn partial_cmp(&self, other: &State) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
#[derive(Copy, Clone, Eq, PartialEq)]

pub struct Edge {
    to: usize,
    cost: usize,
}

impl Edge {
    fn new(to: usize, cost: usize) -> Edge {
        Edge { to, cost }
    }
}

pub struct AdjList {
    dim: usize,
    list: Vec<Vec<Edge>>,
}

impl AdjList {
    pub fn new(d: usize) -> AdjList {
        AdjList {
            dim: d,
            list: vec![vec![]; d],
        }
    }

    pub fn dim(&self) -> usize {
        self.dim
    }

    pub fn add_edge(&mut self, from: usize, to: usize, cost: usize) {
        self.list.get_mut(from).unwrap().push(Edge::new(to, cost));
    }

    pub fn add_undirected_edge(&mut self, from: usize, to: usize, cost: usize) {
        self.list.get_mut(from).unwrap().push(Edge::new(to, cost));
        self.list.get_mut(to).unwrap().push(Edge::new(from, cost));
    }

    pub fn out_edges(&mut self, vertex: usize) -> Vec<Edge> {
        self.list.get_mut(vertex).unwrap().to_vec()
    }

    pub fn in_edges(&mut self, v: usize) -> Vec<usize> {
        let mut res = vec![];
        for l in 0..self.dim() {
            if let Some(list) = self.list.get(l) {
                if list.contains(&Edge::new(v, 0)) {
                    res.push(l);
                }
            }
        }

        res
    }

    fn shortest_paths(&self, start: usize) -> Vec<usize> {
        let mut dist: Vec<_> = (0..self.list.len()).map(|_| usize::MAX).collect();
        let mut heap = BinaryHeap::new();
        dist[start] = 0;
        heap.push(State {
            cost: 0,
            pos: start,
        });
        while let Some(State { cost, pos }) = heap.pop() {
            if cost > dist[pos] {
                continue;
            }
            for edge in &self.list[pos] {
                let next = State {
                    cost: cost + edge.cost,
                    pos: edge.to,
                };
                if next.cost < dist[next.pos] {
                    heap.push(next);
                    dist[next.pos] = next.cost;
                }
            }
        }
        dist
    }
}

#[fastout]
fn main() {
    input! {
        n:usize,
    }

    let mut g = AdjList::new(n);
    for i in 0..n - 1 {
        input! {
            u:Usize1,
            v:Usize1,
            w:usize,
        }
        g.add_undirected_edge(u, v, w);
    }

    let dist = g.shortest_paths(0);

    for i in 0..n {
        println!("{}", dist[i] % 2);
    }
}


import Foundation
let N = Int(readLine()!)!

// -1: not determined, 0: black, 1: white
var graph: [[Int]] = .init(repeating: [], count: N)
var costs: [[Int]] = .init(repeating: [], count: N)
var colors: [Int] = .init(repeating: -1, count: N)

for _ in 0..<N-1 {
  let input = readLine()!.split(separator: " ").map { Int($0)! }
  graph[input[0] - 1].append(input[1] - 1)
  graph[input[1] - 1].append(input[0] - 1)
  costs[input[0] - 1].append(input[2])
  costs[input[1] - 1].append(input[2])
}

var queue = Set<Int>()
queue.insert(0)
colors[0] = 0

while !queue.isEmpty {
  let top = queue.first!
  queue.remove(top)
  for i in 0..<graph[top].count {
    let u = graph[top][i]
    let w = costs[top][i]
    if colors[u] != -1 {
      continue
    }
    colors[u] = (colors[top] + w)  % 2
    queue.insert(u)
  }
}

colors.forEach { print($0) }


let n = Int(readLine()!)!
var ans = Array(repeating:-1, count:n)

for i in 0..<n-1 {
  let l = readLine()!.split(separator:" ").map{ Int($0)! }
  let u = l[0]-1, v = l[1]-1, w = l[2]
  if ans[u] >= 0 {
    if w%2==1 {ans[v] = 1-ans[u]}
  } else if ans[v] >= 0 {
    if w%2==1 {ans[u] = 1-ans[v]}
  } else {
    ans[u] = 0
    if w%2==1 {ans[v] = 1-ans[u]}
  }
}

for i in 0..<n {
  print(ans[i] >= 0 ? ans[i]:0)
}


let n = Int(readLine()!)!
var ans = Array(repeating:-1, count:n)

for i in 0..<n-1 {
  let l = readLine()!.split(separator:" ").map{ Int($0)! }
  let u = l[0]-1, v = l[1]-1, w = l[2]
  if ans[u] >= 0 {
    if w%2==0 {ans[v] = ans[u]}
    else {ans[v] = 1-ans[u]}
  } else if ans[v] >= 0 {
    if w%2==0 {ans[u] = ans[v]}
    else {ans[u] = 1-ans[v]}
  } else {
    ans[u] = 0
    if w%2==0 {ans[v] = ans[u]}
    else {ans[v] = 1-ans[u]}
  }
}

for i in 0..<n {
  print(ans[i])
}


import Foundation
let N = Int(readLine()!)!

// -1: not determined, 0: black, 1: white
var graph: [[Int]] = .init(repeating: [], count: N)
var costs: [[Int]] = .init(repeating: [], count: N)
var colors: [Int] = .init(repeating: -1, count: N)

for _ in 0..<N-1 {
  let input = readLine()!.split(separator: " ").map { Int($0)! }
  graph[input[0] - 1].append(input[1] - 1)
  graph[input[1] - 1].append(input[0] - 1)
  costs[input[0] - 1].append(input[2])
}

var queue = Set<Int>()
queue.insert(0)
colors[0] = 0

while !queue.isEmpty {
  let top = queue.first!
  queue.remove(top)
  for i in 0..<graph[top].count {
    let u = graph[top][i]
    let w = costs[top][i]
    if colors[u] != -1 {
      continue
    }
    colors[u] = (colors[top] + w)  % 2
    queue.insert(u)
  }
}

colors.forEach { print($0) }


const log = console.log;

const createScanFunctions = (input: string) => {
  const str = input.trim();
  const len = str.length;
  let index = 0;

  const scan = () => {
    const startIndex = index;

    while (index < len) {
      const char = str[index];

      if (char === " " || char === "\n")
        return str.substring(startIndex, index++);

      index++;
    }

    return str.substr(startIndex);
  };

  const scanInt = () => parseInt(scan());

  return { scan, scanInt };
};

// ----

const createWeightedUnionFindTree = (elementCount: number) => {
  const parent = new Array<number>(elementCount);
  const rank = new Array<number>(elementCount);
  const weightDifference = new Array<number>(elementCount);

  for (let i = 0; i < elementCount; i++) {
    parent[i] = i;
    rank[i] = 0;
    weightDifference[i] = 0;
  }

  const getRoot = (id: number): number => {
    if (parent[id] === id) return id;

    const root = getRoot(parent[id]);
    weightDifference[id] += weightDifference[parent[id]];

    return (parent[id] = root);
  };

  const getWeight = (id: number) => {
    getRoot(id);

    return weightDifference[id];
  };

  const getWeightDifference = (idA: number, idB: number) =>
    getWeight(idA) - getWeight(idB);

  const uniteTrees = (idA: number, idB: number, weightDiff: number): void => {
    weightDiff += getWeight(idA) - getWeight(idB);

    const rootA = getRoot(idA);
    const rootB = getRoot(idB);

    if (rootA === rootB) return;

    if (rank[rootA] < rank[rootB]) {
      parent[rootA] = rootB;
      weightDifference[rootA] = -weightDiff;
    } else {
      parent[rootB] = rootA;
      weightDifference[rootB] = weightDiff;
      if (rank[rootA] === rank[rootB]) rank[rootA]++;
    }
  };

  const sameTree = (idA: number, idB: number) => getRoot(idA) === getRoot(idB);

  return {
    getRoot,
    uniteTrees,
    sameTree,
    getWeight,
    getWeightDifference
  };
};

const isOdd = (n: number) => (n & 1) === 1;

// ----

function Main(input: string): void {
  const { scanInt } = createScanFunctions(input);
  const n = scanInt();

  const { uniteTrees, getWeightDifference } = createWeightedUnionFindTree(n);

  const edgeCount = n - 1;

  for (let i = 0; i < edgeCount; i++) {
    const vertexIdA = scanInt() - 1;
    const vertexIdB = scanInt() - 1;
    const distance = scanInt();

    uniteTrees(vertexIdA, vertexIdB, distance);
  }

  const vertexColors = new Array<number>(n).fill(0);
  for (let i = 1; i < n; i++)
    if (isOdd(getWeightDifference(0, i))) vertexColors[i] = 1;

  log(vertexColors.join("\n"));
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


import * as fs from "fs";

let [N_str, ...uvw_str] = fs.readFileSync("/dev/stdin", "utf8").trim().split('\n');

let N = Number(N_str);
let colors: boolean[] = new Array(N).fill(false);

type weight = number;
let tree: Map<number, [number, weight][]> = new Map();

for(let i=0; i<N-1; i++) {
    // u < v
    let [u, v, w] = uvw_str[i].split(' ').map(Number);
    u -= 1;
    v -= 1;
    for(let [p, child] of [[u, v], [v, u]]) {
        if (!tree.has(p)) {
            tree.set(p, []);
        }
        tree.get(p).push([child, w]);
    }
}

let stack: [number, number | null][] = [[0, null]]; // list of pair of (node, parent)

while (stack.length != 0) {
    let [node, prev] = stack.pop()
    if (tree.has(node)) {
        for(let [child, weight] of tree.get(node)) {
            if (child == prev)
                continue;
            if (weight%2 == 0) {
                colors[child] = colors[node];
            } else {
                colors[child] = !colors[node];
            }
            stack.push([child, node]);
        }
    }
}

for(let i=0; i<N; i++) {
    console.log((colors[i]?0:1));
}


const log = console.log;

const createScanFunctions = (input: string) => {
  const str = input.trim();
  const len = str.length;
  let index = 0;

  const scan = () => {
    const startIndex = index;

    while (index < len) {
      const char = str[index];

      if (char === " " || char === "\n")
        return str.substring(startIndex, index++);

      index++;
    }

    return str.substr(startIndex);
  };

  const scanInt = () => parseInt(scan());

  return { scan, scanInt };
};

const createArrayOfNumberArrays = (length: number) => {
  const array = new Array<number[]>(length);
  for (let i = 0; i < length; i++) array[i] = [];

  return array;
};

const isEven = (n: number) => (n & 1) === 0;

// ----

function Main(input: string): void {
  const { scanInt } = createScanFunctions(input);

  // prepare graph
  const n = scanInt();
  const adjacentVertexIdTable = createArrayOfNumberArrays(n);
  const adjacentVertexDistanceTable = createArrayOfNumberArrays(n);
  const vertexColorArray = new Array<number | undefined>(n).fill(undefined);

  function linkVertices(id: number, adjacentId: number, distance: number) {
    adjacentVertexIdTable[id].push(adjacentId);
    adjacentVertexDistanceTable[id].push(distance);
    adjacentVertexIdTable[adjacentId].push(id);
    adjacentVertexDistanceTable[adjacentId].push(distance);
  }

  function paintVertex(id: number, color: number) {
    vertexColorArray[id] = color;
  }

  const getVertexColor = (id: number) => vertexColorArray[id];

  // read edges data
  const edgeCount = n - 1;

  for (let i = 0; i < edgeCount; i++)
    linkVertices(scanInt() - 1, scanInt() - 1, scanInt());

  // prepare search, visit first vertex
  const recentVisitedStack: number[] = [];

  vertexColorArray[0] = 0;
  recentVisitedStack.push(0);

  const visitAdjacentVerticesOf = (vertexId: number, searchStack: number[]) => {
    const adjacentVertexIdArray = adjacentVertexIdTable[vertexId];
    const adjacentVertexDistanceArray = adjacentVertexDistanceTable[vertexId];
    const len = adjacentVertexIdArray.length;

    const currentColor = getVertexColor(vertexId);
    if (currentColor === undefined)
      throw new Error(`Vertex id: ${vertexId} not colored.`);

    for (let i = 0; i < len; i++) {
      const adjacentVertexId = adjacentVertexIdArray[i];

      if (vertexColorArray[adjacentVertexId] !== undefined) continue; // already visited

      const adjacentColor = isEven(adjacentVertexDistanceArray[i])
        ? currentColor
        : currentColor ^ 1;

      paintVertex(adjacentVertexId, adjacentColor);

      searchStack.push(adjacentVertexId);
    }
  };

  // search & paint
  while (true) {
    const vertexId = recentVisitedStack.pop();
    if (vertexId === undefined) break;

    visitAdjacentVerticesOf(vertexId, recentVisitedStack);
  }

  // output
  for (const color of vertexColorArray) log(color);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


import * as fs from "fs";

let [N_str, ...uvw_str] = fs.readFileSync("/dev/stdin", "utf8").trim().split('\n');

let N = Number(N_str);
let colors: boolean[] = new Array(N).fill(false);

type weight = number;
let tree: Map<number, [number, weight][]> = new Map();

for(let i=0; i<N-1; i++) {
    // u < v
    let [u, v, w] = uvw_str[i].split(' ').map(Number);
    u -= 1;
    v -= 1;
    if (!tree.has(u)) {
        tree.set(u, []);
    }
    tree.get(u).push([v, w]);
}

let stack: number[] = [0];

while (stack.length != 0) {
    let node = stack.pop()
    if (tree.has(node)) {
        for(let [child, weight] of tree.get(node)) {
            if (weight%2 == 0) {
                colors[child] = colors[node];
            } else {
                colors[child] = !colors[node];
            }
            stack.push(child);
        }
    }
}

for(let i=0; i<N; i++) {
    console.log((colors[i]?0:1));
}


import * as fs from "fs";

let [N_str, ...uvw_str] = fs.readFileSync("/dev/stdin", "utf8").trim().split('\n');

let N = Number(N_str);
let U = new Array();
let V = new Array();
let W = new Array();
for(let i=0; i<N-1; i++) {
    let [u, v, w] = uvw_str[i].split(' ').map(Number);
    U.push(u);
    V.push(v);
    W.push(w);
}
for(let i=0; i<N; i++) {
    console.log(0);
}


const log = console.log;

const createScanFunctions = (input: string) => {
  const str = input.trim();
  const len = str.length;
  let index = 0;

  const scan = () => {
    const startIndex = index;

    while (index < len) {
      const char = str[index];

      if (char === " " || char === "\n")
        return str.substring(startIndex, index++);

      index++;
    }

    return str.substr(startIndex);
  };

  const scanInt = () => parseInt(scan());

  return { scan, scanInt };
};

// ----

const createUnionFindTree = (elementCount: number) => {
  const parent = new Array<number>(elementCount);
  const rank = new Array<number>(elementCount);

  for (let i = 0; i < elementCount; i++) {
    parent[i] = i;
    rank[i] = 0;
  }

  const getRoot = (id: number) =>
    parent[id] === id ? id : (parent[id] = getRoot(parent[id]));

  const uniteGroups = (idA: number, idB: number): void => {
    const rootA = getRoot(idA);
    const rootB = getRoot(idB);

    if (rootA === rootB) return;

    if (rank[rootA] < rank[rootB]) {
      parent[rootA] = rootB;
    } else {
      parent[rootB] = rootA;
      if (rank[rootA] === rank[rootB]) rank[rootA]++;
    }
  };

  const sameGroup = (idA: number, idB: number) => getRoot(idA) === getRoot(idB);

  return { uniteGroups, sameGroup };
};

const isEven = (n: number) => (n & 1) === 0;

// ----

function Main(input: string): void {
  const { scanInt } = createScanFunctions(input);
  const n = scanInt();

  const { uniteGroups, sameGroup } = createUnionFindTree(n);

  const edgeCount = n - 1;

  for (let i = 0; i < edgeCount; i++) {
    const vertexIdA = scanInt() - 1;
    const vertexIdB = scanInt() - 1;
    const distance = scanInt();

    if (isEven(distance)) uniteGroups(vertexIdA, vertexIdB);
  }

  // output
  const vertexColors = new Array<number>(n).fill(0);
  for (let i = 0; i < n; i++) if (!sameGroup(i, 0)) vertexColors[i] = 1;

  log(vertexColors.join("\n"));
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


def main():
    n, k, q, *al = map(int, open(0).read().split())
    gl = [0] * n
    for a in al:
        gl[a-1] += 1

    res = '\n'.join(
        'Yes' if g > q-k
        else 'No'
        for g in gl
    )
    print(res)

if __name__ == '__main__':
    main()


def main():
    N, K, Q, *A = map(int, open(0).read().split())
    ans = [0] * N
    for a in A:
        ans[a - 1] += 1
    print("\n".join("Yes" if Q < K + a else "No" for a in ans))
    return

main()


def main():
    N, K, Q, *A = map(int, open(0).read().split())
    ans = [0] * N
    for a in A:
        ans[a - 1] += 1
    print("\n".join(["Yes" if Q < K + a
                     else "No" for a in ans]))
    return

main()


n,k,q = map(int,input().split())
point = [k]*(n)
for _ in range(q):
    a = int(input())
    for i in range(n):
        if a-1 == i:
            pass
        else:
            point[i] -= 1
for i in range(n):
    if point[i] > 0:
        print("Yes")
    else:
        print("No")


N,K,Q = map(int,input().split())
A = [int(input()) for i in range(Q)]
B = [K]*N
p = 0
for i in range(N+1):
    A.append(i+1)
C = sorted(A)
for i in range(N):
    B[i] += C.index(i+2) - p - 1
    p = C.index(i+2)
for i in range(N):
    if(B[i] > Q):
        print("Yes")
    else:
        print("No")


N,K,Q = map(int,input().split())
A = [int(input()) for i in range(Q)]
B = [K]*N
for i in range(N):
    B[i] += A.count(i+1)
for i in range(N):
    if(B[i] > Q):
        print("Yes")
    else:
        print("No")


import java.util.*;
import java.io.*;

public class Main {

    static FastScanner sc=new FastScanner();
    static PrintWriter out=new PrintWriter(System.out);

    public static void main(String [] args) throws IOException{
        int n=sc.nextInt();
        long k=sc.nextLong();
        int q=sc.nextInt();
        long [] a=new long[n+1];
        for(int i=0;i<q;i++){
            a[sc.nextInt()]++;
        }

        StringBuilder sb=new StringBuilder("");
        for(int i=1;i<=n;i++){
            if((k+a[i]-q)<=0){
                sb.append("No\n");
            }else{
                sb.append("Yes\n");
            }
        }
        out.println(sb.toString().trim());

        out.close();
    }
}

class FastScanner{
    private int BUFFER_SIZE = 1 << 16;

   private  DataInputStream din;

   private  byte[] buffer;

   private int bufferPointer, bytesRead;

   public FastScanner() {
       din = new DataInputStream(System.in);
       buffer = new byte[BUFFER_SIZE];
       bufferPointer = bytesRead = 0;
   }

   public FastScanner( String file_name) throws IOException {
       din = new DataInputStream(new FileInputStream(file_name));
       buffer = new byte[BUFFER_SIZE];
       bufferPointer = bytesRead = 0;
   }

   public String readLine() throws IOException {
        byte[] buf = new byte[64];
       int cnt = 0, c;
       while ((c = read()) != -1) {
           if (c == '\n')
               break;
           buf[cnt++] = (byte) c;
       }
       return new String(buf, 0, cnt);
   }

   public String next() throws IOException{

       byte c = read();
       while(Character.isWhitespace(c)){
           c = read();
       }

        StringBuilder builder = new StringBuilder();
       builder.append((char)c);
       c = read();
       while(!Character.isWhitespace(c)){
           builder.append((char)c);
           c = read();
       }

       return builder.toString();
   }

   public int nextInt() throws IOException {
       int ret = 0;
       byte c = read();
       while (c <= ' ')
           c = read();
        boolean neg = (c == '-');
       if (neg)
           c = read();
       do {
           ret = ret * 10 + c - '0';
       } while ((c = read()) >= '0' && c <= '9');

       if (neg)
           return -ret;
       return ret;
   }

   public int[] nextIntArray( int n) throws IOException {
        int arr[] = new int[n];
       for(int i = 0; i < n; i++){
           arr[i] = nextInt();
       }
       return arr;
   }

   public long nextLong() throws IOException {
       long ret = 0;
       byte c = read();
       while (c <= ' ')
           c = read();
        boolean neg = (c == '-');
       if (neg)
           c = read();
       do {
           ret = ret * 10 + c - '0';
       } while ((c = read()) >= '0' && c <= '9');
       if (neg)
           return -ret;
       return ret;
   }

   public long[] nextLongArray( int n) throws IOException {
        long arr[] = new long[n];
       for(int i = 0; i < n; i++){
           arr[i] = nextLong();
       }
       return arr;
   }

   public char nextChar() throws IOException{
       byte c = read();
       while(Character.isWhitespace(c)){
           c = read();
       }
       return (char) c;
   }

   public double nextDouble() throws IOException {
       double ret = 0, div = 1;
       byte c = read();
       while (c <= ' ')
           c = read();
        boolean neg = (c == '-');
       if (neg)
           c = read();

       do {
           ret = ret * 10 + c - '0';
       } while ((c = read()) >= '0' && c <= '9');

       if (c == '.') {
           while ((c = read()) >= '0' && c <= '9') {
               ret += (c - '0') / (div *= 10);
           }
       }

       if (neg)
           return -ret;
       return ret;
   }

   public double[] nextDoubleArray( int n) throws IOException {
        double arr[] = new double[n];
       for(int i = 0; i < n; i++){
           arr[i] = nextDouble();
       }
       return arr;
   }

   private void fillBuffer() throws IOException {
       bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
       if (bytesRead == -1)
           buffer[0] = -1;
   }

   private byte read() throws IOException {
       if (bufferPointer == bytesRead)
           fillBuffer();
       return buffer[bufferPointer++];
   }

   public void close() throws IOException {
       if (din == null)
           return;
       din.close();
   }

}


import java.io.*;
import java.util.*;
import java.math.*;
// import java.awt.Point;

public class Main {
    InputStream is;
    PrintWriter out;
    String INPUT = "";

    static int mod = 1_000_000_007;
    // int mod = 998244353;
    // long inf = Long.MAX_VALUE/2;
    int inf = Integer.MAX_VALUE/2;

    void solve(){
        int n = ni();
        int k = ni();
        int q = ni();
        int[] a = new int[q];
        int[] num = new int[n];
        for(int i = 0; i < q; i++){
            a[i] = ni()-1;
            num[a[i]]++;
        }
        for(int i = 0; i < n; i++){
            if(k-q+num[i]>0) out.println("Yes");
            else out.println("No");
        }
    }

    void run() throws Exception
    {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        out.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception { new Main().run(); }

    private byte[] inbuf = new byte[1024];
    private int lenbuf = 0, ptrbuf = 0;

    private int readByte()
    {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns()
    {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b) && b != ' ')){
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n)
    {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m)
    {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n)
    {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni()
    {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl()
    {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, FastReader s, PrintWriter out) {
            int n = s.nextInt();
            int k = s.nextInt();
            int q = s.nextInt();
            int[] arr = s.nextIntArray(q);
            int[] neg = new int[n];
            Arrays.fill(neg, q);

            int[] ans = new int[n];
            Arrays.fill(ans, k);
            for (int i = 0; i < q; i++) {
                neg[arr[i] - 1]--;
            }

            for (int i = 0; i < n; i++) {
                ans[i] -= neg[i];
                if (ans[i] > 0)
                    out.println("Yes");
                else
                    out.println("No");
            }

        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public int[] nextIntArray(int n) {
            int[] array = new int[n];
            for (int i = 0; i < n; ++i) array[i] = nextInt();
            return array;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.util.Scanner;

public class Main {

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int k = sc.nextInt();
    int q = sc.nextInt();
    int[] a = new int[n];

    for (int i = 0; i < q; i++) {
      int c = sc.nextInt();
      a[c - 1]++;
    }

    for (int i = 0; i < n; i++) {
      if (a[i] > Math.max(q - k, 0)) {
        System.out.println("Yes");
      } else {
        System.out.println("No");
      }
    }

  }
}


import java.util.Arrays;
import java.util.Scanner;

public class Main {

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int k = sc.nextInt();
    int q = sc.nextInt();
    int[] a = new int[n];
    Arrays.fill(a, k);

    for (int i = 0; i < q; i++) {
      int c = sc.nextInt();
      for (int j = 0; j < n; j++) {
        if (j != (c - 1)) {
          a[j]--;
        }
      }
    }

    for (int i = 0; i < n; i++) {
      if (a[i] > 0) {
        System.out.println("Yes");
      } else {
        System.out.println("No");
      }
    }

  }
}


import java.util.*; import java.io.*; import java.math.*;
public class Main{
	//Don't have to see. start------------------------------------------
	static class InputIterator{
		ArrayList<String> inputLine = new ArrayList<String>(1024);
		int index = 0; int max; String read;
		InputIterator(){
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			try{
				while((read = br.readLine()) != null){
					inputLine.add(read);
				}
			}catch(IOException e){}
			max = inputLine.size();
		}
		boolean hasNext(){return (index < max);}
		String next(){
			if(hasNext()){
				return inputLine.get(index++);
			}else{
				throw new IndexOutOfBoundsException("There is no more input");
			}
		}
	}
	static HashMap<Integer, String> CONVSTR = new HashMap<Integer, String>();
	static InputIterator ii = new InputIterator();//This class cannot be used in reactive problem.
	static PrintWriter out = new PrintWriter(System.out);
	static void flush(){out.flush();}
	static void myout(Object t){out.println(t);}
	static void myerr(Object t){System.err.print("debug:");System.err.println(t);}
	static String next(){return ii.next();}
	static boolean hasNext(){return ii.hasNext();}
	static int nextInt(){return Integer.parseInt(next());}
	static long nextLong(){return Long.parseLong(next());}
	static double nextDouble(){return Double.parseDouble(next());}
	static ArrayList<String> nextStrArray(){return myconv(next(), 8);}
	static ArrayList<String> nextCharArray(){return myconv(next(), 0);}
	static ArrayList<Integer> nextIntArray(){
		ArrayList<String> input = nextStrArray(); ArrayList<Integer> ret = new ArrayList<Integer>(input.size());
		for(int i = 0; i < input.size(); i++){
			ret.add(Integer.parseInt(input.get(i)));
		}
		return ret;
	}
	static ArrayList<Long> nextLongArray(){
		ArrayList<String> input = nextStrArray(); ArrayList<Long> ret = new ArrayList<Long>(input.size());
		for(int i = 0; i < input.size(); i++){
			ret.add(Long.parseLong(input.get(i)));
		}
		return ret;
	}
	static String myconv(Object list, int no){//only join
		String joinString = CONVSTR.get(no);
		if(list instanceof String[]){
			return String.join(joinString, (String[])list);
		}else if(list instanceof ArrayList){
			return String.join(joinString, (ArrayList)list);
		}else{
			throw new ClassCastException("Don't join");
		}
	}
	static ArrayList<String> myconv(String str, int no){//only split
		String splitString = CONVSTR.get(no);
		return new ArrayList<String>(Arrays.asList(str.split(splitString)));
	}
	public static void main(String[] args){
		CONVSTR.put(8, " "); CONVSTR.put(9, "\n"); CONVSTR.put(0, "");
		solve();flush();
	}
	//Don't have to see. end------------------------------------------
	static void solve(){//Here is the main function
      ArrayList<Integer> one = nextIntArray();
      int N = one.get(0);
      int K = one.get(1);
      int Q = one.get(2);
      int[] list = new int[N];
      for(int i = 0; i < N; i++){
        list[next() - 1]++;
      }
      for(int i = 0; i < N; i++){
        if(K - Q + list[i] <= 0){
          myout("No");
        }else{
          myout("Yes");
        }
      }
	}
	//Method addition frame start

	//Method addition frame end
}


//#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define Would
#define you
#define please

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm;
inline char getcha() {
	if (ci - cn == cm) { fread(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	char C = getcha();
	int A = C - '0';
	while ((C = getcha()) >= '0') A = A * 10 + C - '0';
	return A;
}

const int dm = 1 << 12;
char dn[dm], * di = dn;

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

	int N = getint(), K = getint(), Q = getint();

	int P[100001];
	rep1(i, N) {
		P[i] = K - Q;
	}
	rep(i, Q) {
		P[getint()]++;
	}
	rep1(i, N) {
		if (P[i] > 0) {
			*di++ = 'Y';
			*di++ = 'e';
			*di++ = 's';
			*di++ = '\n';
		}
		else {
			*di++ = 'N';
			*di++ = 'o';
			*di++ = '\n';
		}
		if (i % 100 == 0) {
			fwrite(dn, 1, di - dn, stdout);
			di = dn;
		}
	}
	fwrite(dn, 1, di - dn, stdout);

	Would you please return 0;
}


//#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define Would
#define you
#define please

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm;
inline char getcha() {
	if (ci - cn == cm) { fread(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	char C = getcha();
	int A = C - '0';
	while ((C = getcha()) >= '0') A = A * 10 + C - '0';
	return A;
}

const int dm = 1 << 16;
char dn[dm], * di = dn;

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

	int N = getint(), K = getint(), Q = getint();

	int P[100001];
	rep1(i, N) {
		P[i] = K - Q;
	}
	rep(i, Q) {
		P[getint()]++;
	}
	rep1(i, N) {
		if (P[i] > 0) {
			*di++ = 'Y';
			*di++ = 'e';
			*di++ = 's';
			*di++ = '\n';
		}
		else {
			*di++ = 'N';
			*di++ = 'o';
			*di++ = '\n';
		}
		if (i % 16000 == 0) {
			fwrite(dn, 1, di - dn, stdout);
			di = dn;
		}
	}
	fwrite(dn, 1, di - dn, stdout);

	Would you please return 0;
}


//#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define Would
#define you
#define please

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm;
inline char getcha() {
	if (ci - cn == cm) { fread(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	char C = getcha();
	int A = C - '0';
	while ((C = getcha()) >= '0') A = A * 10 + C - '0';
	return A;
}

const int dm = 1 << 17;
char dn[dm], * di = dn;

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

	int N = getint(), K = getint(), Q = getint();

	int P[100001];
	rep1(i, N) {
		P[i] = K - Q;
	}
	rep(i, Q) {
		P[getint()]++;
	}
	rep1(i, N) {
		if (P[i] > 0) {
			*di++ = 'Y';
			*di++ = 'e';
			*di++ = 's';
			*di++ = '\n';
		}
		else {
			*di++ = 'N';
			*di++ = 'o';
			*di++ = '\n';
		}
		if (i % 25000 == 0) {
			fwrite(dn, 1, di - dn, stdout);
			di = dn;
		}
	}
	fwrite(dn, 1, di - dn, stdout);

	Would you please return 0;
}


#include<iostream>
#include <algorithm>
#include <cmath>
#include <set>
#include<map>
#include<cstring>
#include<iomanip>
#include <string>
#include <vector>
#include<unordered_map>
#include<unordered_set>
using namespace std;

typedef long long unsigned llu;
typedef long double ld;
#define ll long long
#define PI 3.14159265358979323846
#define For(i, a, b) for (int i = a, sz = (int)b; i < sz; i++)
#define rFor(i, a, b, c) for (int i = (a); i >= (b); i -= (c))
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define fill(a, b) memset(a, b, sizeof(a))
#define IO ios_base::sync_with_stdio(false), cin.tie(0),cout.tie(0)
const int mod = 1000000007;
const ll inf = 1000000000009;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) { return a*b/gcd(a,b);}

//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdoutn

int main()
{
	IO;
	map<int,int>m;
	ll n{},k{},q{};
	cin>>n>>k>>q;
	For(i,1,q+1){int x{};cin>>x; m[x]++;}
	vector<int>p(n+1);
	For(i,1,n+1)p[i]=k;
	For(i,1,n+1)
	{
		if(m[i]>0)p[i]-=q-m[i];
		else if(!m[i])p[i]-=q;
	}
	For(i,1,n+1)
	{
		if(p[i]>0)cout<<"YES\n";
		else cout<<"NO\n";
	}
//	system("pause");
	return 0;
}


// セグメントツリー　遅延評価なし ((0-indexed))
// https://www.creativ.xyz/segment-tree-abstraction-979/
#include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0;i<(n);i++)

typedef long long ll;

#define REP(i,n) for(ll i=0;i<(ll)(n);i++)
#define REPD(i,n) for(ll i=n-1;i>=0;i--)
#define FOR(i,a,b) for(ll i=a;i<=(ll)(b);i++)
#define FORD(i,a,b) for(ll i=a;i>=(ll)(b);i--)
//定数
#define INF 1000000000 //10^9:極めて大きい値,∞
//略記
#define PB push_back //vectorヘの挿入
#define MP make_pair //pairのコンストラクタ
#define F first //pairの一つ目の要素
#define S second //pairの二つ目の要素

template <class T>
class SegTree {
    int n;                       // 葉の数
    vector<T> data;              // データを格納するvector
    T def;                       // 初期値かつ単位元
    function<T(T, T)> operation; // 区間クエリで使う処理

    // 区間[a,b)の総和。ノードk=[l,r)に着目している。
    T _query(int a, int b, int k, int l, int r) {
        if (r <= a || b <= l) return def; // 交差しない
        if (a <= l && r <= b)
            return data[k]; // a,l,r,bの順で完全に含まれる
        else {
            T c1 = _query(a, b, 2 * k + 1, l, (l + r) / 2); // 左の子
            T c2 = _query(a, b, 2 * k + 2, (l + r) / 2, r); // 右の子
            return operation(c1, c2);
        }
    }

  public:
    // _n:必要サイズ, _def:初期値かつ単位元, _operation:クエリ関数
    SegTree(size_t _n, T _def, function<T(T, T)> _operation)
        : def(_def), operation(_operation) {
        n = 1;
        while (n < _n) {
            n *= 2;
        }
        data = vector<T>(2 * n - 1, def);
    }

    // 場所i(0-indexed)の値をxで更新
    void change(int i, T x) {
        i += n - 1;
        data[i] = x;
        while (i > 0) {
            i = (i - 1) / 2;
            data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
        }
    }
    // 場所i(0-indexed)の値をxで加算
    void add(int i, T x) {
        i += n - 1;
        data[i] = data[i]+ x;
        while (i > 0) {
            i = (i - 1) / 2;
            data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
        }
    }

    // [a, b)の区間クエリを実行
    T query(int a, int b) {
        return _query(a, b, 0, 0, n);
    }

    // 添字でアクセス
    T operator[](int i) {
        return data[i + n - 1];
    }
};
/////////////////////////////
// 区間クエリ                                                  dif
// 区間ｍinクエリ： int func(int a, int b){ return min(a, b); } INF
// 区間ｍaxクエリ： int func(int a, int b){ return max(a, b); } -INF
// 区間和： int func(int a, int b){ return a + b; }            0
/////////////////////////////

int main(void) {
    int N, K, Q;
    cin >> N >> K >> Q;
    // 要素数N・dif=INF・区間min
    SegTree<long long> st(N, K,
                          [](long long a, long long b) { return a+b; });
    rep(q, Q) {
        int a;
        cin >> a;
        a--;
        rep(i,a) st.add(i,-1);
        for(int i=a+1;i<N;i++) st.add(i,-1);
    }
    rep(i,N){
        if(st[i]>0) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){
  int n,k,q,ans;
  cin>>n>>k>>q;
  vector<int>p(n+1,k-q);
  for(int i=0;i<q;i++){
    int ai;
    cin>>ai;
    p[ai]++;
    ans+=p[ai]>0;
  }
  cout<<ans<<endl;
  return 0;
}


// 2019.9.15 bal4u
// Template for Online Contest

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

typedef long long ll;

#define gc() getchar()
#define pc(c) putchar(c)

int in() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

ll inL() {  // long long 整数の入力
	ll n = 0; int c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void out(int n) { // 整数の表示
	int i; char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

void outL(ll n) { // 整数の表示
	int i; char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

int ins(char *s) { // 文字列の入力
	char *p = s--;
	do *++s = gc();
	while (*s > ' ');
	*s = 0;
	return s - p;
}

void outs(char *s) {  // 文字列の表示
	while (*s) pc(*s++);
}

#define MIN(a,b)  ((a)<=(b)?(a):(b))
#define MAX(a,b)  ((a)>=(b)?(a):(b))
#define ABS(a)    ((a)>=0?(a):-(a))
inline static int chmax(int *a, int b) { if (*a < b) *a = b; }
inline static ll  chmaxL(ll *a, int b) { if (*a < b) *a = b; }
inline static int chmin(int *a, int b) { if (*a > b) *a = b; }
inline static ll  chminL(ll *a, int b) { if (*a > b) *a = b; }

int N, K, Q;
int f[100005];

int main()
{
	int i;

	N = in(), K = in(), Q = in();
	for (i = 0; i < Q; i++) f[in()]++;
	for (i = 1; i <= N; i++) puts(K-Q+f[i] <= 0? "No": "Yes");
	return 0;
}