// costel_small_ctc.cpp
#include <bits/stdc++.h>

using namespace std;

class Color {
   public:
    Color(bool _value) : value(_value) {}

    static constexpr bool Red = false;
    static constexpr bool Blue = true;

    operator bool() const { return value; }
    operator bool &() { return value; }

   private:
    bool value;
};

struct Edge {
    int a, b;
    Color c;

    explicit Edge(int _a = -1, int _b = -1, Color _c = Color::Red)
        : a(_a), b(_b), c(_c) {}

    friend istream &operator>>(istream &i, Edge &e) {
        bool color;
        i >> e.a >> e.b >> color;
        --e.a, --e.b;
        e.c = (color == 0) ? Color::Red : Color::Blue;
        return i;
    }
};

struct Graph {
    int N;
    vector<Edge> edges;

    Graph() : N(-1) {}
    Graph(int _N) : N(_N) {}

    int M() const { return edges.size(); }

    friend istream &operator>>(istream &i, Graph &g) {
        int M;
        i >> g.N >> M;
        g.edges.resize(M);
        for (int j = 0; j < M; ++j) {
            i >> g.edges[j];
        }
        return i;
    }
};

bool dfs(const int node, const Color parity, const int init,
         const Color init_color, vector<vector<int>> &vis,
         vector<vector<pair<int, Color>>> &graph, const int round,
         vector<int> &which_scc) {
    vis[parity][node] = round;
    for (const auto &it : graph[node]) {
        const int b = it.first;
        const Color c = it.second;
        if (which_scc[node] != which_scc[b]) {
            continue;
        }
        if (c == parity) {
            if (b == init && parity != init_color) {
                return true;
            }
            if (vis[parity ^ 1][b] < round &&
                dfs(b, parity ^ 1, init, init_color, vis, graph, round,
                    which_scc)) {
                return true;
            }
        }
    }
    return false;
}

void dfs_scc(const int node, const vector<vector<int>> &graph,
             vector<bool> &vis, vector<int> &order) {
    vis[node] = true;
    for (const auto it : graph[node]) {
        if (!vis[it]) {
            dfs_scc(it, graph, vis, order);
        }
    }
    order.push_back(node);
}

void inv_dfs_scc(const int node, vector<vector<int>> &graph, vector<bool> &vis,
                 const int cnt_scc, vector<int> &which_scc) {
    vis[node] = true;
    which_scc[node] = cnt_scc;
    for (const auto it : graph[node]) {
        if (!vis[it]) {
            inv_dfs_scc(it, graph, vis, cnt_scc, which_scc);
        }
    }
};

vector<int> get_sccs(const Graph &g) {
    const int N = g.N;
    const int M = g.M();
    const vector<Edge> &edges = g.edges;

    vector<vector<int>> graph(N);
    vector<vector<int>> inv_graph(N);

    const auto add_edge = [&graph, &inv_graph](const int a, const int b) {
        graph[a].push_back(b);
        inv_graph[b].push_back(a);
    };

    for (const Edge &edge : edges) {
        const int a = edge.a;
        const int b = edge.b;
        add_edge(a, b);
    }

    vector<bool> vis(N);
    vector<int> order;
    order.reserve(N);
    for (int i = 0; i < N; ++i) {
        if (!vis[i]) {
            dfs_scc(i, graph, vis, order);
        }
    }

    vector<int> which_scc(N);
    fill(vis.begin(), vis.end(), false);
    int cnt_scc = 0;
    for (int i = N - 1; i >= 0; --i) {
        if (!vis[order[i]]) {
            ++cnt_scc;
            inv_dfs_scc(order[i], inv_graph, vis, cnt_scc, which_scc);
        }
    }
    return which_scc;
}

vector<bool> solve_brute(const Graph &g) {
    const int N = g.N;
    const int M = g.M();
    const vector<Edge> &edges = g.edges;

    vector<vector<pair<int, Color>>> graph(N);
    for (const Edge &edge : edges) {
        const int a = edge.a;
        const int b = edge.b;
        const Color c = edge.c;
        graph[a].emplace_back(b, c);
    }

    vector<vector<int>> vis(2, vector<int>(N, 0));
    vector<bool> ans(N);
    int round = 0;

    vector<int> which_scc = get_sccs(g);
    for (int i = 0; i < N; ++i) {
        ++round;
        ans[i] =
            dfs(i, Color::Red, i, Color::Red, vis, graph, round, which_scc);
    }
    for (int i = 0; i < N; ++i) {
        if (!ans[i]) {
            ++round;
            ans[i] = dfs(i, Color::Blue, i, Color::Blue, vis, graph, round,
                         which_scc);
        }
    }
    return ans;
}

void print_sol(ostream &o, const vector<bool> &sol) {
    for (int i = 0; i < static_cast<int>(sol.size()); ++i) {
        o << sol[i];
    }
    o << '\n';
}

int main() {
    Graph g;
    cin >> g;
    print_sol(cout, solve_brute(g));
    return 0;
}