#include <iostream>
#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;

#define mindcoding mlc

const int MAXN = 100100;

int n, m, aib[MAXN];

struct interval {
    int x, y, val;
};

void update (int poz, int val) {
    while (poz <= n) {
        aib[poz] ^= val;
        poz += poz & (-poz);
    }
}

int query (int poz) {
    int sum = 0;
    while (poz > 0) {
        sum ^= aib[poz];
        poz -= poz & (-poz);
    }
    return sum;
}

interval mlg[MAXN];

int used[MAXN], next[MAXN], v[MAXN];
set<int> libere;

bool cmp(interval a, interval b) {
    return a.y - a.x < b.y - b.x;
}

int main() {
    //freopen("medium.in", "r", stdin);
    cin >> n >> m;

    for (int i = 1; i <= m; ++i)
        cin >> mlg[i].x >> mlg[i].y >> mlg[i].val;
    sort (mlg + 1, mlg + m + 1, cmp);

    for (int i = 1; i <= n; ++i)
        libere.insert(i);
    for (int i = 1; i <= m; ++i) {
        int x = mlg[i].x;
        int y = mlg[i].y;
        int curXor = mlg[i].val ^ (query(x - 1) ^ query(y));

        set<int>::iterator it1 = libere.lower_bound(x);
        set<int>::iterator it2 = libere.upper_bound(y);

        while (it1 != it2){
            int cur = *(it1);
            int islast = ((++it1) == it2);
            if (islast) {
                v[cur] = curXor;
                update(cur, curXor);
            }
            else {
                v[cur] = 1;
                update(cur, 1);
                curXor ^= 1;
            }
            libere.erase(cur);
        }
    }
    for (int i = 1; i <= n; ++i)
        cout << v[i] << " ";
    return 0;

}