#include <bits/stdc++.h>
using namespace std;
long long rdtsc() {
  long long tmp;
  asm("rdtsc" : "=A"(tmp));
  return tmp;
}
inline int myrand() { return abs((rand() << 15) ^ rand()); }
inline int rnd(int x) { return myrand() % x; }
struct Push {
  int vid;
  vector<pair<int, int> > a;
  int read() {
    int cnt;
    if (scanf("%d%d", &vid, &cnt) < 2) return 0;
    --vid;
    a.clear();
    vector<int> cur;
    for (int i = 0; i < cnt; ++i) {
      int x;
      assert(scanf("%d", &x) == 1);
      if (x != -1) --x;
      cur.push_back(x);
    }
    sort(cur.begin(), cur.end());
    for (int i = 0; i < ((int)(cur).size());) {
      int i0 = i;
      while (i < ((int)(cur).size()) && cur[i] == cur[i0]) ++i;
      a.push_back(make_pair(cur[i0], i - i0));
    }
    return 1;
  }
};
const int maxn = (int)1e5 + 10;
Push pushes[maxn];
int cnt[maxn];
int st[maxn];
vector<vector<pair<int, int> > > back;
int dead[maxn];
vector<vector<int> > es, esrev;
int perm[maxn];
int used[maxn];
int pcnt;
void dfs1(int v) {
  used[v] = 1;
  for (int it = 0; it < ((int)(es[v]).size()); ++it) {
    int u = es[v][it];
    if (used[u]) continue;
    dfs1(u);
  }
  perm[pcnt++] = v;
}
int myisinf[maxn];
void dfs2(int v, bool alone = 1) {
  used[v] = 1;
  for (int it = 0; it < ((int)(esrev[v]).size()); ++it) {
    int u = esrev[v][it];
    if (used[u]) {
      if (u == v) alone = 0;
      continue;
    }
    alone = 0;
    dfs2(u, alone);
  }
  if (!alone) myisinf[v] = 1;
}
void dfs3(int v) {
  used[v] = 1;
  myisinf[v] = 1;
  for (int it = 0; it < ((int)(esrev[v]).size()); ++it) {
    int u = esrev[v][it];
    if (used[u]) continue;
    dfs3(u);
  }
}
int myleft[maxn];
int d[maxn];
int mins[maxn];
int values[maxn];
bool solve() {
  int m, n;
  if (scanf("%d%d", &m, &n) < 2) return 0;
  back = vector<vector<pair<int, int> > >(n);
  for (int i = 0; i < m; ++i) {
    assert(pushes[i].read());
    for (int j = 0; j < ((int)(pushes[i].a).size()); ++j)
      if (pushes[i].a[j].first != -1)
        back[pushes[i].a[j].first].push_back(
            make_pair(i, pushes[i].a[j].second));
  }
  for (int i = 0; i < m; ++i) cnt[i] = ((int)(pushes[i].a).size()) - 1;
  for (int i = 0; i < n; ++i) dead[i] = 1;
  int r = 0;
  for (int i = 0; i < m; ++i) {
    if (cnt[i] == 0) st[r++] = i;
  }
  for (int l = 0; l < r; ++l) {
    int id = st[l];
    int vid = pushes[id].vid;
    if (!dead[vid]) continue;
    dead[vid] = 0;
    for (int it = 0; it < ((int)(back[vid]).size()); ++it) {
      int curid = back[vid][it].first;
      if (--cnt[curid] == 0) st[r++] = curid;
    }
  }
  es = esrev = vector<vector<int> >(n);
  for (int i = 0; i < m; ++i) {
    if (cnt[i] > 0) continue;
    for (int j = 0; j < ((int)(pushes[i].a).size()); ++j) {
      int s = pushes[i].vid;
      int t = pushes[i].a[j].first;
      if (t == -1) continue;
      es[s].push_back(t);
      esrev[t].push_back(s);
    }
  }
  for (int i = 0; i < n; ++i) used[i] = 0, myisinf[i] = 0;
  pcnt = 0;
  for (int i = 0; i < n; ++i) {
    if (dead[i]) {
      assert(!((int)(es[i]).size()));
      continue;
    }
    if (!used[i]) dfs1(i);
  }
  for (int i = 0; i < n; ++i) used[i] = 0;
  for (int i = pcnt - 1; i >= 0; --i) {
    int v = perm[i];
    if (!used[v]) dfs2(v);
  }
  for (int i = 0; i < n; ++i) used[i] = 0;
  for (int i = 0; i < n; ++i)
    if (myisinf[i] && !used[i]) dfs3(i);
  vector<vector<int> > from(n);
  for (int i = 0; i < m; ++i) {
    if (cnt[i] > 0) continue;
    from[pushes[i].vid].push_back(i);
  }
  for (int i = 0; i < n; ++i) d[i] = -1;
  for (int i = 0; i < pcnt; ++i) {
    int v = perm[i];
    assert(!dead[v]);
    if (myisinf[v]) continue;
    long long res = 0;
    for (int it = 0; it < ((int)(from[v]).size()); ++it) {
      int id = from[v][it];
      long long value = 0;
      for (int j = 0; j < ((int)(pushes[id].a).size()); ++j) {
        int who = pushes[id].a[j].first, times = pushes[id].a[j].second;
        if (who == -1)
          value += times;
        else {
          assert(d[who] != -1);
          value += (long long)d[who] * times;
        }
      }
      res = max(res, value);
    }
    assert(res != 0);
    res = min(res, (long long)((int)314 * (int)1e6));
    d[v] = (int)res;
  }
  priority_queue<pair<int, int> > tree;
  for (int i = 0; i < n; ++i) {
    if (dead[i]) continue;
    mins[i] = ((int)314 * (int)1e6);
    used[i] = 0;
  }
  r = 0;
  for (int i = 0; i < m; ++i) {
    if (cnt[i] > 0) continue;
    myleft[i] = ((int)(pushes[i].a).size()) - 1;
    values[i] = 0;
    for (int j = 0; j < ((int)(pushes[i].a).size()); ++j)
      if (pushes[i].a[j].first == -1) values[i] += pushes[i].a[j].second;
    if (myleft[i] == 0)
      mins[pushes[i].vid] = min(mins[pushes[i].vid], values[i]);
  }
  for (int i = 0; i < n; ++i)
    if (!dead[i]) tree.push(make_pair(-mins[i], i));
  while (!tree.empty()) {
    pair<int, int> top = tree.top();
    int v = top.second;
    tree.pop();
    if (-mins[v] != top.first) continue;
    assert(!used[v]);
    used[v] = 1;
    for (int it = 0; it < ((int)(back[v]).size()); ++it) {
      int id = back[v][it].first;
      if (cnt[id] > 0) continue;
      long long cur = values[id];
      cur += (long long)back[v][it].second * mins[v];
      cur = min(cur, (long long)((int)314 * (int)1e6));
      values[id] = cur;
      --myleft[id];
      if (myleft[id] == 0) {
        int nv = pushes[id].vid;
        if (mins[nv] > values[id]) {
          mins[nv] = values[id];
          tree.push(make_pair(-mins[nv], nv));
        }
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    if (dead[i]) {
      printf("-1 -1\n");
      continue;
    }
    assert(used[i]);
    if (!myisinf[i]) assert(mins[i] <= d[i]);
    printf("%d %d\n", mins[i], myisinf[i] ? -2 : d[i]);
  }
  return 1;
}
int main() {
  srand(rdtsc());
  while (1) {
    if (!solve()) break;
  }
  return 0;
}
