#include <bits/stdc++.h>
using namespace std;
int n, m, sum;
int Need[100005], Order[100005];
set<int> Presents[100005], Have[100005];
vector<pair<pair<int, int>, int> > Op;
priority_queue<pair<int, int> > pq;
bool Compare(int x, int y) { return Presents[x].size() < Presents[y].size(); }
void Add(int id) {
  if ((int)Presents[id].size() < Need[id])
    pq.push(make_pair(Need[id] - Presents[id].size(), id));
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    Order[i] = i;
    int sz;
    cin >> sz;
    sum += sz;
    while (sz--) {
      int tmp;
      cin >> tmp;
      Presents[i].insert(tmp);
      Have[tmp].insert(i);
    }
  }
  sort(Order + 1, Order + n + 1, Compare);
  for (int i = 0; i < sum; i++) {
    ++Need[Order[n - i % n]];
  }
  for (int i = 1; i <= n; i++) {
    Add(i);
  }
  for (int i = 1; i <= m; i++) {
    vector<int> Move;
    for (auto x : Have[i]) {
      if (Presents[x].size() <= Need[x]) {
        continue;
      }
      while (pq.empty() == false) {
        if (Have[i].count(pq.top().second) or
            pq.top().first !=
                Need[pq.top().second] - Presents[pq.top().second].size()) {
          pq.pop();
          continue;
        }
        Op.emplace_back(make_pair(x, pq.top().second), i);
        Presents[x].erase(i);
        Presents[pq.top().second].insert(i);
        Move.emplace_back(pq.top().second);
        pq.pop();
        break;
      }
    }
    for (auto x : Have[i]) {
      Add(x);
    }
    for (auto x : Move) {
      Add(x);
    }
  }
  cout << Op.size() << '\n';
  for (auto x : Op) {
    cout << x.first.first << ' ' << x.first.second << ' ' << x.second << '\n';
  }
}
