This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
 
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);cerr.tie(0)
#define mp make_pair
#define xx first
#define yy second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(x) x.begin(),x.end()
#define ff(i,a,b) for (int i = a; i < b; i++)
#define fff(i,a,b) for (int i = a; i <= b; i++)
#define bff(i,a,b) for (int i = b-1; i >= a; i--)
#define bfff(i,a,b) for (int i = b; i >= a; i--)
 
using namespace std;
long double typedef ld;
unsigned int typedef ui;
long long int typedef li;
pair<int,int> typedef pii;
pair<li,li> typedef pli;
pair<ld,ld> typedef pld;
vector<vector<int>> typedef graph;
unsigned long long int typedef ull;
//const int mod = 998244353;
const int mod = 1000000007;
 
 
 
 
 
 
 
//Note to self: Check for overflow
 
graph g(200005);
int toindexhelpminus1[1284];
int dub[200005];
set<pii> active;
set<int> tinta;
 
int up[20][200005];
int tin[200005],tout[200005],koji[200005];
int VREME=0;
 
void dfs(int p, int q)
{
    dub[p]=dub[q]+1,tin[p]=++VREME,up[0][p]=max(0,q),koji[VREME]=p;
    for (auto it : g[p]) if (it!=q) dfs(it,p);
    tout[p]=VREME;
}
 
void build(int n)
{
    ff(k,1,20) ff(i,0,n) up[k][i]=up[k-1][up[k-1][i]];
}
 
bool anc(int a, int b)
{
    return tin[a]<=tin[b] && tout[a]>=tout[b];
}
 
int Lca(int a, int b)
{
    bff(k,0,20) if (!anc(up[k][a],b)) a=up[k][a];
    if (!anc(a,b)) a=up[0][a]; return a;
}
 
int dist(int a, int b)
{
    int c=Lca(a,b);
    return dub[a]+dub[b]-2*dub[c];
}
 
int find_closest(int p)
{
    auto kad=tinta.lower_bound(tin[p]);
    if (kad==tinta.end()) kad=tinta.begin();
 
    if (*kad==tin[p]) return p;
    auto posle=kad;
    auto pre=posle;
    if (kad==tinta.begin()) pre=prev(tinta.end());
    else pre=prev(kad);
 
    if (dist(p,koji[*pre]) < dist(p,koji[*posle])) return koji[*pre];
    return koji[*posle];
}
 
void kill(int p, int q, int d)
{
    active.erase({-dub[p],p});
    if (d>1) for (auto it : g[p]) if (it!=q) kill(it,p,d-1);
}
 
int main()
{
    FAST;
 
    int n,D; cin>>n>>D;
    ff(i,1,n)
    {
        int p; cin>>p;
        g[p].pb(i),g[i].pb(p);
    }
 
    int ans=0;
    dub[-1]=0;
 
    dfs(0,-1),tout[0]=VREME,build(n);
    ff(i,0,n) active.insert({-dub[i],i});
    ff(i,0,n) tinta.insert(tin[i]);
 
    while (!active.empty())
    {
        int p=active.begin()->yy;
 
        while (!active.empty())
        {
            int q=find_closest(p);
            if (dist(p,q)<D) active.erase({-dub[q],q}),tinta.erase(tin[q]);
            else break;
        }
 
        ans++;
    }
 
    cout<<ans<<"\n";
}
 
//Note to self: Check for overflow
Compilation message (stderr)
catinatree.cpp: In function 'int Lca(int, int)':
catinatree.cpp:67:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
   67 |     if (!anc(a,b)) a=up[0][a]; return a;
      |     ^~
catinatree.cpp:67:32: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
   67 |     if (!anc(a,b)) a=up[0][a]; return a;
      |                                ^~~~~~
catinatree.cpp: In function 'int main()':
catinatree.cpp:109:11: warning: array subscript -1 is below array bounds of 'int [200005]' [-Warray-bounds]
  109 |     dub[-1]=0;
      |     ~~~~~~^
catinatree.cpp:39:5: note: while referencing 'dub'
   39 | int dub[200005];
      |     ^~~| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |