#include <bits/stdc++.h>
const int INF = 2000000005;
const long long BIG_INF = 2000000000000000005;
const int mod = 1000000007;
const int P = 31;
const long double PI = 3.141592653589793238462643;
const double eps = 1e-9;
using namespace std;
vector<pair<int, int>> dir = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
bool valid(int x, int y, int n, int m) {
  return x >= 0 && y >= 0 && x < n && y < m;
}
mt19937 rng(1999999973);
const int N = 100000 + 50;
int sum = 0, n, m, order[N], need[N];
unordered_set<int> box[N];
bool comp(int x, int y) { return box[x].size() > box[y].size(); }
vector<vector<int>> ans;
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    int t;
    cin >> t;
    sum += t;
    for (int j = 0; j < t; j++) {
      int cur;
      cin >> cur;
      box[i].insert(cur);
    }
    order[i] = i;
  }
  sort(order, order + n, comp);
  for (int i = 0; i < sum; i++) need[i % n]++;
  vector<int> to_erase;
  int l = 0, r = n - 1;
  while (l < r) {
    while (l < r && box[order[r]].size() == need[r]) r--;
    while (l < r && box[order[l]].size() == need[l]) l++;
    for (auto it = box[order[l]].begin(); it != box[order[l]].end(); it++) {
      if (box[order[r]].find(*it) == box[order[r]].end()) {
        to_erase.push_back(*it);
        box[order[r]].insert(*it);
        ans.push_back({order[l] + 1, order[r] + 1, *it});
        if (box[order[l]].size() - to_erase.size() == need[l] ||
            box[order[r]].size() == need[r])
          break;
      }
    }
    while (!to_erase.empty()) {
      box[order[l]].erase(to_erase.back());
      to_erase.pop_back();
    }
  }
  cout << ans.size() << '\n';
  for (int i = 0; i < ans.size(); i++) {
    cout << ans[i][0] << " " << ans[i][1] << " " << ans[i][2] << '\n';
  }
  return 0;
}
