#include <bits/stdc++.h>
using namespace std;
const int N = 300002;
int n, m, mx, ans[N], mxCompColor[N], parent[N];
vector<vector<int> > a(N);
bool intersection[N];
int find(int a) { return parent[a] == a ? a : parent[a] = find(parent[a]); }
void merge(int a, int b) { parent[find(a)] = parent[find(b)]; }
int main() {
  scanf("%d%d", &n, &m);
  for (int i = (1); i <= (int)(m); ++i) parent[i] = i;
  for (int i = (1); i <= (int)(n); ++i) {
    int second;
    scanf("%d", &second);
    mx = max(mx, second);
    int first;
    if (second) {
      scanf("%d", &first);
      if (second > 1) intersection[first] = true;
    }
    for (int j = (1); j <= (int)(second - 1); ++j) {
      int x;
      scanf("%d", &x);
      a[i].push_back(x);
      merge(x, first);
      if (second > 1) intersection[x] = true;
    }
  }
  for (int i = (1); i <= (int)(m); ++i)
    if (intersection[i]) ans[i] = ++mxCompColor[find(i)];
  for (int i = (1); i <= (int)(n); ++i) {
    int c = 1;
    set<int> present;
    for (int j : a[i])
      if (ans[j]) present.insert(j);
    for (int j : a[i])
      if (!ans[j]) {
        while (present.find(c) != present.end()) ++c;
        ans[j] = c;
      }
  }
  cout << (max(1, mx)) << endl;
  for (int i = (1); i <= (int)(m); ++i) printf("%d ", max(1, ans[i]));
}
