#include <bits/stdc++.h>

using namespace std;

using LL = long long;
using PII = pair<int, int>;
using ll = long long;
using DBL = double;
using VI = vector<int>;
using VD = vector<DBL>;
using VVI = vector<VI>;
using VVD = vector<VD>;
#define FOR(i,a,b) for(int i = a; i < b; i++)
#define REP(i,n) FOR(i,0,n)
#define SZ(a) ((int)((a).size()))
#define ALL(x) (x).begin(), (x).end()
#define SET(a,v) memset((a), (v), sizeof(a))
#define EB emplace_back
#define PB push_back
#define MP make_pair
#define ST first
#define ND second

// #define trace(...) {__f(#__VA_ARGS__, __VA_ARGS__);}
// template<typename Arg> void __f(const char* name, Arg&& arg) {
//   cerr << name << " = " << arg << std::endl;
// } template <typename Arg1, typename... Args>
// void __f(const char* names, Arg1&& arg1, Args&&... args) {
//   const char* comma = strchr(names + 1, ',');
//   cerr.write(names, comma - names) << " = " << arg1<<" | ";__f(comma+1, args...); }
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds; // OST: find_by_order, order_of_key
// typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// #pragma GCC optimize("Ofast")
// optimize("unroll-loops")
// target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// /*** RNGS ***/
// SEED=chrono::steady_clock::now().time_since_epoch().count();
// // or high_resolution_clock
// mt19937 rng(SEED); /*or*/ random_device rd; mt19937 rng(rd());
// uniform_int_distribution<> dis(MIN, MAX);// usage: dis(rng)
// struct chash {int operator()(int x) const {return x^SEED;}};
// gp_hash_table<int,int,chash>m;//use cc if very less updates
// /*** FAST IO ***/
// inline int scan(){ bool y=0; int x=0; char c=getchar_unlocked();
// while(c<'0'||c>'9'){ if(c=='-')y=1; c=getchar_unlocked();}
// while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar_unlocked();}
// return y?-x:x; }

const int MAXN = 200010, MOD = 1000000007;
vector<int> g[MAXN];
int p[MAXN], dph[MAXN], dp1[MAXN], dp0[MAXN];

inline int mul(int a, int b) {
	return (a*1ll*b)%MOD;
}

inline int add(int a, int b) {
	return (a+b>=MOD?a+b-MOD:a+b);
}

inline int sub(int a, int b) {
	return (a>=b?a-b:a-b+MOD);
}

int powmod(int a, int b) {
	int y = 1;
	while(b) {
		if(b&1) y = mul(y, a);
		a = mul(a, a);
		b /= 2;
	}
	return y;
}

int h[MAXN];
VI nodesH[MAXN];
vector <PII> aux[MAXN];  // aux is adjList of auxtree.

void dfs_init(int u, int curH) {
	h[u] = curH;
	nodesH[h[u]].PB(u);
	for(auto&v: g[u]) {
		dfs_init(v, h[u]+1);
	}
}

int cnth(int u, int h, int par) {
	int &y = dph[u];
	if(y != -1) return y;
	y = (::h[u] == h);
	for(auto&z: aux[u]) {
		auto v = z.ST;
		if(v == par) continue;
		y += cnth(v, h, u);
	}
	return y;
}

int calc0(int u, int h, int par);
int calc1(int u, int h, int par);

int calc0(int u, int h, int par) {
	int &y = dp0[u];
	if(y != -1) return y;
	return y = sub(powmod(2, cnth(u, h, par)), calc1(u, h, par));
}

int calc1(int u, int h, int par) {
	int &y = dp1[u];
	if(y != -1) return y;
	if(::h[u] == h) return y = 1;
	if(SZ(aux[u]) == 1) return y = 0;
	VI a;
	for(auto&z: aux[u]) {
		auto v = z.ST;
		if(v == par) continue;
		a.PB(calc0(v, h, u));
	}
	VI pref(SZ(a)), suff(SZ(a));
	pref[0] = a[0];
	for(int i=1; i<SZ(a); ++i) {
		pref[i] = mul(pref[i-1], a[i]);
	}
	suff[SZ(a)-1] = a[SZ(a)-1];
	for(int i=SZ(a)-2; i>=0; --i) {
		suff[i] = mul(suff[i+1], a[i]);
	}
	y = 0;
	int idx = 0;
	for(int i=0; i<SZ(a); ++i) {
		if(aux[u][idx].ST == par) ++idx;
		y = add(y, mul(mul((i==0?1:pref[i-1]), (i==SZ(a)-1?1:suff[i+1])), calc1(aux[u][idx].ST, h, u)));
		++idx;
	}
	return y;
}


const int N = 2e5+10, LOGN = 20;
// clear auxNodes, mark, aux;
// auxNodes contains nodes of current aux tree
VI auxNodes;  // dists is distance from 1 to any node.
int P[LOGN][N], depth[N], timer, st[N], en[N];
bool mark[N]; //mark contains marked nodes
int dists[N];
void dfs0 (int v, int par) {
  P[0][v] = par; st[v] = timer++; //adj list is pair
  for(auto x: g[v]) {
    int u = x;
    if(u == par) continue;
    depth[u] = depth[v] + 1, dists[u] = dists[v] + 1;
    dfs0(u, v);
  } en[v] = timer;//*******set mark = false after all processing
}
void pre(int n) {
  timer = 1; dfs0(1, 1);
  FOR(i, 1, LOGN) FOR(j, 1, n + 1) P[i][j] = P[i - 1][P[i - 1][j]];
}
bool ancestor(int par, int u) { return ((st[par] < st[u]) && (en[par] >= en[u])); }
bool cmp(int x, int y) { return st[x] < st[y]; }
int LCA(int x, int y) {
  if(depth[x] < depth[y]) swap(x, y);
  for(int i = LOGN - 1; i >= 0; i--) {
    if(depth[P[i][x]] >= depth[y]) x = P[i][x];
  }
  if(x == y) return x;
  for(int i = LOGN - 1; i >= 0; i--) {
    if(P[i][x] != P[i][y]) x = P[i][x], y = P[i][y];
  }
  return P[0][x];
}
int dist(int u, int par){
  if(depth[u] < depth[par]) swap(u, par);
  return dists[u] - dists[par];
}
int createtree() {
  for(auto v: auxNodes) mark[v] = true;
  sort(ALL(auxNodes), cmp);
  FOR(i, 0, SZ(auxNodes) - 1) {
    int lc = LCA(auxNodes[i], auxNodes[i + 1]);
    if(mark[lc]) continue;
    auxNodes.push_back(lc);
    mark[lc] = true;
  }
  sort(ALL(auxNodes), cmp);//***call pre,clear auxNodes,create tree,dfs
  for(int u: auxNodes) aux[u].clear();
  stack <int> sta; sta.push(auxNodes[0]);
  FOR(i, 1, SZ(auxNodes)){
    int u = auxNodes[i];
    while(!ancestor(sta.top(), u)) sta.pop();
    int v = sta.top();
    LL w = dist(u, v); // edge weight of the tree
    aux[u].push_back({v, w});
    aux[v].push_back({u, w});
    sta.push(u);
  } return auxNodes[0];
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n;
	cin >> n;
	for(int i=1; i<=n; ++i) {
		cin >> p[i];
		g[p[i]+1].PB(i+1);
	}
	int ans = 0;
	dfs_init(1, 0);
	pre(n+1);
	for(int i=0; i<=n; ++i) {
		auxNodes = nodesH[i];
		if(SZ(auxNodes) == 0) continue;
		int root = createtree();
		for(auto&z: auxNodes) dph[z] = -1;
		for(auto&z: auxNodes) dp0[z] = -1;
		for(auto&z: auxNodes) dp1[z] = -1;
		for(auto&z: auxNodes) mark[z] = 0;
		ans = add(ans, mul(powmod(2, n+1-cnth(root, i, 0)), calc1(root, i, 0)));
	}
	cout << ans << endl;
	return 0;
}

Measured memory_bytes: 59008