#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const long long mod = 1000000007;
const int N = 1e5 + 5;
set<int> boxs[N];
int main(int argc, char** argv) {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  cin >> n >> m;
  int total = 0;
  for (int i = 0, a; i < n; i++) {
    cin >> a;
    total += a;
    for (int j = 0, x; j < a; j++) {
      cin >> x;
      boxs[i + 1].insert(x);
    }
  }
  int target = (total + n - 1) / n;
  int gr = 0;
  set<pair<int, int>> st;
  for (int i = 1; i <= n; i++)
    st.insert({boxs[i].size(), i}), gr += (boxs[i].size() >= target);
  vector<pair<int, pair<int, int>>> moves;
  while (st.size() > 1) {
    int sm = st.begin()->first;
    int ma = st.rbegin()->first;
    if (ma - sm <= 1) break;
    int small_index = st.begin()->second;
    int big_index = st.rbegin()->second;
    st.erase(st.begin());
    st.erase(*st.rbegin());
    int Need = 0;
    if (gr < total % n)
      Need = target;
    else
      Need = total / n;
    for (set<int>::iterator it = boxs[big_index].begin();
         it != boxs[big_index].end() && ma - sm > 1 && sm < Need &&
         ma > Need;) {
      if (boxs[small_index].find(*it) != boxs[small_index].end()) {
        it++;
        continue;
      }
      auto temp = it;
      temp++;
      boxs[small_index].insert(*it);
      moves.push_back({big_index, {small_index, *it}});
      boxs[big_index].erase(*it);
      it = temp;
      sm++;
      ma--;
    }
    st.insert({ma, big_index});
    st.insert({sm, small_index});
    if (sm >= target) gr--;
  }
  cout << moves.size() << '\n';
  for (int i = 0; i < moves.size(); i++) {
    cout << moves[i].first << " " << moves[i].second.first << " "
         << moves[i].second.second << '\n';
  }
  return 0;
}
