Problem: Consider a rooted tree. A rooted tree has one special vertex called the root. All edges are directed from the root. Vertex u is called a child of vertex v and vertex v is called a parent of vertex u if there exists a directed edge from v to u. A vertex is called a leaf if it doesn't have children and has a parent.

Let's call a rooted tree a spruce if its every non-leaf vertex has at least 3 leaf children. You are given a rooted tree, check whether it's a spruce.

The definition of a rooted tree can be found [here](https://goo.gl/1dqvzz).

Input

The first line contains one integer n — the number of vertices in the tree (3 ≤ n ≤ 1 000). Each of the next n - 1 lines contains one integer pi (1 ≤ i ≤ n - 1) — the index of the parent of the i + 1-th vertex (1 ≤ pi ≤ i).

Vertex 1 is the root. It's guaranteed that the root has at least 2 children.

Output

Print "Yes" if the tree is a spruce and "No" otherwise.

Examples

Input

4
1
1
1


Output

Yes


Input

7
1
1
1
2
2
2


Output

No


Input

8
1
1
1
1
3
3
3


Output

Yes

Note

The first example:

<image>

The second example:

<image>

It is not a spruce, because the non-leaf vertex 1 has only 2 leaf children.

The third example:

<image>

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;
public class working
{
    static PrintWriter out=new PrintWriter((System.out));
    public static void main(String args[])throws IOException
    {
        Reader sc=new Reader();
        
        int n=sc.nextInt();
        ArrayList<Integer>[] adj=new ArrayList[n+1];
        for(int i=0;i<=n;i++) adj[i]=new ArrayList<>();
        
        for(int tt=2;tt<=n;tt++){
            int x=sc.nextInt();
            adj[x].add(tt);
        }
        boolean ok=dfs(adj,1);
        if(ok) out.println("YES");
        else out.println("NO");
    	out.close();
 
    }
    
    private static boolean dfs(ArrayList<Integer>[] adj,int i){
        if(adj[i].size()==0) return true;
        int count=0;
        for(int j:adj[i]){
            if(adj[j].size()==0) count++;
            if(!dfs(adj,j)){
                return false;
            }
        }
        return count>=3;
    }
    
    // private static void dfs(ArrayList<Integer>[] adj,int i,int par,boolean[] vis){
    //     for(int j:adj[i]){
    //         if(j!=par){
    //             vis[j]=true;
    //             dfs(adj,j,i,vis);
    //         }
    //     }
    // }

    // private static boolean possible(char[][] grid,int i,int j){
    //     return (i>=0 && j>=0 && i<grid.length && j<grid[0].length);
    // }
    /*
    int n=sc.nextInt();
        	char[] s=sc.next().toCharArray();
        	int res=0;
        	for(int i=1;i<n;i++){
        		if( (s[i]=='1') && s[i]==s[i-1]) res++;
        	}
        	out.println(res);
    
    private static int modInverse(int a, int m) 
    { 
        a = a % m; 
        for (int x = 1; x < m; x++) 
           if ((a * x) % m == 1) 
              return x; 
        return 1;  
   }
    
    private static int gcd(int a,int b){
    	if(b==0) return a;
    	return gcd(b,a%b);
    }
    
    private static int dfs(ArrayList<Integer>[] adj,int[] arr,int i,int par){
    	if(adj[i].size()==0) return arr[i];
    	int curr=arr[i],s=adj[i].size();
    	int max=0;
        for(int j:adj[i]){
        	if(j==par) continue;
        	int temp=dfs(adj,arr,j,i);
        	max=Math.max(max,temp);
        	curr+=temp;
        }
        int rem=curr%s;
        if(rem>0) rem=1;
        int ans=rem+curr/s;
        if(max>ans) return max;
        return ans;
    }
     */
    public static long pow(long a,long b){
        if(b==0){
            return 1;
        }
        if(b%2==0){
            return pow(a*a,b/2);
        }else{
            return a*pow(a*a,b/2);
        }
    }
    static class Reader 
    { 
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer("");
        public String next()
        {
            while(!st.hasMoreTokens())
            {
                try
                {
                    st=new StringTokenizer(br.readLine());
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        public int nextInt()
        {
            return Integer.parseInt(next());
        }
        public long nextLong()
        {
            return Long.parseLong(next());
        }
        public double nextDouble()
        {
            return Double.parseDouble(next());
        }
        public String nextLine()
        {
            try
            {
                return br.readLine();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            return null;
        }
        public boolean hasNext()
        {
            String next=null;
            try
            {
                next=br.readLine();
            }
            catch(Exception e)
            {
            }
            if(next==null)
            {
                return false;
            }
            st=new StringTokenizer(next);
            return true;
        }
    } 
}