#include <bits/stdc++.h>
using namespace std;
const int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
const int fxx[8][2] = {{0, 1}, {0, -1}, {1, 0},  {-1, 0},
                       {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
#pragma unused(fx)
#pragma unused(fxx)
template <typename T, typename TT>
ostream& operator<<(ostream& s, pair<T, TT> t) {
  return s << "(" << t.first << "," << t.second << ")";
}
template <typename T>
ostream& operator<<(ostream& s, vector<T> t) {
  for (int i = 0; i < (t).size(); i++)
    s << t[i] << ((i < (t).size() - 1) ? " " : "");
  return s;
}
int g1(int g) { return g % 3 + 1; }
int g2(int g) { return (g + 1) % 3 + 1; }
int main() {
  int(n), (m);
  scanf("%d %d", &(n), &(m));
  vector<int> col(n + 1);
  vector<vector<int> > edges(m, vector<int>(3));
  for (int i = 0; i < m; i++) {
    int(a), (b), (c);
    scanf("%d %d %d", &(a), &(b), &(c));
    edges[i][0] = a;
    edges[i][1] = b;
    edges[i][2] = c;
    if (col[a]) {
      col[b] = g1(col[a]);
      col[c] = g2(col[a]);
    } else if (col[b]) {
      col[a] = g1(col[b]);
      col[c] = g2(col[b]);
    } else if (col[c]) {
      col[a] = g1(col[c]);
      col[b] = g2(col[c]);
    } else {
      col[a] = 1;
      col[b] = 2;
      col[c] = 3;
    }
  }
  for (int i = 1; i < n + 1; i++)
    if (col[i] == 0) col[i] = 1;
  for (int i = 0; i < m; i++) {
    vector<int> e = edges[i];
    if (col[e[0]] == col[e[1]] || col[e[2]] == col[e[1]] ||
        col[e[2]] == col[e[0]])
      cout << "false" << i << "\n";
  }
  for (int i = 1; i < n + 1; i++) cout << col[i] << " ";
}
