#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 110;
const int MAXM = 10100;
struct EdgeNode
{
int to;
int next;
}Edges[MAXM];
int Head[MAXN],vis[MAXN],low[MAXN];
int dfn[MAXN],Stack[MAXN],indegree[MAXN],outdegree[MAXN];
int Count[MAXN],m,id;
void AddEdges(int u,int v)
{
Edges[id].to = v;
Edges[id].next = Head[u];
Head[u] = id++;
}
int TarBFS(int pos,int lay,int &scc)
{
vis[pos] = 1;
low[pos] = dfn[pos] = lay;
Stack[++m] = pos;
for(int i = Head[pos]; i != -1; i = Edges[i].next)
{
if(!vis[Edges[i].to])
TarBFS(Edges[i].to,++lay,scc);
if(vis[Edges[i].to] == 1)
low[pos] = min(low[pos],low[Edges[i].to]);
}
if(dfn[pos] == low[pos])
{
++scc;
do
{
Count[scc]++;
low[Stack[m]] = scc;
vis[Stack[m]] = 2;
}while(Stack[m--] != pos);
}
return 0;
}
void Tarjan(int N)
{
int scc, temp, lay;
scc = temp = m = 0;
lay = 1;
memset(vis,0,sizeof(vis));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
for(int i = 1; i <= N; ++i)
if(vis[i] == 0)
TarBFS(i,lay,scc);
for(int i = 1; i <= N; ++i)
{
for(int j = Head[i]; j != -1; j = Edges[j].next)
if(low[i] != low[Edges[j].to])
{
outdegree[low[i]]++;
indegree[low[Edges[j].to]]++;
}
}
int SumIn = 0, SumOut = 0;
for(int i = 1; i <= scc; ++i)
{
if(!indegree[i])
SumIn++;
if(!outdegree[i])
SumOut++;
}
if(scc == 1)
printf("1\n0\n");
else
printf("%d\n%d\n", SumIn, max(SumIn,SumOut));
}
int main()
{
int N, v;
while(~scanf("%d", &N))
{
memset(Head,-1,sizeof(Head));
memset(outdegree,0,sizeof(outdegree));
memset(indegree,0,sizeof(indegree));
memset(Count,0,sizeof(Count));
id = 0;
for(int i = 1; i <= N; ++i)
while(scanf("%d",&v) && v)
AddEdges(i,v);
Tarjan(N);
}
return 0;
}