rt
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
struct node
{
__int128 p,q;
}ans[N];
int n,m,k,u,in_val[N];
vector<int>edge[N];
void paint(__int128 a)
{
if(a==0)return;
paint(a/10);
putchar(char(a%10+'0'));
}
int gcd(int x,int y)
{
if(x>y)swap(x,y);
if(x==0)return y;
return gcd(x,y%x);
}
void build(int u,int v)
{
edge[u].push_back(v);
in_val[v]++;
}
void yuefen(node &x)
{
int Gcd=gcd(x.p,x.q);
x.p/=Gcd,x.q/=Gcd;
}
void tongfen(node &x,node &y)
{
int Gcd=gcd(x.q,y.q),Lcm=x.q/Gcd*y.q;
x.p*=Lcm/x.q,y.p*=Lcm/y.q;
x.q=y.q=Lcm;
}
void BFS()
{
queue<int>que;
for(int i=1;i<=m;i++)
{
ans[i]=(node){1,1};
que.push(i);
}
for(int i=m+1;i<=n;i++)
ans[i]=(node){0,1};
while(!que.empty())
{
int u=que.front();
node tmp=ans[u];
que.pop();
tmp.q*=edge[u].size();
for(auto v:edge[u])
{
tongfen(tmp,ans[v]);
in_val[v]--;
if(in_val[v]==0)que.push(v),in_val[v]--;
ans[v].p+=tmp.p;
yuefen(tmp),yuefen(ans[v]);
}
if(!edge[u].empty())ans[u]=(node){0,1};
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>k;
for(int j=1;j<=k;j++)
cin>>u,build(i,u);
}
BFS();
for(int i=1;i<=n;i++)
{
if(edge[i].empty())
{
paint(ans[i].p);
putchar(' ');
paint(ans[i].q);
putchar('\n');
}
}
return 0;
}