#include <bits/stdc++.h>
using namespace std;
int n, m, t, s;
int sz[200003];
int id[200003];
int sta[200003];
int dia[200003];
int cnt[200003];
bool nc[200003];
int ans1[200003];
int ans2[200003];
int mark[200003];
bool used[200003];
vector<int> scc[200003];
vector<int> adj0[200003];
vector<int> adj1[200003];
vector<int> adj2[200003];
vector<int> adj3[200003];
vector<int> adj4[200003];
int DP(int node) {
  if (used[node]) return ans2[node];
  used[node] = true;
  for (int i = 0; i < (int)adj0[node].size(); i++) {
    int x = adj0[node][i];
    if (nc[x]) continue;
    int sum = dia[x];
    for (int j = 0; j < (int)adj2[x].size(); j++) {
      int y = adj2[x][j];
      sum = min(sum + DP(y), 314000000);
    }
    ans2[node] = max(ans2[node], sum);
  }
  return ans2[node];
}
void DfsNeg(int node) {
  ans2[node] = -2;
  for (int i = 0; i < (int)adj4[node].size(); i++)
    if (ans2[adj4[node][i]] != -2) DfsNeg(adj4[node][i]);
}
void SccDfs2(int node) {
  scc[s].push_back(node);
  used[node] = true;
  for (int i = 0; i < (int)adj4[node].size(); i++)
    if (!used[adj4[node][i]]) SccDfs2(adj4[node][i]);
}
void SccDfs1(int node) {
  used[node] = true;
  for (int i = 0; i < (int)adj3[node].size(); i++)
    if (!used[adj3[node][i]]) SccDfs1(adj3[node][i]);
  sta[++t] = node;
}
void SolveMax() {
  for (int i = 1; i <= m; i++) {
    for (int j = 0; j < (int)adj2[i].size(); j++)
      if (ans1[adj2[i][j]] == 1 << 30) {
        nc[i] = true;
        break;
      }
  }
  for (int i = 1; i <= m; i++)
    if (!nc[i])
      for (int j = 0; j < (int)adj2[i].size(); j++) {
        int x = adj2[i][j];
        if (mark[x] != i) {
          mark[x] = i;
          adj3[id[i]].push_back(x);
          adj4[x].push_back(id[i]);
        }
        if (x == id[i]) ans2[x] = -2;
      }
  for (int i = 1; i <= n; i++)
    if (!used[i]) SccDfs1(i);
  memset(used, 0, sizeof used);
  for (int i = t; i >= 1; i--)
    if (!used[sta[i]]) {
      ++s;
      SccDfs2(sta[i]);
    }
  for (int i = 1; i <= n; i++)
    if (ans2[i] == -2) DfsNeg(i);
  for (int i = 1; i <= s; i++)
    if (scc[i].size() > 1) {
      int vsz = scc[i].size();
      for (int j = 0; j < vsz; j++)
        if (ans2[scc[i][j]] != -2) DfsNeg(scc[i][j]);
    }
  memset(used, 0, sizeof used);
  for (int i = 1; i <= n; i++)
    if (!used[i] && ans1[i] != 1 << 30 && ans2[i] != -2) DP(i);
}
void SolveMin() {
  priority_queue<pair<int, int> > heap;
  for (int i = 1; i <= n; i++) ans1[i] = 1 << 30;
  for (int i = 1; i <= m; i++) cnt[i] = dia[i];
  for (int i = 1; i <= m; i++)
    if (!sz[i] && dia[i] < ans1[id[i]]) {
      heap.push(pair<int, int>(-dia[i], id[i]));
      ans1[id[i]] = dia[i];
    }
  while (!heap.empty()) {
    pair<int, int> tmp = heap.top();
    heap.pop();
    int node = tmp.second;
    int dist = -tmp.first;
    if (ans1[node] < dist) continue;
    for (int i = 0; i < (int)adj1[node].size(); i++) {
      int x = adj1[node][i];
      sz[x]--;
      cnt[x] = min(314000000, cnt[x] + ans1[node]);
      if (sz[x] == 0 && cnt[x] < ans1[id[x]]) {
        ans1[id[x]] = cnt[x];
        heap.push(pair<int, int>(-cnt[x], id[x]));
      }
    }
  }
}
void Read() {
  scanf("%d%d", &m, &n);
  for (int i = 1, x; i <= m; i++) {
    scanf("%d", &id[i]);
    adj0[id[i]].push_back(i);
    scanf("%d", &x);
    for (int j = 1, y; j <= x; j++) {
      scanf("%d", &y);
      if (y == -1)
        dia[i]++;
      else {
        adj1[y].push_back(i);
        adj2[i].push_back(y);
        sz[i]++;
      }
    }
  }
}
int main() {
  Read();
  SolveMin();
  SolveMax();
  for (int i = 1; i <= n; i++) {
    if (ans1[i] == 1 << 30)
      printf("-1 -1\n");
    else
      printf("%d %d\n", ans1[i], ans2[i]);
  }
  return 0;
}
