#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100007;
set<int> st[MAXN];
pair<int, int> pr[MAXN];
int target[MAXN];
int rmap[MAXN];
struct nd {
  int from, to, item;
};
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int tot = 0;
  for (int i = 1; i <= n; i++) {
    int s;
    cin >> s;
    pr[i].first = s;
    pr[i].second = i;
    tot += s;
    while (s--) {
      int x;
      cin >> x;
      st[i].insert(x);
    }
  }
  sort(pr + 1, pr + n + 1);
  for (int i = 1; i <= n; i++) {
    rmap[pr[i].second] = i;
  }
  set<pair<int, int> > fcuk;
  int x = 0;
  for (int i = 1; i <= n; i++) {
    target[i] = tot / (n + 1 - i);
    tot -= target[i];
    int id = pr[i].second;
    if (st[id].size() < target[i])
      x = i;
    else if (st[id].size() > target[i]) {
      for (int x : st[id]) {
        fcuk.emplace(x, id);
      }
    }
  }
  vector<nd> vnd;
  for (int i = 1; i <= x; i++) {
    int id = pr[i].second;
    auto it = fcuk.begin();
    while (it != fcuk.end() && st[id].size() < target[i]) {
      pair<int, int> p = *it;
      if (st[id].find(p.first) != st[id].end())
        ;
      else {
        fcuk.erase(it);
        st[id].insert(p.first);
        vnd.push_back(nd{p.second, id, p.first});
        st[p.second].erase(p.first);
        int jd = rmap[p.second];
        if (st[p.second].size() == target[jd]) {
          for (int x : st[p.second]) {
            fcuk.erase(pair<int, int>(x, p.second));
          }
        }
      }
      it = fcuk.lower_bound(pair<int, int>(p.first + 1, 0));
    }
    assert(st[id].size() == target[i]);
  }
  cout << vnd.size() << endl;
  for (nd _ : vnd) {
    cout << _.from << " " << _.to << " " << _.item << "\n";
  }
  return 0;
}
