#include <bits/stdc++.h>
using namespace std;
;
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const long long INFLL = 0x3f3f3f3f3f3f3f3f;
set<int> s[maxn];
set<int>::iterator it;
struct EDGE {
  int v, nxt;
} edge[maxn << 1];
int tot;
int head[maxn];
int color[maxn];
void add_edge(int u, int v) {
  edge[tot].v = v;
  edge[tot].nxt = head[u];
  head[u] = tot++;
}
int ans;
void dfs(int pos, int pre) {
  if (pre == -1) {
    for (it = s[pos].begin(); it != s[pos].end(); it++) {
      color[*it] = ++ans;
    }
  } else {
    vector<int> used;
    for (it = s[pos].begin(); it != s[pos].end(); it++) {
      if (color[*it]) {
        used.push_back(color[*it]);
      }
    }
    int dis = 0;
    int now = 1;
    int len = used.size();
    sort(used.begin(), used.end());
    for (it = s[pos].begin(); it != s[pos].end(); it++) {
      if (color[*it] == 0) {
        while (dis < len) {
          if (used[dis] == now)
            now++, dis++;
          else
            break;
        }
        color[*it] = now++;
        ans = max(ans, now - 1);
      }
    }
  }
  for (int i = head[pos]; i != -1; i = edge[i].nxt) {
    if (edge[i].v != pre) {
      dfs(edge[i].v, pos);
    }
  }
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  tot = 0;
  memset(head, -1, sizeof(head));
  memset(color, 0, sizeof(color));
  int num;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &num);
    while (num--) {
      int kind;
      scanf("%d", &kind);
      s[i].insert(kind);
    }
  }
  for (int i = 1, u, v; i < n; i++) {
    scanf("%d%d", &u, &v);
    add_edge(u, v);
    add_edge(v, u);
  }
  ans = 0;
  dfs(1, -1);
  ans = max(1, ans);
  printf("%d\n", ans);
  for (int i = 1; i <= m; i++) {
    if (color[i] == 0)
      printf("1 ");
    else
      printf("%d ", color[i]);
  }
  printf("\n");
  return 0;
}
