#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
template <typename T>
T &chmin(T &a, const T &b) {
  return a = min(a, b);
}
template <typename T>
T &chmax(T &a, const T &b) {
  return a = max(a, b);
}
template <typename T>
T inf;
template <>
constexpr int inf<int> = 1e9;
template <>
constexpr ll inf<ll> = 1e18;
template <>
constexpr ld inf<ld> = 1e30;
struct yes_no : numpunct<char> {
  string_type do_truename() const { return "Yes"; }
  string_type do_falsename() const { return "No"; }
};
int res[300010];
bool visited[300010];
vector<int> s[300010];
vector<int> g[300010];
void get_col(vector<int> &vec, int &pos, int &res) {
  ++res;
  while (pos < int(vec.size()) && vec[pos] == res) ++pos, ++res;
}
void dfs(int v) {
  vector<int> vec;
  for (int i : s[v]) {
    if (res[i] == 0) continue;
    vec.push_back(res[i]);
  }
  sort((vec).begin(), (vec).end());
  int pos = 0, col = 0;
  for (int i : s[v]) {
    if (res[i] != 0) continue;
    get_col(vec, pos, col);
    res[i] = col;
  }
  visited[v] = true;
  for (int i : g[v]) {
    if (visited[i]) continue;
    dfs(i);
  }
}
int main() {
  locale loc(locale(), new yes_no);
  cout << boolalpha;
  cout.imbue(loc);
  int n, k;
  scanf("%d%d", &n, &k);
  for (int i = 0; i < (int)(n); i++) {
    int sz, in;
    scanf("%d", &sz);
    for (int j = 0; j < (int)(sz); j++) {
      scanf("%d", &in);
      s[i].push_back(in - 1);
    }
  }
  for (int i = 0; i < (int)(n - 1); i++) {
    int from, to;
    scanf("%d%d", &from, &to);
    --from;
    --to;
    g[from].push_back(to);
    g[to].push_back(from);
  }
  dfs(0);
  for (int i = 0; i < (int)(k); i++) chmax(res[i], 1);
  int num = *max_element(res, res + k);
  cout << num << endl;
  for (int i = 0; i < (int)(k); i++) {
    printf("%d", res[i]);
    if (i == k - 1)
      printf("\n");
    else
      printf(" ");
  }
  return 0;
}
