import std.stdio, std.conv, std.string;
import std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

int DEBUG_LEVEL = 0;
void print()(){ writeln(""); }
void print(T, A ...)(T t, lazy A a){ write(t), print(a); }
void print(int level, T, A ...)(T t, lazy A a){ if(level <= DEBUG_LEVEL) print(t, a); }

void main(string[] args){
	if(args.length > 1 && args[1] == "-debug"){
		if(args.length > 2 && args[2].isNumeric) DEBUG_LEVEL = args[2].to!int;
		else DEBUG_LEVEL = 1;
	}
	
	int n = read.to!int;
	
	Node[] nodes;
	foreach(i; 0 .. n) nodes ~= new Node(i);
	
	Edge[] edges;
	foreach(i; 0 .. n - 1){
		int u = read.to!int - 1;
		int v = read.to!int - 1;
		long w = read.to!long;
		edges ~= new Edge(nodes[u], nodes[v], w);
	}
	
	nodes[0].setValue(1);
	foreach(ed; edges) ed.paint();
	
	foreach(nd; nodes) nd.value.writeln;
	
}

class Edge{
	Node node1;
	Node node2;
	long value;
	this(Node node1, Node node2, long value){
		if(node1.id < node2.id) this.node1 = node1, this.node2 = node2;
		else this.node1 = node2, this.node2 = node1;
		node1.edges ~= this, node2.edges ~= this;
		this.value = value;
	}
	void paint(){
		if(node1.isVisited && ! node2.isVisited){
			node2.setValue((node1.value + this.value) % 2);
			foreach(ed; node2.edges) ed.paint();
		}
		else if(! node1.isVisited && node2.isVisited){
			node1.setValue((node2.value + this.value) % 2);
			foreach(ed; node1.edges) ed.paint();
		}
		else if(! node1.isVisited && node2.isVisited){
			foreach(ed; node1.edges) ed.paint();
			foreach(ed; node2.edges) ed.paint();
		}
		
	}
}

// 木 辺の重み edge 再帰

class Node{
	int id;
	int value = -1;
	bool isVisited = 0;
	Edge[] edges;
	this(int id){
		this.id = id;
	}
	void setValue(int v){
		value = v % 2;
		this.isVisited = 1;
	}
}
