#include <bits/stdc++.h>
using namespace std;
#define y1 hld
#define int long long
#define pii pair<int, int>
#define vi vector<int>
#define vii vector<pii>
#define fi first
#define se second
#define big (int)1e18
#define small (int)1e9
#define mouse (int)-1e18
#define cat (int)-1e9
#define pb push_back
#define eb emplace_back
struct tri {
    int u, v, w, i;
};
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define srt(x) sort(all(x));
#define bit(x, i) ((x >> i) & 1)
#define mask(i) (1LL << i)
#define saiz(x) (int)x.size()
#define uni(x) sort(all(x)), x.erase(unique(all(x)), x.end())
#define debug(x) cerr << x << ' '
#define debg(x) cerr << x << '\n'
#define deb(x, y) cerr << x << ' ' << y << '\n'
#define de(x, y, z) cerr << x << ' ' << y << ' ' << z << '\n'
#define htbd(x, y, z, t) cerr << x << ' ' << y << ' ' << z << ' ' << t << '\n'
template <class T>
using minheap = priority_queue<T, vector<T>, greater<T>>;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
int ceil_div(int a, int b) { return (a + b - 1) / b; }
#define fill0(x) memset(x, 0, sizeof x)
#define f36(x) memset(x, -1, sizeof x)
#define inf(x) memset(x, 0x3f, sizeof x)
#define nyc(x) memset(x, -0x3f, sizeof x)
#define loop(i, a, b) for (int i = (a); i <= (b); i++)
#define back(i, a, b) for (int i = (a); i >= (b); i--)
#define popcnt(x) __builtin_popcountll(x)
#define lb lower_bound
#define ub upper_bound
#define f59(a, b) a = min(a, b)
#define f69(a, b) a = max(a, b)
#define rep(i, n) for (int i = 1; i <= n; i++)
#define has(x, y) (x.find(y) != x.end())
#define each(x, a) for (auto &x : a)
#define lbit(x) (x & -x)
#define f(u, v) adj[u].push_back(v)
#define g(u, v, w) adj[u].push_back({v, w})
#define f2(u, v) (f(u, v), f(v, u))
#define g2(u, v, w) (g(u, v, w), g(v, u, w))
const int N = 2e5 + 5, M = 4e5 + 5;
int n, m;
tri e[M];
int sz[N], p[N], vs[N];
void init() {
    for (int i = 1; i <= n; i++) sz[i] = 1, p[i] = i;
}
int par(int i) {
    if (i == p[i]) return i;
    return par(p[i]);
}
#define uni unI
void uni(int u, int v) {
    u = par(u);
    v = par(v);
    if (u == v) return;
    if (sz[u] > sz[v]) swap(u, v);
    p[u] = v;
    sz[v] += sz[u];
}
int id[N], low[N], b[N];
vector<pii> adj[N];
int timer;
void dfs(int u, int d) {
    id[u] = low[u] = ++timer;
    for (pii v : adj[u]) {
        if (v.se == d) continue;
        if (id[v.fi] == 0)
            low[u] = min(low[u], id[v.fi]);
        else {
            dfs(v.fi, v.se);
            low[u] = min(low[u], low[v.fi]);
            if (low[v.fi] >= id[v.fi]) b[v.se] = 2;
        }
    }
}
signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= m; i++) cin >> e[i].u >> e[i].v >> e[i].w, e[i].i = i;
    sort(e + 1, e + m + 1, [&](tri a, tri b) { return a.w < b.w; });
    for (int i = 1; i <= m; i++) b[i] = 1;
    init();
    for (int l = 1; l <= m; l++) {
        int r = l;
        while (r < m && e[r + 1].w == e[l].w) r++;
        set<int> nd;
        loop(i, l, r) nd.insert(par(e[i].u)), nd.insert(par(e[i].v)),
            g2(par(e[i].u), par(e[i].v), e[i].i);
        loop(i, l, r) if (par(e[i].u) != par(e[i].v)) b[e[i].i] = 0;
        loop(i, l, r) uni(e[i].u, e[i].v);
        for (int i : nd) dfs(i, -1);
        for (int i : nd) id[i] = low[i] = 0;
        timer = 0;
        for (int i : nd) adj[i].clear();
    }
    loop(i, 1, m) cout << b[i];
}