#include <bits/stdc++.h>
std::vector<std::pair<std::unordered_set<int>, int>> v;
bool cmp(std::pair<std::unordered_set<int>, int> v1,
         std::pair<std::unordered_set<int>, int> v2) {
  return v1.first.size() < v2.first.size();
}
struct req {
  int l, r, x;
};
signed main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);
  int n, m;
  std::cin >> n >> m;
  v.resize(n);
  int sz = 0;
  for (int i = 0; i < n; ++i) {
    int x;
    std::cin >> x;
    sz += x;
    v[i].second = i;
    for (int j = 0; j < x; ++j) {
      int x1;
      std::cin >> x1;
      v[i].first.insert(x1);
    }
  }
  std::vector<int> sizes;
  for (int i = 0; i < n; ++i) {
    sizes.push_back(sz / n + ((sz % n) > i));
  }
  std::sort(sizes.begin(), sizes.end());
  std::sort(v.begin(), v.end(), cmp);
  std::vector<req> answ;
  int l = 0, r = n - 1;
  while (l < r) {
    std::vector<int> toErase;
    for (auto d : v[r].first) {
      if (sizes[l] - v[l].first.size() == 0) {
        break;
      }
      if (v[r].first.size() - sizes[r] - toErase.size() == 0) {
        break;
      }
      if (v[l].first.find(d) != v[l].first.end()) {
        continue;
      } else {
        answ.push_back({v[r].second, v[l].second, d});
        v[l].first.insert(d);
        toErase.push_back(d);
      }
    }
    for (auto q : toErase) {
      v[r].first.erase(q);
    }
    int f1 = sizes[l] - v[l].first.size();
    int f2 = v[r].first.size() - sizes[r];
    assert(f1 == 0 || f2 == 0);
    if (f1 == 0) {
      l++;
    }
    if (f2 == 0) {
      r--;
    }
  }
  std::cout << answ.size() << '\n';
  for (auto d : answ) {
    std::cout << d.l + 1 << ' ' << d.r + 1 << ' ' << d.x << '\n';
  }
}
