Problem: Earlier, when there was no Internet, each bank had a lot of offices all around Bankopolis, and it caused a lot of problems. Namely, each day the bank had to collect cash from all the offices.

Once Oleg the bank client heard a dialogue of two cash collectors. Each day they traveled through all the departments and offices of the bank following the same route every day. The collectors started from the central department and moved between some departments or between some department and some office using special roads. Finally, they returned to the central department. The total number of departments and offices was n, the total number of roads was n - 1. In other words, the special roads system was a rooted tree in which the root was the central department, the leaves were offices, the internal vertices were departments. The collectors always followed the same route in which the number of roads was minimum possible, that is 2n - 2.

One of the collectors said that the number of offices they visited between their visits to offices a and then b (in the given order) is equal to the number of offices they visited between their visits to offices b and then a (in this order). The other collector said that the number of offices they visited between their visits to offices c and then d (in this order) is equal to the number of offices they visited between their visits to offices d and then c (in this order). The interesting part in this talk was that the shortest path (using special roads only) between any pair of offices among a, b, c and d passed through the central department.

Given the special roads map and the indexes of offices a, b, c and d, determine if the situation described by the collectors was possible, or not.

Input

The first line contains single integer n (5 ≤ n ≤ 5000) — the total number of offices and departments. The departments and offices are numbered from 1 to n, the central office has index 1.

The second line contains four integers a, b, c and d (2 ≤ a, b, c, d ≤ n) — the indexes of the departments mentioned in collector's dialogue. It is guaranteed that these indexes are offices (i.e. leaves of the tree), not departments. It is guaranteed that the shortest path between any pair of these offices passes through the central department.

On the third line n - 1 integers follow: p2, p3, ..., pn (1 ≤ pi < i), where pi denotes that there is a special road between the i-th office or department and the pi-th department.

Please note the joint enumeration of departments and offices.

It is guaranteed that the given graph is a tree. The offices are the leaves, the departments are the internal vertices.

Output

If the situation described by the cash collectors was possible, print "YES". Otherwise, print "NO".

Examples

Input

5
2 3 4 5
1 1 1 1


Output

YES

Input

10
3 8 9 10
1 2 2 2 2 2 1 1 1


Output

NO

Input

13
13 12 9 7
1 1 1 1 5 5 2 2 2 3 3 4


Output

YES

Note

In the first example the following collector's route was possible: <image>. We can note that between their visits to offices a and b the collectors visited the same number of offices as between visits to offices b and a; the same holds for c and d (the collectors' route is infinite as they follow it each day).

In the second example there is no route such that between their visits to offices c and d the collectors visited the same number of offices as between visits to offices d and c. Thus, there situation is impossible. 

In the third example one of the following routes is: <image>.

Solution (in JAVA):

Solution:
//package tinkoff2017.e;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E2 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";
	
	void solve()
	{
		int n = ni();
		int[] a = na(4);
		for(int i = 0;i < 4;i++){
			a[i]--;
		}
		int[] par = new int[n];
		par[0] = -1;
		for(int i = 1;i <n;i++){
			par[i] = ni()-1;
		}
		int[][] g = parentToG(par);
		
		int[][] pars = parents3(g, 0);
		int[] ord = pars[1];
		boolean[][] dp = new boolean[n][];
		int[] dom = new int[n];
		Arrays.fill(dom, -1);
		int[] nl = new int[n];
		outer:
		for(int i = n-1;i >= 1;i--){
			int cur = ord[i];
			if(g[cur].length == 1){
				nl[cur]++;
			}
			nl[par[cur]] += nl[cur];
			for(int j = 0;j < 4;j++){
				if(a[j] == cur){
					dom[cur] = j;
					dp[cur] = new boolean[]{true};
					continue outer;
				}
			}
			int dome = -1;
			for(int e : g[cur]){
				if(par[cur] == e)continue;
				if(dom[e] != -1){
					dom[cur] = dom[e];
					dome = e;
					break;
				}
			}
			if(dom[cur] == -1)continue;
			dp[cur] = Arrays.copyOf(dp[dome], nl[cur]);
			for(int e : g[cur]){
				if(par[cur] == e)continue;
				if(dome == e)continue;
				for(int j = dp[cur].length-1-nl[e];j >= 0;j--){
					dp[cur][j+nl[e]] |= dp[cur][j];
				}
			}
		}
//		tr(dom);
		if(nl[0] % 2 != 0){
			out.println("NO");
			return;
		}
		
		boolean[] ep = new boolean[n+1];
		ep[0] = true;
		boolean[][] dps = new boolean[4][];
		int[] fa = new int[4];
		for(int e : g[0]){
			if(dom[e] == -1){
				for(int j = n;j >= nl[e];j--){
					ep[j] |= ep[j-nl[e]];
				}
			}else{
				dps[dom[e]] = dp[e];
				fa[dom[e]] = dp[e].length;
//				tr(dom[e]);
//				tf(dp[e]);
			}
		}
//		tf(ep);
		// a c b d
		{
			boolean[] canab = new boolean[n+1];
			for(int i = 0;i < dps[0].length;i++){
				for(int j = 0;j < dps[1].length;j++){
					if(dps[0][i] && dps[1][j]){
						int len = nl[0]/2-1-(dps[0].length-i-1 + j) - fa[2];
						if(len >= 0)canab[len] = true;
					}
				}
			}
			boolean[] cancd = new boolean[n+1];
			for(int i = 0;i < dps[2].length;i++){
				for(int j = 0;j < dps[3].length;j++){
					if(dps[2][i] && dps[3][j]){
						int len = nl[0]/2-1-(dps[2].length-i-1 + j) - fa[1];
						if(len >= 0)cancd[len] = true;
					}
				}
			}
			for(int i = 0;i <= n;i++){
				for(int j = 0;j <= n;j++){
					if(ep[i] && ep[j] && canab[i] && cancd[j]){
						out.println("YES");
						return;
					}
				}
			}
		}
		{
			boolean[] canab = new boolean[n+1];
			for(int i = 0;i < dps[0].length;i++){
				for(int j = 0;j < dps[1].length;j++){
					if(dps[0][i] && dps[1][j]){
						int len = nl[0]/2-1-(dps[0].length-i-1 + j) - fa[3];
						if(len >= 0)canab[len] = true;
					}
				}
			}
			boolean[] cancd = new boolean[n+1];
			for(int i = 0;i < dps[3].length;i++){
				for(int j = 0;j < dps[2].length;j++){
					if(dps[3][i] && dps[2][j]){
						int len = nl[0]/2-1-(dps[3].length-i-1 + j) - fa[1];
						if(len >= 0)cancd[len] = true;
					}
				}
			}
			for(int i = 0;i <= n;i++){
				for(int j = 0;j <= n;j++){
					if(ep[i] && ep[j] && canab[i] && cancd[j]){
						out.println("YES");
						return;
					}
				}
			}
		}
		out.println("NO");
	}
	
	public static void tf(boolean... r)
	{
		for(boolean x : r)System.out.print(x?'#':'.');
		System.out.println();
	}

	
	public static int[][] parents3(int[][] g, int root) {
		int n = g.length;
		int[] par = new int[n];
		Arrays.fill(par, -1);

		int[] depth = new int[n];
		depth[0] = 0;

		int[] q = new int[n];
		q[0] = root;
		for (int p = 0, r = 1; p < r; p++) {
			int cur = q[p];
			for (int nex : g[cur]) {
				if (par[cur] != nex) {
					q[r++] = nex;
					par[nex] = cur;
					depth[nex] = depth[cur] + 1;
				}
			}
		}
		return new int[][] { par, q, depth };
	}

	
	public static int[][] parentToG(int[] par)
	{
		int n = par.length;
		int[] ct = new int[n];
		for(int i = 0;i < n;i++){
			if(par[i] >= 0){
				ct[i]++;
				ct[par[i]]++;
			}
		}
		int[][] g = new int[n][];
		for(int i = 0;i < n;i++){
			g[i] = new int[ct[i]];
		}
		for(int i = 0;i < n;i++){
			if(par[i] >= 0){
				g[par[i]][--ct[par[i]]] = i;
				g[i][--ct[i]] = par[i];
			}
		}
		return g;
	}
	

	
	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);
		
		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}
	
	public static void main(String[] args) throws Exception { new E2().run(); }
	
	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;
	
	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}
	
	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }
	
	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }
	
	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}
	
	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}
	
	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}
	
	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}
	
	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}
		
		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}
	
	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}
		
		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}
	
	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}