unittest
{
	assert( [ "3", "1 2 2", "2 3 1" ].parse.expand.solve == "0\n0\n1" );
//	assert( [ "5", "2 5 2", "2 3 10", "1 3 8", "3 4 2" ].parse.expand.solve == "1\n0\n1\n0\n1" );
	assert( [ "5", "2 5 2", "2 3 10", "1 3 8", "3 4 2" ].parse.expand.solve == "0\n0\n0\n0\n0" );
}



import std.conv;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto n = input.front.to!( long );
	auto uvws = new long[][]( n - 1, 3 );
	foreach( ref uvw; uvws )
	{
		input.popFront;
		uvw = input.front.split.to!( long[] );
	}
	return tuple( n, uvws );
}

auto solve( long n, long[][] uvws )
{
	auto bws = new Tuple!( long, long )[][]( n );
	foreach( ref uvw; uvws )
	{
		uvw[ 0 ]--;
		uvw[ 1 ]--;
		bws[ uvw[ 0 ] ] ~= tuple( uvw[ 1 ], uvw[ 2 ] );
		bws[ uvw[ 1 ] ] ~= tuple( uvw[ 0 ], uvw[ 2 ] );
	}
	
	auto cs = new byte[]( n );
	cs[ 1 .. $ ] = -1;
	
	auto queue = [ 0L ];
	while( !queue.empty )
	{
		auto t = queue.front;
		queue.popFront();
		foreach( bw; bws[ t ] )
		{
			if( 0 <= cs[ bw[ 0 ] ] ) continue;
			if( bw[ 1 ] % 2 == 0 ) cs[ bw[ 0 ] ] =  cs[ t ];
			else                   cs[ bw[ 0 ] ] = !cs[ t ];
			queue ~= bw[ 0 ];
		}
	}
	
	return cs.to!( string[] ).join( "\n" );
}
