#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int boro = 200005;
ll vag = 1000000007;
int n , a[boro] , tim[boro] , chek[boro] , typ[boro] , one , two , ek , dui , k , ans , ansop;
int depth[boro] , borodepth[boro] , siz[boro] , amar[boro] , shobar[boro] , shuru[boro] , shesh[boro] , here;
int tans , tansop;
vector<int> adj[boro] , koi[boro] ;
deque<int> sizz[boro];
multiset<int> ms;
void dfs( int me ){
shuru[me] = here;
here++;
borodepth[me] = depth[me];
if( ms.find(a[me]) == ms.end() ){
chek[me] = 1;
}
else chek[me] = 0;
ms.insert(a[me]);
for( auto it : adj[me] ){
depth[it] = depth[me] + 1;
dfs( it );
borodepth[me] = max( borodepth[me] , borodepth[it] );
}
ms.erase(ms.find(a[me]));
shesh[me] = here;
}
void getboro( int me , int col ){
siz[depth[me]]++;
if( a[me] == col ) amar[depth[me]]++;
for( auto it : adj[me] ) getboro( it , col );
}
void getchoto( int me ){
for( auto it : adj[me] ){
getchoto( it );
if( (int)sizz[me].size() < (int)sizz[it].size() ) swap( sizz[me] , sizz[it] );
for( int z = 0; z < (int)sizz[it].size(); z++ ){
sizz[me][z] += sizz[it][z];
}
}
sizz[me].push_front(1);
if( tim[a[me]] == 0 && chek[me] == 1 ){
// after each process reset
for( auto it: koi[a[me]] ){
if( (depth[it] >= depth[me]) && (depth[it] <= borodepth[me]) ){
amar[depth[it] - depth[me]] = 0;
shobar[depth[it] - depth[me]] = 0;
}
}
for( auto it: koi[a[me]] ){
if( (depth[it] >= depth[me]) && (depth[it] <= borodepth[me]) ){
shobar[depth[it] - depth[me]]++;
if( shuru[it] >= shuru[me] && shuru[it] <= shesh[me] ) amar[depth[it] - depth[me]]++;
}
}
tans = 0;
tansop = 0;
for( auto it: koi[a[me]] ){
if( (depth[it] >= depth[me]) && (depth[it] <= borodepth[me]) ){
one = depth[it] - depth[me];
if( shobar[one] != 0 ){
int lol = min( sizz[me][one] , shobar[one] );
tans += lol;
tansop += (lol - amar[one]);
shobar[one] = 0;
}
}
}
if( ans < tans ){
ans = tans;
ansop = tansop;
}
else if( ans == tans ) ansop = min( ansop , tansop );
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cin >> n >> k;
for( int z = 0; z < n; z++ ){
cin >> a[z];
koi[a[z]].push_back(z);
tim[a[z]]++;
}
int nn = (int)(sqrt(n));
for( int z = 0; z < k; z++ ){
if( tim[z] >= nn ) typ[z] = 1;
else {
typ[z] = 0; // rememver to consider size 0;
}
}
for( int z = 1; z < n; z++ ){
cin >> one;
adj[one].push_back(z);
}
depth[1] = 1;
here = 0;
dfs( 0 );
ans = (int)koi[a[0]].size();
ansop = 0;
// here is boro check
for( int z = 0; z < k; z++ ){
if( typ[z] == 1 ){
for( int y = 1; y <= n; y++ ){
shobar[y] = 0;
}
for( auto it : koi[z] ){
shobar[depth[it]]++;
}
for( auto it: koi[z] ){
if( chek[it] == 1 ){
for( int y = depth[it]; y <= borodepth[it]; y++ ){
amar[y] = 0;
siz[y] = 0;
}
getboro(it , a[it]);
tans = 0;
tansop = 0;
for( int y = depth[it]; y <= borodepth[it]; y++ ){
int lol = min( siz[y] , shobar[y] );
tans += lol;
tansop += (lol - amar[y]);
}
if( ans < tans ){
ans = tans;
ansop = tansop;
}
else if( ans == tans ) ansop = min( ansop , tansop );
}
}
}
}
getchoto( 0 );
cout << ans << " " << ansop << "\n";
return 0;
}
/*
// sqrt decomp
// process small and big differently
// have 3 - size of depth , what i have , what is total
// get dfs order
// get which ones we need to check with set
// start end
*/