Problem:
Score : 1000 points

Problem Statement

Snuke has a rooted tree with N+1 vertices.
The vertices are numbered 0 through N, and Vertex 0 is the root of the tree.
The parent of Vertex i (1 \leq i \leq N) is Vertex p_i.

Besides this tree, Snuke also has an box which is initially empty and many marbles, and playing with them.
The play begins with placing one marble on some of the vertices, then proceeds as follows:

If there is a marble on Vertex 0, move the marble into the box.

Move each marble from the vertex to its parent (all at once).

For each vertex occupied by two or more marbles, remove all the marbles from the vertex.

If there exists a vertex with some marbles, go to Step 1. Otherwise, end the play.

There are 2^{N+1} ways to place marbles on some of the vertices.
For each of them, find the number of marbles that will be in the box at the end of the play, and compute the sum of all those numbers modulo 1,000,000,007.

Constraints

1 \leq N < 2 \times 10^{5}

0 \leq p_i < i

Partial Scores

In the test set worth 400 points, N < 2{,}000.

Input

Input is given from Standard Input in the following format:

N
p_1 p_2 ... p_{N}

Output

Print the answer.

Sample Input 1

2
0 0

Sample Output 1

8

When we place a marble on both Vertex 1 and 2, there will be multiple marbles on Vertex 0 by step 2. In such a case, these marbles will be removed instead of being moved to the box.

Sample Input 2

5
0 1 1 0 4

Sample Output 2

96

Sample Input 3

31
0 1 0 2 4 0 4 1 6 4 3 9 7 3 7 2 15 6 12 10 12 16 5 3 20 1 25 20 23 24 23

Sample Output 3

730395550

Be sure to compute the sum modulo 1,000,000,007.

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		if(N >= 2000){
			Console.WriteLine(0);
			return;
		}
		
		List<int>[] E = new List<int>[N];
		for(int i=0;i<N;i++) E[i] = new List<int>();
		for(int i=1;i<N;i++){
			E[P[i]].Add(i);
		}
		
		int[] cnt = new int[N];
		Func<int,int> dfs = null;
		dfs = x =>{
			if(cnt[x] != 0) return cnt[x];
			cnt[x] = 1;
			foreach(var nxt in E[x]){
				cnt[x] += dfs(nxt);
			}
			return cnt[x];
		};
		
		dfs(0);
		
		long[] B = new long[N+1];
		B[0] = 1;
		for(int i=0;i<N;i++){
			B[i+1] = B[i] + B[i];
			if(B[i+1] >= mod) B[i+1] -= mod;
		}
		
		int[] depth = new int[N];
		depth[0] = 0;
		Queue<int> Q = new Queue<int>();
		Q.Enqueue(0);
		while(Q.Count>0){
			var now = Q.Dequeue();
			foreach(var nxt in E[now]){
				depth[nxt] = depth[now] + 1;
				Q.Enqueue(nxt);
			}
		}
		
		List<int>[] ds = new List<int>[N];
		for(int i=0;i<N;i++) ds[i] = new List<int>();
		
		for(int i=0;i<N;i++){
			ds[depth[i]].Add(i);
		}
		long ans = 0;
		int dmax = depth.Max();
		int done = 0;
		for(int i=0;i<=dmax;i++){
			long[][] dp = new long[2][];
			for(int j=0;j<2;j++) dp[j] = new long[N];
			foreach(var m in ds[i]){
				dp[1][m] = B[cnt[m] - 1];
				dp[0][m] = B[cnt[m] - 1];
			}
			int strt = i - 1;
			for(int dep = strt; dep >= 0; dep--){
				foreach(var par in ds[dep]){
					long tot = 1;
					long zeros = 1;
					foreach(var nxt in E[par]){
						tot *= (dp[0][nxt] + dp[1][nxt]); tot %= mod;
						zeros *= dp[0][nxt]; zeros %= mod;
					}
					long sel = 0;
					foreach(var nxt in E[par]){
						long one = (((zeros * ModInv(dp[0][nxt])) % mod) * dp[1][nxt]) % mod;
						sel += one; sel %= mod;
					}
					
					dp[1][par] += sel ; dp[1][par] %= mod;
					long rest = (tot + mod - sel) % mod; if(tot < 0) tot += mod;
					dp[0][par] += rest ; dp[0][par] %= mod;
						
				}
			}
			
			long tt = dp[1][0] * B[done]; tt %= mod;
			ans += tt; ans %= mod;
			done += ds[i].Count;
		}
		Console.WriteLine(ans);
	}
	
	
	const long mod = (long) 1e9 + 7;
	static long ModInv(long x){
		//拡張ユークリッドの互除法でmod逆元を求める
		//ax + mod * y = 1 で mod取れば ax = 1 になるから xがaの逆元になる
		//逆元が存在しない→0を返す。
		long a=0,b=0,c=0;
		if(x==0)return 0;
		ExtGCD(x,mod,ref a,ref b,ref c);
		if(c!=1)return 0;
		return (a+mod)%mod;
	}
	static void ExtGCD(long x,long y,ref long a,ref long b,ref long c){
		long r0=x;long r1=y;
		long a0=1;long a1=0;
		long b0=0;long b1=1;
		long q1,r2,a2,b2;
		while(r1>0){
			q1=r0/r1;
			r2=r0%r1;
			a2=a0-q1*a1;
			b2=b0-q1*b1;
			r0=r1;r1=r2;
			a0=a1;a1=a2;
			b0=b1;b1=b2;
		}
		c=r0;
		a=a0;
		b=b0;
	}
	
	int N;
	int[] P;
	public Sol(){
		N = ri();
		P = new int[N+1];
		var d = ria();
		P[0] = -1;
		for(int i=0;i<N;i++) P[i+1] = d[i];
		
		N++;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}