#include <bits/stdc++.h>
using namespace std;
int a, b, c, d, e, n, m, t, kk, tt = 0, l[5007], r[5007], fa[5007], type[5007],
                                ind[5007];
int y[5007] = {0}, qw[5007], tree[1000007], a1[5007], a2[5007], a3[5007],
    a4[5007];
vector<int> q[5007];
vector<short> w[5007];
void get(int x1, int l, int r, int tl, int tr, int k) {
  if (tree[k] == tt) return;
  if (l >= tl && r <= tr) {
    tree[k] = tt;
    for (int i = l; i <= r; i++) w[x1].push_back(i);
    return;
  }
  int m = (l + r) / 2;
  if (tl <= m) get(x1, l, m, tl, tr, k << 1);
  if (tr > m) get(x1, m + 1, r, tl, tr, (k << 1) + 1);
}
int sou(int x1) {
  t = 0;
  if (type[x1] == 0)
    for (int j = 1; j <= q[x1].size(); j++) w[x1].push_back(q[x1][j - 1]);
  else
    get(x1, 1, m, q[x1][0], q[x1][1], 1);
  for (int j = 1; j <= w[x1].size(); j++)
    if (!qw[fa[w[x1][j - 1]]]) {
      qw[fa[w[x1][j - 1]]] = 1;
      if (y[fa[w[x1][j - 1]]] == 0 || sou(y[fa[w[x1][j - 1]]])) {
        y[fa[w[x1][j - 1]]] = x1;
        w[x1].clear();
        return 1;
      }
    }
  w[x1].clear();
  return 0;
}
int main() {
  scanf("%d%d", &n, &m);
  kk = 1;
  for (int i = 1; i <= m; i++) fa[i] = i;
  int ans = 0, t3 = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &type[kk]);
    if (type[kk] == 0) {
      scanf("%d", &b);
      for (int j = 1; j <= b; j++) {
        scanf("%d", &c);
        q[kk].push_back(c);
      }
      ind[kk] = i;
      kk++;
    } else if (type[kk] == 1) {
      scanf("%d%d", &b, &c);
      ind[kk] = i;
      q[kk].push_back(b);
      q[kk++].push_back(c);
    } else {
      scanf("%d%d%d", &b, &c, &d);
      fa[c] = b;
      fa[d] = b;
      ans += 2;
      a1[++t3] = b, a2[t3] = c, a3[t3] = d, a4[t3] = i;
    }
  }
  for (int i = 1; i <= kk - 1; i++) {
    tt++;
    for (int j = 1; j <= m; j++) qw[j] = 0;
    if (sou(i)) ans++;
  }
  printf("%d\n", ans);
  for (int i = 1; i <= t3; i++) {
    fa[a1[i]] = 0;
    fa[a2[i]] = 0;
    fa[a3[i]] = 0;
    int g = 0;
    if (y[a1[i]] == 0) {
      printf("%d %d\n", a4[i], a1[i]);
      printf("%d %d\n", a4[i], a2[i]);
      continue;
    } else if (type[y[a1[i]]] == 0)
      for (int j = 1; j <= q[y[a1[i]]].size(); j++) {
        if (q[y[a1[i]]][j - 1] == a1[i]) g = 1;
        if (q[y[a1[i]]][j - 1] == a2[i]) g = 2;
        if (q[y[a1[i]]][j - 1] == a3[i]) g = 3;
      }
    else
      for (int j = q[y[a1[i]]][0]; j <= q[y[a1[i]]][1]; j++) {
        if (j == a1[i]) g = 1;
        if (j == a2[i]) g = 2;
        if (j == a3[i]) g = 3;
      }
    if (g == 1)
      printf("%d %d\n", ind[y[a1[i]]], a1[i]);
    else
      printf("%d %d\n", a4[i], a1[i]);
    if (g == 2)
      printf("%d %d\n", ind[y[a1[i]]], a2[i]);
    else
      printf("%d %d\n", a4[i], a2[i]);
    if (g == 3)
      printf("%d %d\n", ind[y[a1[i]]], a3[i]);
    else
      printf("%d %d\n", a4[i], a3[i]);
  }
  for (int i = 1; i <= m; i++)
    if (y[i] && fa[i] == i) printf("%d %d\n", ind[y[i]], i);
  return 0;
}
