#include <bits/stdc++.h>
using namespace std;
const int N = 40005;
const int inf = 1000 * 1000 * 1000;
const int mod = 1000 * 1000 * 1000 + 7;
int n, m;
int l[N], r[N];
int cnt[N];
int S, T;
int timer;
struct edge {
  int a, b, cap, flow;
};
vector<int> g[N], gg[N];
vector<edge> G;
vector<int> seg, mas;
int answ[N];
void add_edge(int a, int b, int c) {
  edge e1 = {a, b, c, 0};
  edge e2 = {b, a, 0, 0};
  g[a].push_back((int)G.size());
  G.push_back(e1);
  g[b].push_back((int)G.size());
  G.push_back(e2);
}
int L[4 * 5005], R[4 * 5005];
void build(int v, int s, int e) {
  L[v] = s;
  R[v] = e;
  timer = max(timer, v + n);
  if (v != 1) {
    add_edge(v + n, v / 2 + n, e - s + 1);
  }
  if (s == e) return;
  int m = (s + e) / 2;
  build(2 * v, s, m);
  build(2 * v + 1, m + 1, e);
}
void split(int v, int s, int e, int l, int r) {
  if (l > r) return;
  if (s == l && e == r) {
    mas.push_back(v + n);
    return;
  }
  int m = (s + e) / 2;
  split(2 * v, s, m, l, min(r, m));
  split(2 * v + 1, m + 1, e, max(m + 1, l), r);
}
int pos[N], d[N];
bool bfs() {
  queue<int> q;
  for (int i = S; i <= T; i++) {
    d[i] = -1;
  }
  d[S] = 0;
  q.push(S);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (int i = 0; i < (int)g[v].size(); i++) {
      int id = g[v][i];
      int to = G[id].b;
      if (G[id].cap == G[id].flow) continue;
      if (d[to] == -1) {
        d[to] = d[v] + 1;
        q.push(to);
      }
    }
  }
  return (d[T] != -1);
}
int dfs(int v, int flow) {
  if (v == T || flow == 0) return flow;
  for (; pos[v] < (int)g[v].size(); pos[v]++) {
    int i = pos[v];
    int id = g[v][i];
    int to = G[id].b;
    if (d[to] != d[v] + 1) continue;
    int x = dfs(to, min(flow, G[id].cap - G[id].flow));
    if (x) {
      G[id].flow += x;
      G[id ^ 1].flow -= x;
      return x;
    }
  }
  return 0;
}
int flow() {
  int answ = 0;
  while (bfs()) {
    for (int i = S; i <= T; i++) pos[i] = 0;
    while (true) {
      int x = dfs(S, inf);
      if (x == 0) break;
      answ += x;
    }
  }
  return answ;
}
int main() {
  scanf("%d%d", &n, &m);
  S = 0;
  build(1, 1, m);
  for (int i = 1; i <= n; i++) {
    int id;
    scanf("%d", &id);
    if (id == 0) {
      add_edge(S, i, 1);
      int k;
      scanf("%d", &k);
      while (k--) {
        int a;
        scanf("%d", &a);
        mas.clear();
        split(1, 1, m, a, a);
        add_edge(i, mas[0], 1);
      }
    }
    if (id == 1) {
      add_edge(S, i, 1);
      scanf("%d%d", &l[i], &r[i]);
      mas.clear();
      split(1, 1, m, l[i], r[i]);
      for (int j = 0; j < (int)mas.size(); j++) {
        add_edge(i, mas[j], 1);
      }
    }
    if (id == 2) {
      add_edge(S, i, 2);
      int a, b, c;
      scanf("%d%d%d", &a, &b, &c);
      gg[i].push_back(a);
      gg[i].push_back(b);
      gg[i].push_back(c);
      mas.clear();
      split(1, 1, m, a, a);
      add_edge(i, mas[0], 1);
      mas.clear();
      split(1, 1, m, b, b);
      add_edge(i, mas[0], 1);
      mas.clear();
      split(1, 1, m, c, c);
      add_edge(i, mas[0], 1);
    }
  }
  T = timer + 1;
  add_edge(n + 1, T, m);
  cout << flow() << endl;
  vector<pair<int, int> > vert;
  for (int i = 0; i < (int)G.size(); i += 2) {
    if (G[i].flow == 0) continue;
    int a = G[i].a;
    int b = G[i].b;
    if (a >= 1 && a <= n) {
      if (L[b - n] == R[b - n]) {
        answ[L[b - n]] = a;
      } else {
        vert.push_back(make_pair(-b, a));
      }
    }
  }
  sort(vert.begin(), vert.end());
  for (int i = 0; i < (int)vert.size(); i++) {
    int a = vert[i].second;
    int b = -vert[i].first;
    int l = L[b - n];
    int r = R[b - n];
    for (int j = l; j <= r; j++) {
      if (answ[j] == 0) {
        answ[j] = a;
        break;
      }
    }
  }
  for (int i = 1; i <= m; i++) {
    if (answ[i] == 0) continue;
    cnt[answ[i]]++;
  }
  for (int i = 1; i <= n; i++) {
    if ((int)gg[i].size() && cnt[i] == 1) {
      for (int j = 0; j < (int)gg[i].size(); j++) {
        int gag = gg[i][j];
        if (answ[gag] == i) continue;
        answ[gag] = i;
        break;
      }
    }
  }
  for (int i = 1; i <= m; i++) {
    if (answ[i] == 0) continue;
    printf("%d %d\n", answ[i], i);
  }
  return 0;
}
