#include <bits/stdc++.h>
using namespace std;
struct TREE_NODE {
  vector<int> types;
  vector<int> adj;
};
TREE_NODE tree[300005];
int color[300005];
bool colorvis[300005];
int colornum;
int n, m;
void dfs(int current, int parent) {
  const TREE_NODE& node = tree[current];
  int c = 1;
  for (int t : node.types) {
    if (color[t]) colorvis[color[t]] = true;
  }
  for (int t : node.types) {
    if (!color[t]) {
      while (colorvis[c]) ++c;
      color[t] = c;
      colorvis[c] = true;
      colornum = max(colornum, c);
    }
  }
  for (int t : node.types) colorvis[color[t]] = false;
  for (int child : node.adj) {
    if (child != parent) dfs(child, current);
  }
}
int main(int argc, char* argv[]) {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    int s;
    scanf("%d", &s);
    while (s--) {
      int t;
      scanf("%d", &t);
      tree[i].types.push_back(t);
    }
    sort(tree[i].types.begin(), tree[i].types.end());
  }
  for (int i = 0; i < (n - 1); ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    tree[u].adj.push_back(v);
    tree[v].adj.push_back(u);
  }
  colornum = 1;
  dfs(1, -1);
  printf("%d\n", colornum);
  for (int i = 1; i <= m; ++i) {
    if (i > 1) putchar(' ');
    if (color[i] == 0) color[i] = 1;
    printf("%d", color[i]);
  }
  putchar('\n');
  return 0;
}
