// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



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

#define rloop(i,n) for(int i = int(n);i >= 0;i--)

#define range(i,a,b) for(int i = int(a);i <= int(b);i++)

#define SZ(c) int(c.size())

#define ALL(c) c.begin(), c.end()

#define RALL(c) c.rbegin(), c.rend()

#define PI acos(-1)

#define pb push_back

#define mp make_pair

#define fr first

#define sc second

#define sfi1(v) scanf("%d",&v)

#define sfi2(v1,v2) scanf("%d %d",&v1,&v2)

#define sfi3(v1,v2,v3) scanf("%d %d %d",&v1,&v2,&v3)

#define sfll1(v) scanf("%I64d",&v);

#define sfll2(v1,v2) scanf("%I64d %I64d",&v1,&v2)

#define sfll3(v1,v2,v3) scanf("%I64d %I64d %I64d",&v1,&v2,&v3)

#define endl '\n'



typedef vector<int> vi;

typedef vector<pair<int,int> > vii;

typedef long long ll;

typedef pair<int, int> pii;



const int N = 1e5 + 5;

vi adj[N];

int p[N] , w[N];

int n;



int f(int u){

    if(u == p[u])return u;

    return p[u] = f(p[u]);

}



bool is_connected(int a , int b){

    return f(a) == f(b);

}



void connect(int a , int b){

    a = f(a);

    b = f(b);

    if(a == b)return;

    if(w[a] < w[b])swap(a,b);

    w[a] += w[b];

    p[b] = a;

}



void init(){

    for(int i = 0 ; i < N ; i++)

        p[i] = i , w[i] = 1;

}



int main()

{



#ifndef ONLINE_JUDGE

	//freopen("in.in", "r", stdin);

	//freopen("out.in", "w", stdout);

#endif

	ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);



    init();

    vii edges;

    int n , u , v, c;

    cin >> n;

    vi ans(n , -1);

    loop(i,n-1){

        cin >> u >> v >> c;

        u-- , v--;

        if(c&1)edges.pb({u,v});

        else connect(u,v);

    }



    for(auto edge : edges){

        //cout << f(edge.fr) << " " << f(edge.sc) << endl;

        adj[f(edge.fr)].pb(f(edge.sc));

        adj[f(edge.sc)].pb(f(edge.fr));

    }





    queue<int> q;

    ans[f(0)] = 0;

    q.push(f(0));

    while(!q.empty()){

        int u = q.front();

        q.pop();

        for(int nxt : adj[u]){

            if(ans[nxt] == -1){

                ans[nxt] = 1 - ans[u];

                q.push(nxt);

            }

        }

    }



    loop(i,n)cout << ans[f(i)] << endl;





    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.2396599706532319x):
/*بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيم*/



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

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



#include <bits/stdc++.h>

using namespace std;

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

typedef long long ll;

const double PI = acos(-1.0);

const ll mod = 1e9 + 7;

//const ll mod = 998244353;





inline void normal(ll &a) { a %= mod; (a < 0) && (a += mod); }

inline ll modMul(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a * b) % mod; }

inline ll modAdd(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a + b) % mod; }

inline ll modSub(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); a -= b; normal(a); return a; }

inline ll modPow(ll b, ll p) { ll r = 1; while (p) { if (p & 1) r = modMul(r, b); b = modMul(b, b); p >>= 1; } return r; }

inline ll modInverse(ll a) { return modPow(a, mod - 2); }

inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }



#define si(x) scanf("%d",&x)

#define sii(x,y) scanf("%d %d",&x,&y)

#define siii(x,y,z) scanf("%d %d %d",&x,&y,&z)

#define sl(x) scanf("%lld",&x)

#define sll(x,y) scanf("%lld %lld",&x,&y)

#define slll(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)

#define ss(ch) scanf("%s",ch)

#define pi(x) printf("%d",x)

#define pii(x,y) printf("%d %d",x,y)

#define piii(x,y,z) printf("%d %d %d",x,y,z)

#define pl(x) printf("%lld",x)

#define pll(x,y) printf("%lld %lld",x,y)

#define plll(x,y,z) printf("%lld %lld %lld",x,y,z)

#define ps(ch) printf("%s",ch)

#define F(i,a,b)      for(int i= a; i <= b; i++)

#define R(i,b,a)      for(int i= b; i >= a; i--)



int dx[]  = {0, 0, 1, -1};

int dy[]  = {1, -1, 0, 0};

int dx8[] = {0, 0, 1, 1, 1, -1, -1, -1};

int dy8[] = {1, -1, -1, 0, 1, -1, 0, 1};

int kx8[] = {1, 1, 2, 2, -1, -1, -2, -2};

int ky8[] = {2, -2, 1, -1, 2, -2, 1, -1};

/* for Random Number generate

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

*/

///**

template < typename F, typename S >ostream& operator << ( ostream& os, const pair< F, S > & p ) {return os << "(" << p.first << ", " << p.second << ")";}

template < typename T >ostream &operator << ( ostream & os, const vector< T > &v ) {os << "{"; for (auto it = v.begin(); it != v.end(); ++it) {if ( it != v.begin() ) os << ", "; os << *it;} return os << "}";}

template < typename T >ostream &operator << ( ostream & os, const set< T > &v ) {os << "["; for (auto it = v.begin(); it != v.end(); ++it) {if ( it != v.begin()) os << ", "; os << *it;} return os << "]";}

template < typename F, typename S >ostream &operator << ( ostream & os, const map< F, S > &v ) {os << "["; for (auto it = v.begin(); it != v.end(); ++it) {if ( it != v.begin() ) os << ", "; os << it -> first << " = " << it -> second ;} return os << "]";}

#define dbg(args...) do {cerr << #args << " : "; faltu(args); } while(0)

clock_t tStart = clock();

#define timeStamp dbg("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)

void faltu () { cerr << endl; }

template <typename T>void faltu( T a[], int n ) {for (int i = 0; i < n; ++i) cerr << a[i] << ' '; cerr << endl;}

template <typename T, typename ... hello>

void faltu( T arg, const hello &... rest) { cerr << arg << ' '; faltu(rest...); }



// Program showing a policy-based data structure.

#include <ext/pb_ds/assoc_container.hpp> // Common file 

#include <ext/pb_ds/tree_policy.hpp>

#include <functional> // for less 

using namespace __gnu_pbds;



// GNU link : https://goo.gl/WVDL6g

typedef tree<int, null_type, less_equal<int>, rb_tree_tag,

        tree_order_statistics_node_update>

        new_data_set;

// find_by_order(k) – ফাংশনটি kth ordered element এর একটা পয়েন্টার রিটার্ন করে। অর্থাৎ তুমি চাইলেই kth ইন্ডেক্সে কি আছে, সেটা জেনে ফেলতে পারছো!

// order_of_key(x) – ফাংশনটি x এলিমেন্টটা কোন পজিশনে আছে সেটা বলে দেয়।

//*//**___________________________________________________**/

const int N = 100006;

vector<pair<int, int>> g[N];

bool vis[N];

int n;

int color[N], dis[N];



void bfs(int s)

{

  queue<pair<int, int>> Q;

  Q.push({s, 0});

  vis[s] = true;

  dis[s] = 0;

  while (!Q.empty()) {

    auto it = Q.front();

    Q.pop();

    int u = it.first;

    //int P = it.second;

    for (auto it : g[u]) {

      int v = it.first;

      int x = it.second;

      if (vis[v])continue;

      vis[v] = true;

      dis[v] = dis[u] + x;

      dis[v] &= 1;

      //dbg(v);

      if ((dis[v] & 1) != (dis[u] & 1))

        color[v] = 1 - color[u];

      else color[v] = color[u];

      Q.push({v, dis[v]});

    }

  }

}



int main()

{

  FASTIO

  /*

#ifndef ONLINE_JUDGE

  freopen("in.txt", "r", stdin);

  freopen("out.txt", "w", stdout);

  freopen("error.txt", "w", stderr);

#endif

//*/

  int T;

  T = 1;

  //scanf("%d", &T);

  for (int cs = 1; cs <= T; cs++) {

    cin >> n;



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

      int a, b, c;

      cin >> a >> b >> c;

      g[a].push_back({b, c & 1});

      g[b].push_back({a, c & 1});

    }

    bfs(1);

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

      cout << color[i] << "\n";

  }

  return 0;

}