#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int n,m;
int nex[1000005][6];
int in[1000005];
int anss[1000005];
struct water
{
unsigned long long int a,b;
}w[1000005],ans;
stack<int> s;
int order[1000005];
void add(int a,int b,int c,int d)
{
ans.a=a*d+c*b;
ans.b=b*d;
}
void simplify()
{
unsigned long long int common=max(ans.a,ans.b)%min(ans.a,ans.b);
unsigned long long int last=min(ans.a,ans.b);
while(common!=0)
{
unsigned long long int tmp=common;
common=last%common;
last=tmp;
}
ans.a/=last;
ans.b/=last;
}
void flow(int from,int to,int d)
{
water tmp,original;
tmp.a=w[from].a;
tmp.b=(w[from].b)*d;
if(w[to].b==0)
{
original.a=0;
original.b=1;
}
else
{
original.a=w[to].a;
original.b=w[to].b;
}
add(tmp.a,tmp.b,original.a,original.b);
simplify();
w[to].a=ans.a;
w[to].b=ans.b;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int d=0;
scanf("%d",&d);
nex[i][0]=d;
for(int q=1;q<=d;q++)
{
int a;
scanf("%d",&a);
nex[i][q]=a;
in[a]++;
}
}
for(int i=1;i<=n;i++)
{
if(in[i]==0)
{
s.push(i);
order[0]++;
order[order[0]]=i;
w[i].a=1;
w[i].b=1;
}
}
while(!s.empty())
{
int now=s.top();
s.pop();
if(nex[now][0]==0)
{
anss[0]++;
anss[anss[0]]=now;
continue;
}
for(int i=1;i<=nex[now][0];i++)
{
int t=nex[now][i];
flow(now,t,nex[now][0]);
in[t]--;
if(in[t]==0)
{
s.push(t);
}
}
}
sort(anss+1,anss+1+anss[0]);
for(int i=1;i<=anss[0];i++)
{
ans.a=w[anss[i]].a;
ans.b=w[anss[i]].b;
simplify();
printf("%lld %lld\n",ans.a,ans.b);
}
return 0;
}