#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 10;
int n, m, size[maxn], sum, avg, ted;
vector<int> v[maxn];
vector<pair<pair<int, int>, int> > ans;
set<int> S;
unordered_map<long long, bool> have;
bool cmp(int a, int b) { return size[a] < size[b]; }
int32_t main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%d", size + i);
    sum += size[i];
    for (int j = 0; j < size[i]; j++) {
      int a;
      scanf("%d", &a);
      a--;
      have[1ll * i * maxn + 1ll * a] = 1;
      v[a].push_back(i);
    }
  }
  avg = (sum / n);
  for (int i = 0; i < n; i++) {
    if (size[i] < avg) {
      S.insert(i);
    }
  }
  for (int i = 0; i < m; i++) {
    sort(v[i].begin(), v[i].end(), cmp);
    if (S.size()) {
      for (auto it = S.begin(); it != S.end();) {
        int pos = (*it);
        it++;
        if (v[i].empty() || size[v[i].back()] <= avg + 1) break;
        if (!have[1ll * pos * maxn + 1ll * i]) {
          size[pos]++;
          have[1ll * pos * maxn + 1ll * i] = 1;
          size[v[i].back()]--;
          ans.push_back({{v[i].back(), pos}, i});
          if (size[pos] == avg) {
            S.erase(pos);
          }
          v[i].pop_back();
        }
      }
    }
  }
  if (S.size()) {
    for (int i = 0; i < m; i++) {
      sort(v[i].begin(), v[i].end(), cmp);
      if (S.size()) {
        for (auto it = S.begin(); it != S.end();) {
          int pos = (*it);
          it++;
          if (v[i].empty() || size[v[i].back()] <= avg) break;
          if (!have[1ll * pos * maxn + 1ll * i]) {
            have[1ll * pos * maxn + 1ll * i] = 1;
            size[pos]++;
            size[v[i].back()]--;
            ans.push_back({{v[i].back(), pos}, i});
            if (size[pos] >= avg) {
              S.erase(pos);
            }
            v[i].pop_back();
          }
        }
      }
    }
  } else {
    for (int i = 0; i < n; i++) {
      if (size[i] <= avg) {
        S.insert(i);
      }
    }
    for (int i = 0; i < m; i++) {
      sort(v[i].begin(), v[i].end(), cmp);
      if (S.size()) {
        for (auto it = S.begin(); it != S.end();) {
          int pos = (*it);
          it++;
          if (v[i].empty() || size[v[i].back()] <= avg + 1) break;
          if (!have[1ll * pos * maxn + 1ll * i]) {
            have[1ll * pos * maxn + 1ll * i] = 1;
            size[pos]++;
            size[v[i].back()]--;
            ans.push_back({{v[i].back(), pos}, i});
            if (size[pos] >= avg + 1) {
              S.erase(pos);
            }
            v[i].pop_back();
          }
        }
      }
    }
  }
  printf("%d\n", int(ans.size()));
  for (pair<pair<int, int>, int> x : ans) {
    printf("%d %d %d\n", x.first.first + 1, x.first.second + 1, x.second + 1);
  }
}
