#include<bits/stdc++.h>
using namespace std;
int n,m;
vector<int>edge[100005];
int dfn[105];
int low[105];
int cnt,cntb;
stack<int>s;
bool instack[105];
vector<int>belong[105];
int b[105];
bool ind[105],oud[105];
void tarjan(int u){
cnt++;
dfn[u]=low[u]=cnt;
s.push(u);
instack[u]=1;
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
cntb++;
int node;
do{
node=s.top();
s.pop();
instack[node]=0;
belong[cntb].push_back(node);
b[node]=cntb;
}while(node!=u);
}
}
int main(){
cin>>n>>m;
for(int u=1;u<=n;u++){
int v;
while(1){
cin>>v;
if(v==0)break;
edge[u].push_back(v);
}
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(i);
}
}
if(cntb==1){
cout<<1<<endl<<0;
return 0;
}
for(int u=1;u<=n;u++){
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i];
if(b[u]!=b[v]){
ind[b[v]]=1;
oud[b[u]]=1;
}
}
}
int c1=0,c2=0;
for(int i=1;i<=cntb;i++){
if(!ind[i]){
c1++;
}
if(!oud[i]){
c2++;
}
}
cout<<c1<<endl<<max(c1,c2);
return 0;
}