#include <bits/stdc++.h>
using namespace std;
const int MAX = 314000000;
const int maxn = 2e5 + 10;
vector<int> g[maxn], rg[maxn], ng[maxn];
int cnode;
int _val[maxn], val[maxn], id[maxn];
int dp[maxn];
int ansmin[maxn], ansmax[maxn], minmin[maxn], n, m;
int todo[maxn];
void bfs() {
  memset(ansmin, -1, sizeof(ansmin));
  queue<int> que;
  for (int i = 1; i <= m + n; i++)
    if (todo[i] < 1) {
      ansmin[i] = 0x3f3f3f3f;
      que.push(i);
    }
  while (!que.empty()) {
    int x = que.front();
    que.pop();
    for (int i = 0; i < rg[x].size(); i++) {
      int to = rg[x][i];
      todo[to]--;
      if (todo[to] < 1 && ansmin[to] == -1) {
        ansmin[to] = 0x3f3f3f3f;
        que.push(to);
      }
    }
  }
}
bool usd[maxn], in[maxn];
int dfn[maxn], low[maxn], fa[maxn], DFN;
stack<int> st;
vector<int> tmp;
void tarjan(int x) {
  usd[x] = 1;
  dfn[x] = low[x] = ++DFN;
  st.push(x);
  in[x] = 1;
  for (int i = 0; i < g[x].size(); i++) {
    int to = g[x][i];
    if (!usd[to]) {
      tarjan(to);
      low[x] = min(low[x], low[to]);
    } else if (in[to])
      low[x] = min(low[x], dfn[to]);
  }
  if (low[x] == dfn[x]) {
    int y;
    tmp.clear();
    cnode++;
    do {
      y = st.top();
      st.pop();
      in[y] = 0;
      fa[y] = cnode;
      tmp.push_back(y);
    } while (y != x);
    for (int i = 0; i < tmp.size(); i++)
      for (int j = 0; j < g[tmp[i]].size(); j++) {
        if (fa[tmp[i]] != fa[g[tmp[i]][j]])
          ng[cnode].push_back(fa[g[tmp[i]][j]]);
      }
    if (tmp.size() > 1) {
      id[cnode] = -1;
      ansmax[cnode] = -2;
    } else
      val[cnode] = _val[tmp[0]], id[cnode] = tmp[0];
  }
}
void dfs(int x) {
  usd[x] = 1;
  if (id[x] > n) {
    ansmax[x] = 0;
  }
  for (int i = 0; i < ng[x].size(); i++) {
    int to = ng[x][i];
    if (!usd[to]) dfs(to);
    if (id[x] <= n) {
      if (ansmax[to] == -2)
        ansmax[x] = -2;
      else if (ansmax[x] != -2)
        ansmax[x] = max(ansmax[x], ansmax[to]);
    } else {
      if (ansmax[to] == -2)
        ansmax[x] = -2;
      else if (ansmax[x] != -2)
        ansmax[x] += ansmax[to];
      if (ansmax[x] > MAX) ansmax[x] = MAX;
    }
  }
  if (ansmax[x] != -2) ansmax[x] += val[x];
  if (ansmax[x] > MAX) ansmax[x] = MAX;
}
void getmin() {
  for (int i = 1; i <= m + n; i++)
    if (~ansmin[i]) {
      if (i <= n)
        ansmin[i] = MAX;
      else
        ansmin[i] = _val[i];
    }
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      pq;
  for (int i = 1; i <= m + n; i++)
    if (~ansmin[i] && todo[i] < 1) {
      pq.push(make_pair(ansmin[i], i));
    }
  while (!pq.empty()) {
    pair<int, int> ft = pq.top();
    pq.pop();
    int x = ft.second, s = ft.first;
    if (s > ansmin[x]) continue;
    for (int i = 0; i < rg[x].size(); i++) {
      int to = rg[x][i];
      if (ansmin[to] == -1) continue;
      todo[to]--;
      if (to > n) {
        ansmin[to] += ansmin[x];
        if (todo[to] < 1) pq.push(make_pair(ansmin[to], to));
      } else {
        if (todo[to] < 1 && ansmin[x] < ansmin[to]) {
          ansmin[to] = ansmin[x];
          pq.push(make_pair(ansmin[to], to));
        }
      }
    }
  }
}
int main() {
  scanf("%d%d", &m, &n);
  int mi, li, ci;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &mi, &li);
    g[mi].push_back(n + i);
    rg[n + i].push_back(mi);
    for (int j = 1; j <= li; j++) {
      scanf("%d", &ci);
      if (ci == -1)
        _val[n + i]++;
      else {
        g[n + i].push_back(ci);
        rg[ci].push_back(n + i);
      }
    }
  }
  for (int i = 1; i <= n; i++) todo[i] = 1;
  for (int i = n + 1; i <= m + n; i++) todo[i] = g[i].size();
  bfs();
  for (int i = 1; i <= m + n; i++) g[i].clear();
  for (int i = 1; i <= m + n; i++)
    if (~ansmin[i])
      for (int j = 0; j < rg[i].size(); j++)
        if (~ansmin[rg[i][j]]) g[rg[i][j]].push_back(i);
  for (int i = 1; i <= m + n; i++) rg[i].clear();
  for (int i = 1; i <= m + n; i++)
    for (int j = 0; j < g[i].size(); j++) rg[g[i][j]].push_back(i);
  for (int i = 1; i <= n; i++) todo[i] = 1;
  for (int i = n + 1; i <= m + n; i++) todo[i] = g[i].size();
  getmin();
  memset(minmin, 0x3f, sizeof(minmin));
  for (int i = 1; i <= m + n; i++)
    if (!usd[i]) tarjan(i);
  memset(usd, 0, sizeof(usd));
  for (int i = 1; i <= n; i++) {
    if (ansmin[i] == -1)
      printf("-1 -1\n");
    else {
      if (!usd[fa[i]]) dfs(fa[i]);
      printf("%d %d\n", ansmin[i], ansmax[fa[i]]);
    }
  }
  return 0;
}
