#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 3e5 + 10;
vector<long long> e[MAXN];
vector<long long> vertex[MAXN];
long long d[MAXN];
long long c[MAXN];
long long f = 0, t = 1;
bool check[MAXN];
bool tree_check[MAXN];
long long get_mex() {
  while (d[f] == t) {
    f++;
  }
  return f++;
}
void dfs(long long v) {
  check[v] = true;
  t++;
  f = 1;
  for (long long i = 0; i < e[v].size(); i++) {
    if (tree_check[e[v][i]]) {
      d[c[e[v][i]]] = t;
    }
  }
  for (long long i = 0; i < e[v].size(); i++) {
    if (!tree_check[e[v][i]]) {
      tree_check[e[v][i]] = true;
      c[e[v][i]] = get_mex();
    }
  }
  for (long long i = 0; i < vertex[v].size(); i++) {
    if (!check[vertex[v][i]]) {
      dfs(vertex[v][i]);
    }
  }
}
int main() {
  ios_base ::sync_with_stdio(false);
  cin.tie(0);
  long long n, m, res = 0;
  cin >> n >> m;
  for (long long i = 1; i <= n; i++) {
    long long s;
    cin >> s;
    for (long long j = 0; j < s; j++) {
      long long x;
      cin >> x;
      e[i].push_back(x);
    }
    res = max(res, s);
  }
  for (long long i = 0; i < (n - 1); i++) {
    long long v, u;
    cin >> v >> u;
    vertex[v].push_back(u);
    vertex[u].push_back(v);
  }
  dfs(1);
  cout << max(1LL, res) << endl;
  for (long long i = 1; i <= m; i++) {
    cout << max(1LL, c[i]) << " ";
  }
}
