object Main {

  case class Edge(v: Int, cost: Int)

  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)
    val N = sc.nextInt()
    val G = Array.fill(N)(new scala.collection.mutable.ArrayBuffer[Edge]())
    (0 until (N - 1)) foreach { _ =>
      val u, v, w = sc.nextInt()
      G(u-1).append(Edge(v-1, w))
      G(v-1).append(Edge(u-1, w))
    }

    // ある頂点をある色で塗ったとき,
    // そこから距離が偶数である頂点は同じ色となる
    // 1つは塗れるので、貪欲で一つずつ塗って行く
    // 白と黒を交互に塗っていくが, 二個前からの距離を保持しておいて
    // ちゃんとその距離が偶数かどうかを毎回チェックを入れる
    // 今回は必ず塗れるのでチェックは必要ない
    // ので、今回は適当な根を決めて交互に塗って行く
    def solve(): String = {
      val color = new Array[Int](N) // 1, -1, 0の時、色を塗っていないので訪れてもいない

      def dfs(u: Int): Unit = {
        G(u) foreach { edge =>
          if (color(edge.v) == 0) {
            color(edge.v) = -color(u)
            dfs(edge.v)
          }
        }
      }
      color(0) = 1
      dfs(0)
      color.map { c =>
        if (c == -1) 0
        else 1
      }.mkString("\n")
    }
    println(solve())
  }

}