#pragma GCC optimize ("O2")
#pragma GCC target ("avx2")
//#include<bits/stdc++.h>
//#include<atcoder/all>
//using namespace atcoder;
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

int P[100001];
int sei[100001], fu[100001], kisuu[100001], ind[100001], kazu[100001], kazu2[100001];

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);


	int N;
	cin >> N;
	rep1(i, N - 1) {
		cin >> P[i + 1];
		kazu[P[i + 1]]++;
	}
	rep(i, N) kazu2[i + 1] = (kazu[i + 1] += kazu[i]);

	for (int i = N; i >= 2; i--) {
		int ret = sei[i] - 1;

		auto ki = kisuu + kazu[i - 1];
		int sz = kazu2[i - 1] - kazu[i - 1];
		sort(ki, ki + sz);

		if (sz & 1) {
			ret -= fu[i];
			rep(j, sz) {
				if (j & 1) ret -= ki[j];
				else ret += ki[j];
			}
		}
		else {
			ret += fu[i];
			rep(j, sz) {
				if (j & 1) ret += ki[j];
				else ret -= ki[j];
			}
		}

		if (ret & 1) {
			kisuu[kazu2[P[i] - 1]++] = ret;
		}
		else {
			if (ret >= 0) sei[P[i]] += ret;
			else fu[P[i]] += ret;
		}
	}

	int ret = sei[1] - 1;

	auto ki = kisuu + kazu[0];
	int sz = kazu2[0] - kazu[0];
	sort(ki, ki + sz);

	if (sz & 1) {
		ret -= fu[1];
		rep(j, sz) {
			if (j & 1) ret -= ki[j];
			else ret += ki[j];
		}
	}
	else {
		ret += fu[1];
		rep(j, sz) {
			if (j & 1) ret += ki[j];
			else ret -= ki[j];
		}
	}

	co((N - ret) / 2);

	Would you please return 0;
}
// Problem: C - DFS Game
// Contest: AtCoder - AtCoder Regular Contest 112
// URL: https://atcoder.jp/contests/arc112/tasks/arc112_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <cstdio>
#include <set>

const int maxn = 1e5 + 19;

struct Edge{
	int to, next;
}edge[maxn];

int head[maxn], cnt;

inline void add(int from, int to){
	edge[++cnt].to = to;
	edge[cnt].next = head[from];
	head[from] = cnt;
}

int n, dp[maxn][2], size[maxn];

std::multiset<int> s;
void dfs(int node){
	int odd = 0;
	size[node] = 1;
	for(int i = head[node]; i; i = edge[i].next)
		dfs(edge[i].to), size[node] += size[edge[i].to], odd += size[edge[i].to] & 1;
	for(int now = 0; now < 2; ++now){
		s.clear();
		dp[node][now] = now & 1;
		for(int i = head[node]; i; i = edge[i].next)
			if(size[edge[i].to] & 1){
				dp[node][now] += dp[edge[i].to][now];
				s.insert(dp[edge[i].to][now ^ 1] - dp[edge[i].to][now]);
			}
			else{
				if((dp[edge[i].to][now] < dp[edge[i].to][now ^ 1]) == (now & 1)) dp[node][now] += dp[edge[i].to][now];
				else if(odd & 1) dp[node][now] += dp[edge[i].to][now ^ 1];
				else dp[node][now] += dp[edge[i].to][now];
			}
		int sz = s.size();
		if(!(now & 1))
			for(int i = 1; i <= sz; ++i)
				if(i & 1) s.erase(s.find(*s.begin()));
				else dp[node][now] += *s.begin(), s.erase(s.find(*s.begin()));
		else
			for(int i = 1; i <= sz; ++i)
				if(i & 1) s.erase(s.find(*--s.end()));
				else dp[node][now] += *--s.end(), s.erase(s.find(*--s.end()));
	}
}

int main(){
	scanf("%d", &n);
	for(int i = 2, p; i <= n; ++i){
		scanf("%d", &p);
		add(p, i);
	}
	dfs(1); printf("%d\n", dp[1][1]);
}