#include <bits/stdc++.h>
using namespace std;
inline int read() {
  char ch = getchar();
  int x = 0;
  for (; ch > '9' || ch < '0'; ch = getchar())
    ;
  for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
  return x;
}
int he[100000], ne[1000000 << 1], e[1000000 << 1], va[1000000 << 1],
    cnt = 1, n, m, S, T, Mx, op[100000];
int bel[100000], a[100000][3], ans, cur[100000], dis[100000], Q[1000000];
bool vis[100000];
vector<int> V[100000];
void add(int u, int v, int w) {
  ne[++cnt] = he[u];
  he[u] = cnt;
  e[cnt] = v;
  va[cnt] = w;
  ne[++cnt] = he[v];
  he[v] = cnt;
  e[cnt] = u;
  va[cnt] = 0;
}
void build(int t, int l, int r, int pre) {
  Mx = max(Mx, pre);
  if (pre && l != r) {
    add(pre, t + n + m + 1, 1000000000);
  }
  if (l == r) {
    add(pre, n + l, 1000000000);
    add(n + l, T, 1);
    return;
  }
  int mid = l + r >> 1;
  build(t << 1, l, mid, t + n + m + 1);
  build(t << 1 | 1, mid + 1, r, t + n + m + 1);
}
void addseg(int t, int l, int r, int L, int R, int i) {
  if (l == r) {
    add(i, l + n, 1);
    return;
  }
  if (L <= l && r <= R) {
    add(i, t + n + m + 1, 1);
    return;
  }
  int mid = l + r >> 1;
  if (L <= mid) addseg(t << 1, l, mid, L, R, i);
  if (R > mid) addseg(t << 1 | 1, mid + 1, r, L, R, i);
}
bool BFS() {
  memset(dis, -1, sizeof(int) * (Mx + 3));
  assert(dis[T] == -1);
  int h = 0, t, x, y, i;
  dis[Q[t = 1] = S] = 0;
  for (; h != t;)
    for (i = he[x = Q[++h]]; i; i = ne[i])
      if (va[i] && dis[y = e[i]] == -1) {
        dis[Q[++t] = y] = dis[x] + 1;
      }
  return dis[T] != -1;
}
int dfs(int x, int a) {
  if (x == T || a == 0) return a;
  int f = 0, flow = 0;
  for (int &i = cur[x]; i; i = ne[i])
    if (dis[e[i]] == dis[x] + 1 && (f = dfs(e[i], min(a, va[i]))) > 0) {
      flow += f;
      va[i] -= f;
      va[i ^ 1] += f;
      a -= f;
      if (!a) break;
    }
  return flow;
}
void dinic() {
  int TT = 0;
  while (BFS()) {
    memcpy(cur, he, sizeof(int) * (Mx + 3));
    ans += dfs(S, 1000000000);
    TT++;
    assert(TT < 100);
  }
}
int main() {
  n = read(), m = read();
  S = 0;
  T = n + m + 1;
  build(1, 1, m, 0);
  for (int i = 1; i <= n; i++) {
    op[i] = read();
    if (op[i] == 0) {
      add(S, i, 1);
      int k = read();
      for (int j = 1; j <= k; j++) {
        int u = read();
        add(i, u + n, 1);
      }
    }
    if (op[i] == 1) {
      add(S, i, 1);
      int l = read(), r = read();
      addseg(1, 1, m, l, r, i);
    }
    if (op[i] == 2) {
      int x = read(), y = read(), z = read();
      a[i][0] = x, a[i][1] = y, a[i][2] = z;
      add(S, i, 2);
      add(i, x + n, 1);
      add(i, y + n, 1);
      add(i, z + n, 1);
    }
  }
  dinic();
  printf("%d\n", ans);
  for (int u = n + 1; u <= m + n; u++) {
    bool flag = 0;
    for (int i = he[u]; i && !flag; i = ne[i]) {
      if (e[i] == T && va[i] == 0) flag = 1;
    }
    if (!flag) continue;
    for (int i = he[u]; i && flag; i = ne[i]) {
      if (va[i] && (i & 1) && e[i] <= n) {
        bel[u - n] = e[i];
        V[e[i]].push_back(u - n);
        flag = 0;
      }
    }
    if (!flag) continue;
    int v = u;
    while (v > n)
      for (int i = he[v]; i; i = ne[i])
        if (va[i] && (i & 1)) {
          va[i]--;
          v = e[i];
          break;
        }
    bel[u - n] = v;
    V[v].push_back(u - n);
  }
  for (int i = 1; i <= n; i++) {
    if (op[i] == 2 && V[i].size() == 1) {
      for (int j = 0; j < 3; j++)
        if (a[i][j] != V[i][0]) {
          int t = bel[a[i][j]];
          V[t].clear();
          V[i].push_back(a[i][j]);
          break;
        }
    }
  }
  for (int i = 1; i <= n; i++)
    for (int j = 0; j < V[i].size(); j++) printf("%d %d\n", i, V[i][j]);
  return 0;
}
