#include <bits/stdc++.h>
using namespace std;
const int MAX_N=100005;
const int B=350;
struct DC
{
int d,count;
};
vector<int> adj[MAX_N];
int pref[MAX_N];
int st[MAX_N];
int ed[MAX_N];
int depth[MAX_N];
int sz[MAX_N];
int heavy[MAX_N];
int node[MAX_N];
int subtree[MAX_N];
int timer=0;
int n,k;
vector<int> dn[MAX_N];
vector<int> nodes[MAX_N];
int ap[MAX_N];
int ai[MAX_N];
int counter[MAX_N];
vector<DC> cg[MAX_N];
int cur[MAX_N];
int cpv,tg;
int tc[MAX_N];
bool is[MAX_N];
void prep(int u, int d)
{
st[u]=++timer;
node[timer]=u;
depth[u]=d;
sz[u]=1;
subtree[u]=d;
dn[d].push_back(st[u]);
heavy[u]=-1;
int xsz=-1;
for(int v : adj[u])
{
prep(v,d+1);
sz[u]+=sz[v];
subtree[u]=max(subtree[u],subtree[v]);
if(sz[v]>xsz)
{
xsz=sz[v];
heavy[u]=v;
}
}
ed[u]=timer;
}
inline void add(int u)
{
int d=depth[u];
if(is[d])
{
if(cur[d]<tc[d])
{
cpv++;
}
}
cur[d]++;
}
inline void remove(int u)
{
int d=depth[u];
cur[d]--;
if(is[d])
{
if(cur[d]<tc[d])
{
cpv--;
}
}
}
void dsu(int u, bool keep)
{
for(int v : adj[u])
{
if(v!=heavy[u])
{
dsu(v,false);
}
}
if(heavy[u]!=-1)
{
dsu(heavy[u],true);
}
for(int v : adj[u])
{
if(v!=heavy[u])
{
for(int t=st[v]; t<=ed[v]; t++)
{
add(node[t]);
}
}
}
add(u);
if(pref[u]==tg)
{
ap[u]=cpv;
}
if(!keep)
{
for(int t=st[u]; t<=ed[u]; t++)
{
remove(node[t]);
}
}
}
void dfs(int u)
{
int before=counter[pref[u]];
for(int v : adj[u])
{
dfs(v);
}
counter[pref[u]]++;
ai[u]=counter[pref[u]]-before;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin>>n>>k;
for(int i=0; i<n; i++)
{
cin>>pref[i];
nodes[pref[i]].push_back(i);
}
for(int i=1; i<n; i++)
{
int p;
cin>>p;
adj[p].push_back(i);
}
prep(0,0);
dfs(0);
for(int g=0; g<k; g++)
{
if(nodes[g].empty())
{
continue;
}
vector<int> dl;
for(int u : nodes[g])
{
dl.push_back(depth[u]);
}
sort(dl.begin(),dl.end());
for(int i=0; i<(int)dl.size(); )
{
int d=dl[i];
int c=0;
while(i<(int)dl.size() && dl[i]==d)
{
c++;
i++;
}
cg[g].push_back({d,c});
}
}
for(int g=0; g<k; g++)
{
if(nodes[g].empty())
{
continue;
}
if((int)nodes[g].size()<=B)
{
for(int u : nodes[g])
{
int p=0;
auto it=lower_bound(cg[g].begin(),cg[g].end(),depth[u], [](const DC& a, int v)
{
return a.d<v;
});
for(; it!=cg[g].end(); it++)
{
if(it->d>subtree[u])
{
break;
}
auto& v=dn[it->d];
int s=upper_bound(v.begin(),v.end(),ed[u])-lower_bound(v.begin(),v.end(),st[u]);
p+=min(s,it->count);
}
ap[u]=p;
}
}
else
{
tg=g;
cpv=0;
for(auto& dc : cg[g])
{
is[dc.d]=true;
tc[dc.d]=dc.count;
}
dsu(0,false);
for(auto& dc : cg[g])
{
is[dc.d]=false;
}
}
}
int xp=-1;
int ns=2e9;
for(int i=0; i<n; i++)
{
if(ap[i]>xp)
{
xp=ap[i];
ns=ap[i]-ai[i];
}
else if(ap[i]==xp)
{
ns=min(ns,ap[i]-ai[i]);
}
}
cout<<xp<<" "<<ns<<endl;
return 0;
}