#include <bits/stdc++.h>
inline void in(int &MAGNUS) { scanf("%d", &MAGNUS); }
inline void out(int MAGNUS) { printf("%d\n", MAGNUS); }
inline void in(int &MAGNUS, int &CLAR) { scanf("%d%d", &MAGNUS, &CLAR); }
inline void out(int MAGNUS, int CLAR) { printf("%d %d\n", MAGNUS, CLAR); }
inline void inl(long long &LIV) { scanf("%lld", &LIV); }
inline void inl(long long &LIV, long long &MART) {
  scanf("%lld%lld", &LIV, &MART);
}
inline void outl(long long LIV) { printf("%lld\n", LIV); }
inline void outl(long long LIV, long long MART) {
  printf("%lld %lld\n", LIV, MART);
}
using namespace std;
int N, M;
vector<int> graf[300005], tree[300005];
int col[300005];
void dfs(int u, int par) {
  set<int> used;
  for (int i = 0; i <= (int)graf[u].size() - 1; i++) {
    int v = graf[u][i];
    used.insert(col[v]);
  }
  int cur = 1;
  for (int i = 0; i <= (int)graf[u].size() - 1; i++) {
    int v = graf[u][i];
    while (used.count(cur)) cur++;
    if (col[v] == 0) {
      col[v] = cur;
      used.insert(cur);
    }
  }
  for (int i = 0; i <= (int)tree[u].size() - 1; i++) {
    int v = tree[u][i];
    if (v == par) continue;
    dfs(v, u);
  }
}
int main() {
  in(N, M);
  int ans = 1;
  for (int i = 1; i <= N; i++) {
    int s;
    in(s);
    for (int j = 1; j <= s; j++) {
      int u;
      in(u);
      graf[i].push_back(u);
    }
    ans = max(ans, s);
  }
  for (int i = 1; i <= N - 1; i++) {
    int u, v;
    in(u, v);
    tree[u].push_back(v);
    tree[v].push_back(u);
  }
  dfs(1, 0);
  out(ans);
  for (int i = 1; i <= M; i++) {
    if (col[i] == 0) col[i] = 1;
    printf("%d ", col[i]);
  }
  puts("");
  return 0;
}
