#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!(ch >= '0' && ch <= '9')) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + (ch - '0');
    ch = getchar();
  }
  return x * f;
}
struct edge {
  int next, to;
} e[900500];
vector<int> v[900500];
int cnt, head[900500], size[900500], col[900500];
bool used[900500], vis[900500];
inline void ins(int u, int v) {
  e[++cnt].to = v;
  e[cnt].next = head[u];
  head[u] = cnt;
}
inline void insert(int u, int v) {
  ins(u, v);
  ins(v, u);
}
void dfs(int x) {
  int j = 1;
  vis[x] = 1;
  for (int i = 0; i < size[x]; i++) used[col[v[x][i]]] = 1;
  for (int i = 0; i < size[x]; i++)
    if (!col[v[x][i]]) {
      for (; used[j]; j++)
        ;
      used[col[v[x][i]] = j] = 1;
    }
  for (int i = 0; i < size[x]; i++) used[col[v[x][i]]] = 0;
  for (int i = head[x]; i; i = e[i].next)
    if (!vis[e[i].to]) dfs(e[i].to);
}
int main() {
  int n = read(), m = read(), ans = 0;
  for (int i = 1; i <= n; i++) {
    size[i] = read();
    for (int j = 1; j <= size[i]; j++) v[i].push_back(read());
    ans = max(ans, size[i]);
  }
  for (int i = 1; i < n; i++) insert(read(), read());
  printf("%d\n", ans ? ans : 1);
  dfs(1);
  for (int i = 1; i <= m; i++) printf("%d ", col[i] ? col[i] : 1);
  return 0;
}
