#include <bits/stdc++.h>
using namespace std;
const int N = 20000, M = 400000, inf = 1050000000;
int n, m, S, T, ans, res, rt, cnt, cc = 1, hd[N], nxt[M], iter[N], s[N], ls[N],
                                   rs[N], p[N], tg[N], A[N][3], fr[N], rnk[N],
                                   q[N];
struct edg {
  int u, v, c;
} e[M];
void add(int u, int v, int w) {
  e[++cc] = (edg){u, v, w};
  nxt[cc] = hd[u];
  hd[u] = cc;
  e[++cc] = (edg){v, u, 0};
  nxt[cc] = hd[v];
  hd[v] = cc;
}
bool bfs() {
  memset(rnk, 0, sizeof(rnk));
  for (int i = S; i <= T; i++) iter[i] = hd[i];
  int l = 1, r = 2;
  q[1] = S;
  rnk[S] = 1;
  while (l < r)
    for (int x = q[l++], i = hd[x]; i; i = nxt[i])
      if (!rnk[e[i].v] && e[i].c) rnk[e[i].v] = rnk[x] + 1, q[r++] = e[i].v;
  return rnk[T];
}
int dfs(int x, int f) {
  if (x == T || !f) return f;
  int res = 0, t;
  for (int &i = iter[x]; i && f; i = nxt[i])
    if (rnk[e[i].v] == rnk[x] + 1 && e[i].c) {
      t = dfs(e[i].v, min(f, e[i].c));
      e[i].c -= t;
      e[i ^ 1].c += t;
      res += t;
      f -= t;
    }
  if (!res) rnk[x] = 0;
  return res;
}
void build(int &x, int l, int r, int pre) {
  if (!x) x = ++cnt;
  if (pre) add(pre, x, r - l + 1);
  if (l == r) {
    p[l] = x;
    return;
  }
  int mid = l + r >> 1;
  build(ls[x], l, mid, x);
  build(rs[x], mid + 1, r, x);
}
void upd(int x, int l, int r, int tl, int tr, int s) {
  if (tl <= l && r <= tr) {
    add(s, x, 1);
    return;
  }
  int mid = l + r >> 1;
  if (tl <= mid) upd(ls[x], l, mid, tl, tr, s);
  if (tr > mid) upd(rs[x], mid + 1, r, tl, tr, s);
}
void fnd(int x, int p) {
  if (x == T) return;
  for (int i = hd[x]; i; i = nxt[i])
    if (!(i & 1) && e[i ^ 1].c && res) {
      fnd(e[i].v, p);
      e[i ^ 1].c--;
      e[i].c++;
      if (e[i].v == T) res--, fr[x] = p;
    }
}
int main() {
  int tp, x, len, l, r, a, b, c;
  scanf("%d%d", &n, &m);
  cnt = n;
  build(rt, 1, m, 0);
  S = 0;
  T = cnt + 1;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &tp);
    if (!tp) {
      scanf("%d", &len);
      add(S, i, 1);
      for (int j = 1; j <= len; j++) scanf("%d", &x), add(i, p[x], 1);
    }
    if (tp == 1) {
      scanf("%d%d", &l, &r);
      add(S, i, 1);
      upd(rt, 1, m, l, r, i);
    }
    if (tp == 2) {
      scanf("%d%d%d", &A[i][0], &A[i][1], &A[i][2]);
      tg[i] = 1;
      add(S, i, 2);
      add(i, p[A[i][0]], 1);
      add(i, p[A[i][1]], 1);
      add(i, p[A[i][2]], 1);
    }
  }
  for (int i = 1; i <= m; i++) add(p[i], T, 1);
  while (bfs()) ans += dfs(S, inf);
  for (int i = hd[S]; i; i = nxt[i])
    if (e[i ^ 1].c) res = e[i ^ 1].c, fnd(e[i].v, e[i].v);
  for (int i = 1; i <= m; i++) s[fr[p[i]]]++;
  for (int i = 1; i <= n; i++)
    if (tg[i] && s[i] == 1)
      for (int j = 0; j <= 2; j++)
        if (fr[p[A[i][j]]] && fr[p[A[i][j]]] != i) {
          fr[p[A[i][j]]] = i;
          break;
        }
  printf("%d\n", ans);
  for (int i = 1; i <= m; i++)
    if (fr[p[i]]) printf("%d %d\n", fr[p[i]], i);
  return 0;
}
