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

#include <type_traits>

using namespace std;



using ll = int64_t;

#define int ll



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

#define REP(i, b) FOR(i, 0, b)

#define MP make_pair

#define PB push_back

#define EB emplace_back

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



using pi = pair<int, int>;

using vi = vector<int>;

using ld = long double;



template <class T, class U>

ostream &operator<<(ostream &os, const pair<T, U> &p) {

  os << "(" << p.first << "," << p.second << ")";

  return os;

}



template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {

  os << "{";

  REP(i, (int)v.size()) {

    if (i)

      os << ",";

    os << v[i];

  }

  os << "}";

  return os;

}



ll read() {

  ll i;

  scanf("%" SCNd64, &i);

  return i;

}



void printSpace() { printf(" "); }



void printEoln() { printf("\n"); }



void print(ll x, int suc = 1) {

  printf("%" PRId64, x);

  if (suc == 1)

    printEoln();

  if (suc == 2)

    printSpace();

}



string readString() {

  static char buf[3341000];

  scanf("%s", buf);

  return string(buf);

}



char *readCharArray() {

  static char buf[3341000];

  static int bufUsed = 0;

  char *ret = buf + bufUsed;

  scanf("%s", ret);

  bufUsed += strlen(ret) + 1;

  return ret;

}



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

  if (a < b)

    a = b;

}



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

  if (b < a)

    a = b;

}



template <class T> T Sq(const T &t) { return t * t; }



const int mod = 1e9 + 7;



const int maxN = 1e5 + 5;

int colors[maxN];

vector<pi> to[maxN];



void dfs(int id, int color, int pa) {

  colors[id] = color;

  for (auto &p : to[id])

    if (p.first != pa)

      dfs(p.first, (color ^ p.second), id);

}



signed main() {

  int n = read();

  REP(i, n - 1) {

    int u, v, w;

    u = read();

    v = read();

    w = read();

    to[u].EB(v, (w & 1));

    to[v].EB(u, (w & 1));

  }

  colors[1] = 0;

  dfs(1, colors[1], 0);

  FOR(i, 1, n + 1) std::cout << colors[i] << std::endl;

}


// Faster C++ solution for the same problem (measured speedup: 3.473187762301748x):
#include <bits/stdc++.h>

#include <type_traits>

using namespace std;



using ll = long long;



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

#define rrep(i, n) for (int i = 1; i <= (n); ++i)

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

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

#define srep(i, s, t) for (int i = s; i < t; ++i)

#define ssrep(i, s, t) for (int i = s; i <= t; ++i)



#define rng(a) a.begin(), a.end()

#define pb push_back

#define eb emplace_back

#define fi first

#define se second



#define chmax(x, y) (x = max(x, y))

#define chmin(x, y) (x = min(x, y))



using pi = pair<int, int>;

using vi = vector<int>;

using vvi = vector<vi>;

using vl = vector<ll>;

using vvl = vector<vl>;

using ld = long double;



template <class T, class U>

ostream &operator<<(ostream &os, const pair<T, U> &p) {

  os << "(" << p.first << "," << p.second << ")";

  return os;

}



template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {

  os << "{";

  rep(i, (int)v.size()) {

    if (i)

      os << ",";

    os << v[i];

  }

  os << "}";

  return os;

}



template <typename T, size_t S> void printArray(const T (&array)[S]) {

  for (auto val : array)

    std::cout << val << ", ";

  std::cout << "\n";

}



const int mod = 1e9 + 7;

const ll inf = 1e18 + 5;



struct UnionFind {

  vi parent, rank, count;

  UnionFind(const int nodeSize)

    : parent(nodeSize), rank(nodeSize, 1), count(nodeSize) {

    rep(i, nodeSize) parent[i] = i, count[i] = 1;

  }

  int find(int x) {

    if (parent[x] == x) return x;

    return parent[x] = find(parent[x]);

  }

  void unite(int x, int y) {

    int rx = find(x);

    int ry = find(y);

    if (rx == ry) return;

    if (rank[rx] < rank[ry]) swap(rx, ry);

    parent[ry] = rx;

    count[rx] += count[ry];

    if (rank[rx] == rank[ry]) ++rank[rx];

  }

  bool same(int x, int y) {

    return find(x) == find(y);

  }

  int num(int x) {

    return count[find(x)];

  }

};



struct Edge { int to, cost; };

vector<vector<Edge>> tree;

vl ans;

void dfs(int par, int now) {

  for (auto &edge : tree[now]) if (edge.to != par) {

    ans[edge.to] = ans[now] + edge.cost;

    dfs(now, edge.to);

  }

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << std::setprecision(10);



  int n; std::cin >> n;

  tree.resize(n);

  rep(i, n-1) {

    int u, v, w; std::cin >> u >> v >> w;

    u--, v--;

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

  }

  ans.resize(n);

  ans[0] = 0;

  dfs(-1, 0);

  rep(i, n) std::cout << (ans[i]&1) << "\n";

}