#include <bits/stdc++.h>
using namespace std;
const int Sn = 200020, limit = 314000000;
const long long inf = (long long)1e14;
pair<long long, int> ky[Sn];
long long ruv[Sn], sp[Sn];
int n, m, go[Sn], val[Sn], best[Sn], size[Sn];
int rt, l[Sn], r[Sn], dit[Sn], dn;
int S[Sn], tS, low[Sn], dfn[Sn], col[Sn], C, Tm;
bool done[Sn], caninf[Sn];
vector<int> has[Sn], ru[Sn], at[Sn];
struct edge {
  int to, nx;
} E[Sn];
int qE[Sn], En = 1;
int merge(int a, int b) {
  if (!a || !b) return a | b;
  if (ky[a] > ky[b]) swap(a, b);
  r[a] = merge(r[a], b);
  if (dit[r[a]] > dit[l[a]]) swap(l[a], r[a]);
  return dit[a] = dit[r[a]] + 1, a;
}
void relax(int d, long long w) {
  if (w < sp[d]) {
    sp[d] = w;
    ky[++dn] = make_pair(w, d);
    rt = merge(rt, dn);
  }
}
void solve_min() {
  for (int i = 1; i <= n; i++) sp[i] = inf;
  for (int i = 1; i <= m; i++) {
    ruv[i] = (long long)ru[i].size() * inf + val[i];
    if (!ru[i].size()) {
      ky[++dn] = make_pair(val[i], go[i]);
      rt = merge(rt, dn);
    }
  }
  while (rt) {
    int d = ky[rt].second, sz = at[d].size();
    long long len = ky[rt].first;
    rt = merge(l[rt], r[rt]);
    if (done[d]) continue;
    if (len > limit) len = limit;
    for (int j = 0, i; j < sz; j++) {
      i = at[d][j];
      if (ruv[i] -= sp[d] - len, ruv[i] < inf) {
        ky[++dn] = make_pair(ruv[i], go[i]);
        rt = merge(rt, dn);
      }
    }
    sp[d] = len, done[d] = 1;
  }
}
void tarjan(int d) {
  S[++tS] = d;
  low[d] = dfn[d] = ++Tm;
  for (int j = qE[d], k; k = E[j].to, j; j = E[j].nx)
    if (!col[k]) {
      if (dfn[k])
        low[d] = min(low[d], dfn[k]);
      else {
        tarjan(k);
        low[d] = min(low[d], low[k]);
      }
    }
  if (low[d] == dfn[d]) {
    C++;
    do {
      col[S[tS]] = C;
      size[C]++;
    } while (S[tS--] != d);
  }
}
void dfs(int d) {
  if (sp[d] == inf) {
    done[d] = 1;
    return;
  }
  if (done[d]) return;
  int rnum = has[d].size();
  best[d] = 0;
  for (int i = 0, t; i < rnum; i++) {
    t = has[d][i];
    int okay = 1, sz = ru[t].size(), temp = val[t];
    for (int j = 0, s; j < sz; j++) {
      s = ru[t][j];
      if (sp[s] == inf) {
        okay = 0;
        break;
      } else if (col[s] == col[d]) {
        caninf[d] = 1;
      } else {
        if (caninf[d]) continue;
        dfs(s);
        if (caninf[s]) caninf[d] = 1;
        temp += best[s];
        if (temp > limit) temp = limit;
      }
    }
    if (!okay) {
      caninf[d] = 0;
      continue;
    }
    if (caninf[d]) return;
    if (temp > best[d]) best[d] = temp;
  }
  done[d] = 1;
}
void solve_max() {
  for (int i = 1; i <= n; i++) done[i] = 0;
  for (int i = 1; i <= n; i++)
    if (!col[i]) tarjan(i);
  for (int i = 1; i <= n; i++)
    if (!done[i]) dfs(i);
}
int main() {
  scanf("%d%d", &m, &n);
  for (int i = 1, l, x; i <= m; i++) {
    scanf("%d%d", go + i, &l);
    has[go[i]].push_back(i);
    while (l--) {
      scanf("%d", &x);
      if (x == -1)
        val[i]++;
      else {
        E[++En] = (edge){x, qE[go[i]]}, qE[go[i]] = En;
        ru[i].push_back(x);
        at[x].push_back(i);
      }
    }
  }
  solve_min();
  solve_max();
  for (int i = 1; i <= n; i++) {
    if (sp[i] == inf) {
      printf("-1 -1\n");
      continue;
    }
    printf("%d ", (int)sp[i]);
    if (caninf[i])
      printf("-2\n");
    else
      printf("%d\n", best[i]);
  }
}
