#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#define MAXN 1000010
#define Inf 0x3f3f3f3f
using namespace std;
inline int read(){
int sum=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')sum=(sum<<1)+(sum<<3)+ch-'0',ch=getchar();
return sum;
}
struct Via{
int to,next,w;
}c[MAXN<<1];
int head[MAXN],t,Ans_Max,Ans_Min,n;
long long f[MAXN][2];
int F[MAXN][2][2];
int Aim[MAXN];
int dfn[MAXN],low[MAXN],stack[MAXN],top,Time,num;
bool in[MAXN],special[MAXN];
vector<int> member[MAXN];
inline long long Min(long long x,long long y){
return x<y?x:y;
}
inline long long Max(long long x,long long y){
return x>y?x:y;
}
inline void add(int x,int y,int z){
c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].w=z;
}
inline void Tarjan(int x){
dfn[x]=low[x]=++Time,stack[++top]=x,in[x]=1;
for(int i=head[x];i;i=c[i].next)
if(c[i].w){
if(!dfn[c[i].to]){
Tarjan(c[i].to),low[x]=Min(low[x],low[c[i].to]);
}else if(in[c[i].to])
low[x]=Min(low[x],dfn[c[i].to]);
}
if(dfn[x]==low[x]){
int j;num++;
do{
j=stack[top--],in[j]=0,member[num].push_back(j),special[j]=1;
}while(j!=x);
if(member[num].size()==1&&Aim[j]!=j){
member[num].clear(),num--,special[j]=0;
}
}
}
inline void dfs(int x,int &sum){
int J=0;
for(int i=head[x];i;i=c[i].next)
if(c[i].w==0&&special[c[i].to]==0){
dfs(c[i].to,sum),f[x][1]+=f[c[i].to][0],f[x][0]+=Max(f[c[i].to][1],f[c[i].to][0]),J++;
}sum++;
if(J==0&&special[x]==0){ f[x][1]=0,f[x][0]=-Inf; }
else f[x][0]+=1;
}
inline int Do_It(int No_){
int len=member[No_].size(),sum=0;
for(int i=0;i<len;i++)dfs(member[No_][i],sum);
if(len==1)return f[member[No_][0]][0];
else{
if(sum==len)return len-1;
F[1][1][1]=f[member[No_][0]][1]<0?-1:f[member[No_][0]][1],F[1][0][1]=-1,F[1][0][0]=f[member[No_][0]][0],F[1][1][0]=-1;
for(int i=1;i<len-1;i++){
F[i+1][1][1]=(F[i][0][1]==-1||f[member[No_][i]][1]<0)?-1:(F[i][0][1]+f[member[No_][i]][1]);
F[i+1][0][1]=((F[i][0][1]==-1&&F[i][1][1]==-1)||f[member[No_][i]][0]<0)?-1:(Max(F[i][1][1],F[i][0][1])+f[member[No_][i]][0]);
F[i+1][1][0]=(F[i][0][0]==-1||f[member[No_][i]][1]<0)?-1:(F[i][0][0]+f[member[No_][i]][1]);
F[i+1][0][0]=((F[i][0][0]==-1&&F[i][1][0]==-1)||f[member[No_][i]][0]<0)?-1:(Max(F[i][1][0],F[i][0][0])+f[member[No_][i]][0]);
}
register int ans=F[len-1][0][0]+Max(f[member[No_][len-1]][1],f[member[No_][len-1]][0]);
if(F[len-1][0][1]!=-1)ans=Max(ans,F[len-1][0][1]+f[member[No_][len-1]][0]);
if(F[len-1][1][0]!=-1)ans=Max(ans,F[len-1][1][0]+f[member[No_][len-1]][0]);
if(F[len-1][1][1]!=-1)ans=Max(ans,F[len-1][1][1]+f[member[No_][len-1]][0]);
return ans;
}
}
inline void Dfs(int x){
int J=0;
for(int i=head[x];i;i=c[i].next)
if(c[i].w==0&&special[c[i].to]==0){
Dfs(c[i].to),f[x][1]+=f[c[i].to][0],f[x][0]+=Min(f[c[i].to][1],f[c[i].to][0]),J++;
}
if(J==0&&special[x]==0){ f[x][1]=0,f[x][0]=Inf; }
else f[x][0]+=1;
}
inline int Cao_It(int No_)
{
register int len=member[No_].size();
for(int i=0;i<len;i++)Dfs(member[No_][i]);
if(len==1)return f[member[No_][0]][0];
else{
F[1][1][1]=f[member[No_][0]][1]>=Inf?Inf:f[member[No_][0]][1],F[1][0][1]=Inf,F[1][0][0]=f[member[No_][0]][0],F[1][1][0]=Inf;
for(int i=1;i<len-1;i++){
F[i+1][1][1]=(F[i][0][1]==Inf||f[member[No_][i]][1]>=Inf)?Inf:(F[i][0][1]+f[member[No_][i]][1]);
F[i+1][0][1]=((F[i][0][1]==Inf&&F[i][1][1]==Inf)||f[member[No_][i]][0]>=Inf)?Inf:(Min(F[i][1][1],F[i][0][1])+f[member[No_][i]][0]);
F[i+1][1][0]=(F[i][0][0]==Inf||f[member[No_][i]][1]>=Inf)?Inf:(F[i][0][0]+f[member[No_][i]][1]);
F[i+1][0][0]=((F[i][0][0]==Inf&&F[i][1][0]==Inf)||f[member[No_][i]][0]>=Inf)?Inf:(Min(F[i][1][0],F[i][0][0])+f[member[No_][i]][0]);
}
int ans=F[len-1][0][0]+Min(f[member[No_][len-1]][1],f[member[No_][len-1]][0]);
if(F[len-1][0][1]!=Inf)ans=Min(ans,F[len-1][0][1]+f[member[No_][len-1]][0]);
if(F[len-1][1][0]!=Inf)ans=Min(ans,F[len-1][1][0]+f[member[No_][len-1]][0]);
if(F[len-1][1][1]!=Inf)ans=Min(ans,F[len-1][1][1]+f[member[No_][len-1]][0]);
return ans;
}
}
inline void Init(){
n=read();for(int i=1;i<=n;i++)Aim[i]=read(),add(i,Aim[i],1),add(Aim[i],i,0);
for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i);
}
inline void Work(){
for(int i=1;i<=num;i++)Ans_Max+=Do_It(i);
memset(f,0,sizeof(f));for(int i=1;i<=num;i++)Ans_Min+=Cao_It(i);
printf("%d %d",Ans_Min,Ans_Max);
}
int main(){
Init();
Work();
return 0;
}