#include <bits/stdc++.h>
using namespace std;
const double EPSILON = 10E-7;
struct tpos {
  int x, y, z;
  tpos(int a, int b) : x(a), y(b) {}
  tpos(int a, int b, int c) : x(a), y(b), z(c) {}
  tpos() : x(0), y(0), z(0) {}
};
int MOD(int a, int d) { return ((a % d) + d) % d; }
auto cmp = [](const tpos &v, const tpos &w) { return (v.y > w.y); };
const int MAXN = 2000010;
const long long int MODC = 1000000007;
vector<int> icecream[300050];
vector<int> edges[300050];
int color[300050];
bool used[500050];
bool visited[300050];
vector<int> vu;
void dfs(int v) {
  visited[v] = true;
  for (auto ic : icecream[v]) {
    if (color[ic])
      used[color[ic]] = true;
    else
      vu.push_back(ic);
  }
  int c = 1;
  for (auto ic : vu) {
    while (used[c]) c++;
    color[ic] = c++;
  }
  for (auto it : icecream[v]) used[color[it]] = false;
  vu.clear();
  for (auto u : edges[v]) {
    if (visited[u]) continue;
    dfs(u);
  }
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) {
    int s;
    scanf("%d", &s);
    for (int j = 0; j < s; j++) {
      int x;
      scanf("%d", &x);
      icecream[i].push_back(x);
    }
  }
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    edges[u].push_back(v);
    edges[v].push_back(u);
  }
  dfs(1);
  int maxc = 0;
  for (int i = 1; i <= m; i++) {
    if (color[i] == 0) color[i] = 1;
    maxc = max(maxc, color[i]);
  }
  printf("%d\n", maxc);
  for (int i = 1; i <= m; i++) {
    printf("%d ", color[i]);
  }
  printf("\n");
  return 0;
}
