#include <bits/stdc++.h>
using namespace std;
const int INF = 1001001001;
const long long INFLL = 1001001001001001001LL;
template <typename T>
void pv(T a, T b) {
  for (T i = a; i != b; ++i) cout << *i << " ";
  cout << endl;
}
template <typename T>
void chmin(T& a, T b) {
  if (a > b) a = b;
}
template <typename T>
void chmax(T& a, T b) {
  if (a < b) a = b;
}
int n, m, maxc;
vector<int> visited;
vector<int> color;
vector<vector<int>> s;
vector<vector<int>> e;
set<int> candidates;
int main() {
  cin >> n >> m;
  s.resize(n);
  for (int i = 0; i < n; i++) {
    int t;
    cin >> t;
    s[i].resize(t);
    for (int j = 0; j < t; j++) {
      int tt;
      cin >> tt;
      s[i][j] = tt - 1;
    }
    chmax(maxc, t);
  }
  e.resize(n);
  for (int i = 0; i < n - 1; i++) {
    int v, u;
    cin >> v >> u;
    v--;
    u--;
    e[v].push_back(u);
    e[u].push_back(v);
  }
  visited.resize(n);
  color.resize(m);
  for (int i = 1; i <= maxc; i++) {
    candidates.insert(i);
  }
  queue<int> bq;
  bq.push(0);
  visited[0] = true;
  while (!bq.empty()) {
    int v = bq.front();
    bq.pop();
    for (auto& c : s[v]) {
      if (color[c]) {
        candidates.erase(color[c]);
      }
    }
    for (auto& c : s[v]) {
      if (!color[c]) {
        color[c] = *candidates.begin();
        candidates.erase(color[c]);
      }
    }
    for (auto& c : s[v]) {
      candidates.insert(color[c]);
    }
    for (auto& w : e[v]) {
      if (!visited[w]) {
        bq.push(w);
        visited[w] = true;
      }
    }
  }
  for (int i = 0; i < m; i++) {
    if (color[i] == 0) color[i] = 1;
  }
  if (m > 0 && maxc == 0) maxc = 1;
  cout << maxc << endl << color[0];
  for (int i = 1; i < m; i++) {
    printf(" %d", color[i]);
  }
  cout << endl;
  return 0;
}
