// costel_cycle.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;
    }
};

void dfs(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(it, graph, vis, order);
        }
    }
    order.push_back(node);
}

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

vector<bool> solve_cycle(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);
    vector<bool> has_self_loop(N);

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

    int cnt_blue = 0;
    for (const Edge &edge : edges) {
        const int a = edge.a;
        const int b = edge.b;
        const Color c = edge.c;
        if (c == Color::Red) {
            add_edge(a, (b + 1) % N);
        } else {
            assert((a + 1) % N == b);
            ++cnt_blue;
        }
    }
    assert(cnt_blue == N);

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

    fill(vis.begin(), vis.end(), false);
    vector<bool> ans(N);
    for (int i = N - 1; i >= 0; --i) {
        if (!vis[order[i]]) {
            vector<int> scc;
            inv_dfs(order[i], scc, 0, inv_graph, vis);
            if (scc.size() > 1 || has_self_loop[scc[0]]) {
                for (auto it : scc) {
                    ans[it] = true;
                    ans[(it + N - 1) % N] = true;
                }
            }
        }
    }
    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_cycle(g));
    return 0;
}