"use strict";

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }

function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }

!function () {
  function splitNum(line) {
    return (Array.isArray(line) ? line : line.split(/\s+/)).map(function (n) {
      return parseInt(n);
    });
  }

  function runRecursive(func) {
    var rootCaller = {
      lastReturnValue: null
    };
    var callStack = [];

    for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      args[_key - 1] = arguments[_key];
    }

    callStack.push({
      iterator: func.apply(void 0, args),
      lastReturnValue: null,
      caller: rootCaller
    });

    for (; callStack.length > 0;) {
      var stackFrame = callStack[callStack.length - 1];
      var iterator = stackFrame.iterator,
          lastReturnValue = stackFrame.lastReturnValue,
          caller = stackFrame.caller;

      var _iterator$next = iterator.next(lastReturnValue),
          value = _iterator$next.value,
          done = _iterator$next.done;

      if (done) {
        caller.lastReturnValue = value;
        callStack.pop();
      } else callStack.push({
        iterator: func.apply(void 0, _toConsumableArray(value)),
        lastReturnValue: null,
        caller: stackFrame
      });
    }

    return rootCaller.lastReturnValue;
  }

  !function (input) {
    var lines = input.split("\n");

    var _splitNum = splitNum(lines[0]),
        _splitNum2 = _slicedToArray(_splitNum, 1),
        N = _splitNum2[0];

    var edges = lines.slice(1, N).map(function (line) {
      var _splitNum3 = splitNum(line),
          _splitNum4 = _slicedToArray(_splitNum3, 3),
          u = _splitNum4[0],
          v = _splitNum4[1],
          w = _splitNum4[2];

      return {
        u: u,
        v: v,
        w: w
      };
    });
    var vs = new Array(N + 1).fill(null).map(function () {
      return [];
    });
    var _iteratorNormalCompletion = true;
    var _didIteratorError = false;
    var _iteratorError = undefined;

    try {
      for (var _iterator = edges[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
        var edge = _step.value;
        var u = edge.u,
            v = edge.v,
            w = edge.w;
        vs[u].push({
          to: v,
          w: w
        });
        vs[v].push({
          to: u,
          w: w
        });
      }
    } catch (err) {
      _didIteratorError = true;
      _iteratorError = err;
    } finally {
      try {
        if (!_iteratorNormalCompletion && _iterator.return != null) {
          _iterator.return();
        }
      } finally {
        if (_didIteratorError) {
          throw _iteratorError;
        }
      }
    }

    var result = new Array(N + 1).fill(-1);
    runRecursive(function* (index, color) {
      result[index] = color;
      var _iteratorNormalCompletion2 = true;
      var _didIteratorError2 = false;
      var _iteratorError2 = undefined;

      try {
        for (var _iterator2 = vs[index][Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
          var _step2$value = _step2.value,
              to = _step2$value.to,
              w = _step2$value.w;

          if (-1 === result[to]) {
            var nextColor = w % 2 == 0 ? color : 1 - color;
            yield [to, nextColor];
          }
        }
      } catch (err) {
        _didIteratorError2 = true;
        _iteratorError2 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
            _iterator2.return();
          }
        } finally {
          if (_didIteratorError2) {
            throw _iteratorError2;
          }
        }
      }
    }, 1, 0);
    console.log(result.slice(1).join("\n"));
  }(require("fs").readFileSync("/dev/stdin", "utf8"));
}();
