#include <bits/stdc++.h>
using namespace std;
#pragma GCC diagnostic ignored "-Wmissing-declarations"
inline int safe_mul(const int x, const int y)
    __attribute__((warn_unused_result));
int const maxn = 100003;
vector<int> used[maxn];
int main() {
  ios_base::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vector<pair<int, int>> nums;
  for (int i = 0; i < n; ++i) {
    int s;
    cin >> s;
    for (int j = 0; j < s; ++j) {
      int x;
      cin >> x;
      used[i].push_back(x);
    }
    nums.emplace_back(s, i);
  }
  sort(nums.begin(), nums.end());
  long long acnt = 0;
  for (const auto& p : nums) acnt += p.first;
  vector<int> need(n);
  for (int i = 0; i < n; ++i) {
    need[i] = acnt / n + (n - i <= acnt % n);
  }
  int l = 0;
  int r = n - 1;
  vector<tuple<int, int, int>> result;
  bitset<maxn + 100> lb;
  for (const int x : used[nums[l].second]) lb.set(x);
  bitset<maxn + 100> rb;
  for (const int x : used[nums[r].second]) rb.set(x);
  for (;;) {
    bool lsh = false;
    while (l < r && nums[l].first == need[l]) {
      ++l;
      lsh = true;
    }
    bool rsh = false;
    while (r > l && nums[r].first == need[r]) {
      --r;
      rsh = true;
    }
    if (l >= r) break;
    if (lsh) {
      lb.reset();
      for (const int x : used[nums[l].second]) lb.set(x);
    }
    if (rsh) {
      rb.reset();
      for (const int x : used[nums[r].second]) rb.set(x);
    }
    auto uni = rb & ~lb;
    uint64_t* ptr = reinterpret_cast<uint64_t*>(&uni);
    bool ex = false;
    for (int i = 0; i <= maxn / 64 && !ex; ++i) {
      if (*ptr) {
        for (int j = 0; j < 64; ++j)
          if ((*ptr) & (1uLL << j)) {
            int idx = i * 64 + j;
            result.emplace_back(nums[r].second + 1, nums[l].second + 1, idx);
            lb[idx] = 1;
            rb[idx] = 0;
            --nums[r].first;
            ++nums[l].first;
            if (nums[l].first == need[l] || nums[r].first == need[r]) {
              ex = true;
              break;
            }
          }
      }
      ++ptr;
    }
  }
  cout << result.size() << endl;
  for (const auto& t : result)
    cout << get<0>(t) << ' ' << get<1>(t) << ' ' << get<2>(t) << '\n';
}
