#include <bits/stdc++.h>
using namespace std;
template <typename T>
T abs(T a) {
  return a < 0 ? -a : a;
}
template <typename T>
T sqr(T a) {
  return a * a;
}
const int INF = (int)1e9;
const long double EPS = 1e-9;
const long double PI = 3.1415926535897932384626433832795;
const int N = 400500;
const int MAX = 314000000;
int n, m;
vector<int> trM[N];
int trD[N], trO[N];
int trSum[N], trCnt[N];
vector<int> g[N], rg[N];
bool canEnd[N], canLoop[N];
int d[N];
set<pair<int, int> > s;
vector<int> cg[N], crg[N];
int col[N];
int cused;
int used[N];
void dfs(int v) {
  if (col[v] == 2) return;
  if (col[v] == 1) {
    canLoop[v] = true;
    return;
  }
  col[v] = 1;
  for (int i = 0; i < int(int((cg[v]).size())); ++i) dfs(cg[v][i]);
  col[v] = 2;
}
void dfsR(int v) {
  if (used[v] == cused) return;
  used[v] = cused;
  canLoop[v] = true;
  for (int i = 0; i < int(int((crg[v]).size())); ++i) dfsR(crg[v][i]);
}
int z[N];
int solve(int v) {
  if (canLoop[v]) throw;
  if (z[v] == -1) {
    int& res = z[v];
    res = 0;
    for (int i = 0; i < int(int((g[v]).size())); ++i) {
      int t = g[v][i];
      int cur = trD[t];
      bool good = true;
      for (int j = 0; j < int(int((trM[t]).size())); ++j)
        if (!canEnd[trM[t][j]]) good = false;
      if (good) {
        for (int j = 0; j < int(int((trM[t]).size())); ++j) {
          int u = trM[t][j];
          cur += solve(u);
          if (cur > MAX) cur = MAX;
        }
        res = max(res, cur);
      }
    }
  }
  return z[v];
}
int main() {
  cin >> m >> n;
  for (int i = 0; i < int(m); ++i) {
    int v;
    scanf("%d", &v);
    v--;
    g[v].push_back(i);
    trO[i] = v;
    int cnt;
    scanf("%d", &cnt);
    for (int j = 0; j < int(cnt); ++j) {
      int x;
      scanf("%d", &x);
      if (x == -1)
        trD[i]++;
      else {
        trM[i].push_back(x - 1);
        rg[x - 1].push_back(i);
      }
    }
  }
  for (int i = 0; i < int(n); ++i) {
    d[i] = INF;
    int mn = INF;
    for (int j = 0; j < int(int((g[i]).size())); ++j)
      if (int((trM[g[i][j]]).size()) == 0) mn = min(mn, trD[g[i][j]]);
    if (mn < (INF >> 1)) {
      d[i] = mn;
      s.insert(pair<int, int>(d[i], i));
    }
  }
  while (!s.empty()) {
    int v = s.begin()->second;
    s.erase(s.begin());
    for (int i = 0; i < int(int((rg[v]).size())); ++i) {
      int t = rg[v][i];
      trSum[t] += d[v];
      if (trSum[t] > MAX) trSum[t] = MAX;
      trCnt[t]++;
      if (trCnt[t] == int((trM[t]).size())) {
        int u = trO[t];
        int nd = trSum[t] + trD[t];
        if (nd > MAX) nd = MAX;
        if (d[u] > nd) {
          pair<int, int> x(d[u], u);
          s.erase(x);
          x.first = d[u] = nd;
          s.insert(x);
        }
      }
    }
  }
  for (int i = 0; i < int(n); ++i) canEnd[i] = (d[i] < INF);
  for (int v = 0; v < int(n); ++v) {
    for (int j = 0; j < int(int((g[v]).size())); ++j) {
      int t = g[v][j];
      bool good = true;
      for (int k = 0; k < int(int((trM[t]).size())); ++k)
        if (!canEnd[trM[t][k]]) {
          good = false;
          break;
        }
      if (good) {
        for (int k = 0; k < int(int((trM[t]).size())); ++k) {
          cg[v].push_back(trM[t][k]);
          crg[trM[t][k]].push_back(v);
        }
      }
    }
  }
  for (int v = 0; v < int(n); ++v)
    if (col[v] == 0) {
      dfs(v);
    }
  cused++;
  for (int v = 0; v < int(n); ++v)
    if (canLoop[v] && used[v] < cused) dfsR(v);
  memset(z, -1, sizeof(z));
  for (int i = 0; i < int(n); ++i) {
    if (!canEnd[i]) {
      puts("-1 -1");
      continue;
    }
    printf("%d ", d[i]);
    if (canLoop[i]) {
      puts("-2");
    } else {
      printf("%d\n", solve(i));
    }
  }
  return 0;
}
