#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 7;
const int N = 2e6 + 5;
struct S {
  int type, next;
} s[N];
int sHead[N];
struct Edge {
  int to, next;
} edge[N];
int head[N];
inline void addEdge(int k, int u, int v) {
  edge[k].to = v;
  edge[k].next = head[u];
  head[u] = k;
}
inline void add(int k, int u, int v) {
  s[k].type = v;
  s[k].next = sHead[u];
  sHead[u] = k;
}
int col[N];
int colNum = 0;
bool vis[N];
bool used[N];
int sSize[N];
void dfs(int u) {
  vis[u] = true;
  int colIdx = 1;
  fill(used, used + sSize[u] + 1, false);
  for (int i = sHead[u]; i != -1; i = s[i].next) {
    int type = s[i].type;
    if (col[type] != -1) {
      used[col[type]] = true;
    }
  }
  for (int i = sHead[u]; i != -1; i = s[i].next) {
    int type = s[i].type;
    if (col[type] == -1) {
      while (used[colIdx]) {
        ++colIdx;
      }
      col[type] = colIdx;
      used[colIdx] = true;
    }
    colNum = max(colNum, colIdx);
  }
  for (int i = head[u]; i != -1; i = edge[i].next) {
    int v = edge[i].to;
    if (vis[v] == false) {
      dfs(v);
    }
  }
}
int main() {
  int n, m;
  while (~scanf("%d%d", &n, &m)) {
    fill(head, head + n + 1, -1);
    fill(sHead, sHead + n + 1, -1);
    fill(col, col + m + 1, -1);
    fill(vis, vis + n + 1, false);
    colNum = 0;
    int nume = 0;
    for (int i = 1; i <= n; ++i) {
      int num;
      scanf("%d", &num);
      sSize[i] = num;
      while (num--) {
        int type;
        scanf("%d", &type);
        add(nume++, i, type);
      }
    }
    nume = 0;
    for (int i = 0; i < n - 1; ++i) {
      int u, v;
      scanf("%d%d", &u, &v);
      addEdge(nume++, u, v);
      addEdge(nume++, v, u);
    }
    for (int i = 1; i <= n; ++i) {
      if (vis[i] == false) {
        dfs(i);
      }
    }
    if (col[1] == -1) {
      col[1] = 1;
    }
    colNum = max(1, colNum);
    printf("%d\n%d", colNum, col[1]);
    for (int i = 2; i <= m; ++i) {
      col[i] = max(1, col[i]);
      printf(" %d", col[i]);
    }
    putchar('\n');
  }
  return 0;
}
