// Original C++ solution (slower):


//#pragma GCC optimize("03,unroll-loops")

//#pragma GCC target("avx,avx2,fma")



#include<bits/stdc++.h>

typedef long long ll;

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

#define ordered_set tree<int, null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>

#define pb           push_back

#define ff           first

#define ss           second

#define gcd(a, b)    __gcd(a, b)

#define lcm(a, b)    ((a)*((b)/gcd(a,b)))

#define all(v)       v.begin(),v.end()

#define lllim        2147483648

#define Pi           2*acos(0.0)

#define sci(n)	     scanf("%d",&n)

#define scii(n,m)    scanf("%d%d",&n,&m)

#define scl(n)       scanf("%lld",&n)

#define scll(n,m)    scanf("%lld%lld",&n,&m)

#define pii          pair<int,int>

#define pll 	     pair<ll,ll>

#define mem(a,b)     memset(a, b, sizeof(a))

#define fill_(a,b)   fill(a,a+n,b);

#define mod          1000000007ll

#define fast_cin     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define filein       freopen("input.txt","r", stdin)

#define D(x)         cerr << __LINE__ << ": " << #x << " = " << (x) << '\n'

#define case		 int t,cas=1;cin>>t;while(t--)

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

#define rev(i,n,a)   for(int i=n;i>=a;i--)



/*------------------------------Graph Moves----------------------------*/

//const int fx[]= {+1,-1,+0,+0};

//const int fy[]= {+0,+0,+1,-1};

//const int fx[]= {+0,+0,+1,-1,-1,+1,-1,+1};  // Kings Move

//const int fy[]= {-1,+1,+0,+0,+1,+1,-1,-1}; // Kings Move

//const int fx[]={-2, -2, -1, -1,  1,  1,  2,  2};  // Knights Move

//const int fy[]={-1,  1, -2,  2, -2,  2, -1,  1}; // Knights Move

/*---------------------------------------------------------------------*/



template<class T> void ckmin(T& a, const T& b) {

    a= b < a? b:a;

}

template<class T> void ckmax(T& a, const T& b) {

    a= b > a? b:a;

}



template<class T> void read(T& a) {

    std::cin>>a;

}



template<class T> void read(T& a, T& b) {

    std::cin>>a>>b;

}

template<class T> void read(T& a,T& b, T& c) {

    std::cin>>a>>b>>c;

}



template<class T> void read(T& ara, int sidx,  int eidx) {

    for(int i=sidx; i<eidx; i++)

        std::cin>>ara[i];

}









using namespace std;

using namespace __gnu_pbds;



const int maxn=100005;



///............................Number theory , si(), bigmod...................///

vector<int>pr;

ll bigmod(ll a, ll b, ll m);

void si();

///.................................Number theory end.........................///



vector<pii>adj[maxn];

int col[maxn];







void dfs(int u, int c, int p)

{

	col[u]=c;

	for(auto x: adj[u])

	{

		if(x.ff!=p)

		{

			int val=x.ss%2;

			if(val==0)

			{

				dfs(x.ff,c,u);

			}

			else

			{

				dfs(x.ff,1-c,u);

			}

		}

	}

}





void solve()

{

	

	int n;read(n);

	

	for(int i=0;i<n-1;i++)

	{

		int p,q,w;

		read(p,q);

		read(w);

		adj[p].pb({q,w});

		adj[q].pb({p,w});

	}	

	mem(col,-1);

	

	dfs(1,0,0);

	

	

	rep(i,1,n+1)

	{

		cout<<col[i]<<endl;

	}

	

	

	

}





int main()

{

    fast_cin;

    // si();



    //while(scanf("%d",&n)!=EOF)

//case

    {

        //cout<<""<<cas++<<""<<endl;

        solve();

    }



    return 0;

}















///............................Number theory , si(), bigmod...................///



bool mark[maxn];



void si()

{

    mem(mark,0);

    for(int i=4; i<maxn; i+=2) mark[i]=1;

    for(int i=3; i*i<maxn; i+=2)

    {

        if(!mark[i])

            for(int j=i*i; j<maxn; j+=2*i)

                mark[j]=1;

    }



    pr.pb(2);

    for(int i=3; i<maxn; i+=2)

        if(!mark[i])

            pr.pb(i);

}





ll bigmod(ll a, ll b, ll m)

{

    if(b==0) return 1;

    if(b==1) return a;



    if(b%2)

    {

        ll res=bigmod(a,b/2,m)%m;

        return ((((res%m)*(res%m))%m)*(a))%m;

    }

    else

    {

        ll res=bigmod(a,b/2,m)%m;

        return (((res%m)*(res%m))%m);

    }

}



///.................................Number theory end.........................///




// Optimized solution to the same problem (faster):
//#pragma GCC         optimize("O3")

#include            <bits/stdc++.h>

#include            <ext/pb_ds/assoc_container.hpp>

#include            <ext/pb_ds/tree_policy.hpp>

#define FastIO      ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0)

#define pb          push_back

#define mp          make_pair

#define mem(x,i)    memset(x,i,sizeof(x))

#define ff          first

#define ss          second

#define popcount(x) __builtin_popcount(x)

#define all(x)      x.begin(),x.end()

#define Case(t)     for(int ks=1;ks<=t;ks++)

#define fileout     freopen("output.txt","w",stdout)

#define filein      freopen("input.txt","r",stdin)

#define D(x)        cerr<< __LINE__ <<": "<< #x << " = "<<(x) <<'\n';

#define endl        '\n'



using namespace std;

using namespace __gnu_pbds;



using ll  = long long;

using ld  = long double;

using ull = unsigned long long;

using pii = pair<int,int>;

using pll = pair<ll,ll>;

using pil = pair<int,ll>;



const int INF    = 0x3f3f3f3f;

const ll LL_INF  = 0x3f3f3f3f3f3f3f3f;

const double PI  = acos(-1);

const double eps = 1e-4;

const int mod    = 1e9+7;

const int mx     = 100005;

template <typename T>  using orderedSet =

    tree<T, null_type, less_equal<T>,

    rb_tree_tag, tree_order_statistics_node_update>;//find_by_order,order_of_key*/



/*------------------------------Graph Moves----------------------------*/

//const int fx[]= {+1,-1,+0,+0};

//const int fy[]= {+0,+0,+1,-1};

//const int fx[]={+0,+0,+1,-1,-1,+1,-1,+1};   // Kings Move

//const int fy[]={-1,+1,+0,+0,+1,+1,-1,-1};  // Kings Move

//const int fx[]={-2, -2, -1, -1,  1,  1,  2,  2};  // Knights Move

//const int fy[]={-1,  1, -2,  2, -2,  2, -1,  1}; // Knights Move

/*---------------------------------------------------------------------*/



//ll powmod(ll a,ll b){ll res=1;a%=mod;assert(b>=0);for(; b; b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

/*----------------------BitMask-----------------------------------------*/

//inline int setBit(int N,int pos){return N=N | (1<<pos);}

//inline int resetBit(int N,int pos){return N= N & ~(1<<pos);}

//inline bool checkBit(int N,int pos){return (bool) (N& (1<<pos));}

int n;

vector<pii>adj[mx];

bool rong[mx];

void dfs(int u,int pa,int col)

{

    rong[u]=col;

    for(pii p:adj[u])

    {

        int v=p.ff;

        int c=p.ss;

        if(v!=pa)

        {

            dfs(v,u,(col+c)%2);

        }

    }

}

int main()

{

    cin>>n;

    for(int i=1;i<n;i++)

    {

        int u,v,w;

        cin>>u>>v>>w;

        adj[u].pb({v,w});

        adj[v].pb({u,w});

    }

    dfs(1,-1,0);

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

}


// Fastest known solution for this problem: