jiahuimbzuai/CoQuIR huggingface dataset:
//  [typescript]
function main(input) {
  const [N,A,B,C,D,E] = input.split("\n").map(v => parseInt(v));
  console.log(Math.ceil(N / Math.min(A,B,C,D,E)) + 4);
}
main(require("fs").readFileSync("/dev/stdin", "utf8").trim());
//  [typescript]
import * as fs from "fs";
const input = fs.readFileSync("/dev/stdin", "utf8").split("\n");

const n = Number(input[0]);
const s = input[1];
let result = 0;
if (s.length < 2) {
    console.log(result);
} else {
    for (let i = 1; i < s.length; i++) {
        const char = s[i];
        const prevChar = s[i - 1];
        if (prevChar === "#" && char === ".") {
            result++;
        }
    }
    console.log(result);
}
//  [typescript]
const txt = require('fs').readFileSync('/dev/stdin', 'utf8')

const [n, a, b, c, d, e, gomi] = txt.split('\n').map((i: string) => { return Number(i) })
const min = [a, b, c, d, e].sort()[0]
if (n % min === 0) {
  console.log(Math.floor(n / min) + 4)
}
else {
  console.log(Math.floor(n / min) + 5)
}
//  [typescript]
const txt = require('fs').readFileSync('/dev/stdin', 'utf8')

const [n, a, b, c, d, e, gomi] = txt.split('\n').map((i: string) => { return Number(i) })
const min = [a, b, c, d, e].sort()[0]
if (min % n === 0) {
  console.log(Math.floor(n / min) + 4)
}
else {
  console.log(Math.floor(n / min) + 5)
}
//  [python]
import sys
from collections import deque


def input():
    return sys.stdin.readline().rstrip()


def main():
    N = int(input())
    edge = [[] for _ in range(N + 1)]
    for i in range(N - 1):
        u, v, w = map(int, input().split())
        edge[u].append((v, w))
        edge[v].append((u, w))

    color = [False] * (N + 1)
    color[1] = 0
    q = deque([1])
    pass
    while q:
        u= q.popleft()
        c1 = color[u]
        for c,w in edge[u]:
            if color[c] is False:
                q.append(c)
                color[c] = (c1+w)%2

    color.pop(0)
    print(*color)

if __name__ == "__main__":
    main()
//  [python]
import sys
from collections import deque
import bisect
import copy
import heapq
import itertools
import math
input = sys.stdin.readline
sys.setrecursionlimit(1000000)
mod = 10 ** 9 + 7

def read_values(): return map(int, input().split())
def read_index(): return map(lambda x: int(x) - 1, input().split())
def read_list(): return list(read_values())
def read_lists(N): return [read_list() for n in range(N)]


def f(N):
    res = 0
    while N != 0:
        b = format(N, "b").count("1")
        N %= b
        res += 1
    return res


def main():
    N = int(input())
    F = [[] for _ in range(N)]

    for _ in range(N - 1):
        u, v, w = read_values()
        u -= 1
        v -= 1
        F[u].append((v, w % 2))
        F[v].append((u, w % 2))

    D = [0] * N
    stack = [(0, 0, -1)]

    while stack:
        a, d, p = stack.pop()
        D[a] = d % 2

        for b, w in F[a]:
            if b == p:
                continue
            stack.append((b, (d + w) % 2, a))
    
    for d in D:
        print(d)


if __name__ == "__main__":
    main()
//  [python]
import sys
input = sys.stdin.readline
from collections import *

def bfs():
    q = deque([0])
    dist = [-1]*N
    dist[0] = 0
    
    while q:
        v = q.popleft()
        
        for nv, w in G[v]:
            if dist[nv]==-1:
                dist[nv] = dist[v]+w
                q.append(nv)
        
    return dist

N = int(input())
G = [[] for _ in range(N)]

for _ in range(N-1):
    u, v, w = map(int, input().split())
    G[u-1].append((v-1, w))
    G[v-1].append((u-1, w))

dist = bfs()
ans = [0]*N

for i in range(N):
    if dist[i]%2==0:
        ans[i] = 1

for ans_i in ans:
    print(ans_i)
//  [python]
from collections import deque

N = int(input())
graph = [[] for _ in range(N)]
for _ in range(N - 1):
    u, v, w = map(int, input().split())
    u, v, w = u - 1, v - 1, w % 2
    graph[u].append([v, w])
    graph[v].append([u, w])

colors = [-1 for _ in range(N)]
stack = deque()
stack.append(0)
colors[0] = 0

while stack:
    n = stack.pop()
    for _next, w in graph[n]:
        if colors[_next] != -1:
            continue
        colors[_next] = (colors[n] + w) % 2
        stack.append([_next])

for c in colors:
    print(c)
//  [python]
from collections import deque

N = int(input())
graph = [[] for _ in range(N)]
for _ in range(N - 1):
    u, v, w = map(int, input().split())
    u, v, w = u - 1, v - 1, w % 2
    graph[u].append([v, w])
    graph[v].append([u, w])

colors = [-1 for _ in range(N)]
stack = deque()
stack.append(0)
colors[0] = 0

while stack:
    n = stack.pop()
    for _next, w in graph[n]:
        if colors[_next] == -1:
            continue
        colors[_next] = (colors[n] + w) % 2 
        stack.append([_next])

for c in colors:
    print(c)
//  [python]
from collections import deque

N = int(input())
graph = [[] for _ in range(N)]
for _ in range(N - 1):
    u, v, w = map(int, input().split())
    u, v, w = u - 1, v - 1, w % 2
    graph[u].append([v, w])
    graph[v].append([u, w])

colors = [-1 for _ in range(N)]
stack = deque()
if N != 1:
    stack.append([0, graph[0][0][0], graph[0][0][1]])
colors[0] = 0

while stack:
    prev, _next, w = stack.pop()
    if colors[_next] == -1:
        if w % 2 == 0:
            color = 0
        else:
            color = 1
        colors[_next] = color
    for v1, w1 in graph[_next]:
        if colors[v1] != -1:
            continue
        stack.append([_next, v1, w + w1])

for c in colors:
    print(c)
//  [cpp]
#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
//#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 chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

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

int to[200001], ne[200001], he[100001];
bool d[100001], D[100001];
void dfs(int A, int prev, bool B) {
	D[A] = B;
	for (int i = he[A]; i; i = ne[i]) {
		if (prev != to[i]) dfs(to[i], A, B ^ d[i >> 1]);
	}
}

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


	int N = getint();
	int k = 2;
	rep1(i, N - 1) {
		int x = getint();
		int y = getint();
		bool z = getint() & 1;
		to[k] = y;
		ne[k] = he[x];
		he[x] = k++;
		to[k] = x;
		ne[k] = he[y];
		he[y] = k++;
		d[i] = z;
	}

	dfs(1, 0, 0);
	const int dm = 1 << 18;
	char dn[dm], * di = dn;
	rep1(i, N) {
		*di++ = '0' + D[i];
		*di++ = '\n';
	}
	fwrite_unlocked(dn, di - dn, 1, stdout);

	Would you please return 0;
}
//  [cpp]
#include<bits/stdc++.h>
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, ct;
inline char getcha() {
	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	if (ci - cn + 16 > cm) {
		int A = getcha() - '0';
		while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
		return A;
	}
	else {
		int A = *ci++ - '0';
		while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';
		return A;
	}
}

pair<pair<int, int>, int> E[200002];
int H[100001];
int D[100001];
void dfs(int A, int B) {
	if (!D[A]) {
		D[A] = B;
		for (int i = H[A]; i; i = E[i].second) {
			dfs(E[i].first.first, B + E[i].first.second);
		}
	}
}

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


	int N = getint();
	for (int i = 1; i < 2 * N - 2; i += 2) {
		int x = getint();
		int y = getint();
		int z = getint() & 1;
		E[i] = mp(mp(y, z), H[x]);
		H[x] = i;
		E[i + 1] = mp(mp(x, z), H[y]);
		H[y] = i + 1;
	}
	
	dfs(1, 1);
	const int dm = 1 << 18;
	char dn[dm], *di = dn;
	rep1(i, N) {
		if (D[i] & 1) *di++ = '0';
		else *di++ = '1';
		*di++ = '\n';
	}
	fwrite_unlocked(dn, di - dn, 1, stdout);

	Would you please return 0;
}
//  [cpp]
#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;
  }
}
//  [cpp]
#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';
}
//  [c]
// 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;
}
//  [c]
#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;
}
//  [c]
#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;
}
//  [c]
#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);
}
//  [c]
#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;
}
//  [c]
#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;
}
//  [javascript]
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");
}
//  [javascript]
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"))}}]);
//  [javascript]
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')));
//  [javascript]
//↓見なくていいよ！ここから--------------------------------------------------
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));
}
//  [javascript]
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;
}
//  [javascript]
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;
}
//  [go]
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
}
//  [go]
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)
	}
}
//  [go]
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)
	}
}
//  [go]
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)
	}
}
//  [go]
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)
	}
}
//  [ruby]
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]
//  [ruby]
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]
//  [ruby]
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]
//  [ruby]
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
//  [ruby]
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]
//  [ruby]
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]
//  [rust]
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);
    }
}
//  [rust]
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);
    }
}
//  [rust]
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);
    }
}
//  [swift]
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) }
//  [swift]
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)
}
//  [swift]
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])
}
//  [swift]
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) }