#include<bits/stdc++.h>
#define int __int128
using namespace std;
const int N = 2e5+10;
struct node {
int fz, fm;
};
struct nodd {
int to;
node val;
};
vector<nodd> edge[N];
int n, m;
node fenshu(int fz1, int fm1, int fz2, int fm2) {
int fmp = __gcd(fm1, fm2);
if(fm1*fm2==0){
return {0,1};
}
int fm = fm1 / fmp*fm2;
int fz = fm / fm1*fz1 + fm / fm2*fz2;
int opt = __gcd(fm, fz);
if(opt==0){
return {0,1};
}
fm /= opt;
fz /= opt;
return {fz, fm};
}
node cheng(node a, int k) {
if (k == 0) {
return a;
}
int fm, fz;
fz = a.fz;
fm = a.fm*k;
int opt = __gcd(fm, fz);
if(opt==0){
return {0,1};
}
fm /= opt;
fz /= opt;
return {fz, fm};
}
bool mark[N];
int d[N];
node val[N];
vector<node> answer;
vector<int> ru[N];
node work(int k) {
if (k <= m) {
return {1, 1};
}
node ans = {0, 1};
for (int i = 0; i < ru[k].size(); i++) {
ans = fenshu(ans.fz, ans.fm, val[ru[k][i]].fz, val[ru[k][i]].fm);
}
return ans;
}
void dfs(int k, node ans) {
if (k == n || d[k] == 0) {
ans = work(k);
answer.push_back(ans);
return;
}
int Chu = 0;
for (int i = 0; i < edge[k].size(); i++) {
if (mark[edge[k][i].to] == 0) {
Chu++;
}
}
if (Chu == 0) {
answer.push_back(ans);
return;
}
for (int i = 0; i < edge[k].size(); i++) {
if (mark[edge[k][i].to] == 0) {
ans = work(k);
node opt = cheng(ans, Chu);
val[k] = opt;
mark[edge[k][i].to] = 1;
dfs(edge[k][i].to, opt);
mark[edge[k][i].to] = 0;
}
}
return;
}
inline bool input (int &x) {
x = 0;
int f = 1;
char c = getchar ();
while (!isdigit (c)) {
c = getchar ();
}
while (isdigit (c)) {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar ();
}
x *= f;
return x;
}
inline bool output (int x) {
if (x < 0) {
putchar ('-');
x = -x;
}
char write[200], cnt = 0;
do {
write[++ cnt] = x % 10;
x /= 10;
} while (x);
do {
putchar (write[cnt --] | 48);
} while (cnt);
return x;
}
vector<int> chu;
signed main() {
freopen("water.in","r",stdin);
freopen("water.out","w",stdout);
input(n);
input(m);
for (int i = 1; i <= n; i++) {
input(d[i]);
if (d[i] == 0) {
chu.push_back(i);
}
for (int j = 1; j <= d[i]; j++) {
int u;
input(u);
ru[u].push_back(i);
edge[i].push_back({u, {0, 1}});
}
}
mark[1] = 1;
for (int i = m; i <= n; i++) {
val[i] = {0, 1};
}
for(int i=1;i<=m;i++) mark[1] = 1,dfs(i, {1, 1});
for (int j = 0; j < chu.size(); j++) {
node opt = work(chu[j]);
output(opt.fz);
cout << " ";
output(opt.fm);
cout << endl;
}
return 0;
}