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

using namespace std;
const int N = 100010;
int n, m, componentNumber[2 * N], currentNumber, sol[N];
vector<int> forwardSuccessor[2 * N], backwardSuccessor[2 * N], currentComponent;
bitset<N> used;
stack<int> st;
void forwardDfs(int), backwardDfs(int);
int main() {
    cin >> n >> m;
    for (; m; m--) {
        int x, y, z;
        cin >> x >> y >> z;
        --x, --y;
        if (z) {
            x = 2 * x;
            y = 2 * y + 1;
        } else {
            x = 2 * x + 1;
            y = 2 * y;
        }
        forwardSuccessor[x].push_back(y);
        backwardSuccessor[y].push_back(x);
    }
    n *= 2;
    for (int i = 0; i < n; i++)
        if (!used[i]) forwardDfs(i);
    do {
        while (st.size() && componentNumber[st.top()]) st.pop();
        if (st.size()) {
            currentNumber++;
            int x = st.top();
            currentComponent.resize(0);
            backwardDfs(x);
            int val;
            if (currentComponent.size() > 1)
                val = 1;
            else
                val = 0;
            for (auto it : currentComponent) sol[it / 2] |= val;
        }
    } while (st.size());
    n /= 2;
    for (int i = 0; i < n; i++) cout << sol[i];
    cout << '\n';
    return 0;
}
void forwardDfs(int node) {
    used[node] = 1;
    for (auto successor : forwardSuccessor[node])
        if (!used[successor]) forwardDfs(successor);
    st.push(node);
}
void backwardDfs(int node) {
    currentComponent.push_back(node);
    componentNumber[node] = currentNumber;
    for (auto successor : backwardSuccessor[node])
        if (!componentNumber[successor]) backwardDfs(successor);
}