using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int[] KMP(string s)
    {
        int n = s.Length;
        var pi = new int[n];
	    for (int i = 1; i < n; ++i)
        {
		    int j = pi[i - 1];
		    while (j > 0 && s[i] != s[j])
			    j = pi[j - 1];
		    if (s[i] == s[j])
                j++;
		    pi[i] = j;
	    }
	    return pi;
    }

    public object Solve()
    {
        string s1 = ReadToken();
        string s2 = ReadToken();
        string s3 = ReadToken();

        int n1 = s1.Length;
        int n2 = s2.Length;
        int n3 = s3.Length;

        var dp = new int[n1 + 1, n2 + 1, n3];
        var path = new Tuple<int, int, int, char>[n1 + 1, n2 + 1, n3];
        for (int i1 = 1; i1 <= n1; i1++)
            for (int i2 = 1; i2 <= n2; i2++)
                for (int i3 = 0; i3 < n3; i3++)
                {
                    if (s1[i1 - 1] == s2[i2 - 1])
                    {
                        if (s3[i3] == s1[i1 - 1])
                        {
                            if (i3 + 1 < n3)
                            {
                                dp[i1, i2, i3 + 1] = dp[i1 - 1, i2 - 1, i3] + 1;
                                path[i1, i2, i3 + 1] = Tuple.Create(i1 - 1, i2 - 1, i3, s1[i1 - 1]);
                            }
                        }
                        else
                        {
                            int jump = KMP(s3.Substring(0, i3) + s1[i1 - 1])[i3];
                            if (dp[i1 - 1, i2 - 1, i3] + 1 > dp[i1, i2, jump])
                            {
                                dp[i1, i2, jump] = dp[i1 - 1, i2 - 1, i3] + 1;
                                path[i1, i2, jump] = Tuple.Create(i1 - 1, i2 - 1, i3, s1[i1 - 1]);
                            }
                        }
                    }
                    if (dp[i1 - 1, i2, i3] >= dp[i1, i2, i3])
                    {
                        dp[i1, i2, i3] = dp[i1 - 1, i2, i3];
                        path[i1, i2, i3] = Tuple.Create(i1 - 1, i2, i3, (char)0);
                    }
                    if (dp[i1, i2 - 1, i3] >= dp[i1, i2, i3])
                    {
                        dp[i1, i2, i3] = dp[i1, i2 - 1, i3];
                        path[i1, i2, i3] = Tuple.Create(i1, i2 - 1, i3, (char)0);
                    }
                }

        int max = -1;
        int nmax = -1;
        for (int i = 0; i < n3; i++)
        {
            if (dp[n1, n2, i] > max)
            {
                max = dp[n1, n2, i];
                nmax = i;
            }
        }
        if (max == 0)
            return 0;

        var list = new List<char>();
        var c = Tuple.Create(n1, n2, nmax, (char)0);
        while (c.Item1 > 0 && c.Item2 > 0)
        {
            c = path[c.Item1, c.Item2, c.Item3];
            if (c.Item4 > 0)
                list.Add(c.Item4);
        }
        list.Reverse();

        for (int i = 0; i < n3; i++)
        {
            for (int j = 0; j <= n1; j++)
            {
                for (int k = 0; k <= n2; k++)
                {
                    Console.Write(dp[j, k, i]);
                }
                Console.WriteLine();
            }
            Console.WriteLine("-----------");
        }

        return new string(list.ToArray());
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
#endif
        try
        {
            var ts = DateTime.Now;
            object result = new Solver().Solve();
            if (result != null)
                writer.WriteLine(result);
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read/Write

    private static Queue<string> currentLineTokens = new Queue<string>();

    private static string[] ReadAndSplitLine()
    {
        return reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public static string ReadToken()
    {
        while (currentLineTokens.Count == 0)
            currentLineTokens = new Queue<string>(ReadAndSplitLine());
        return currentLineTokens.Dequeue();
    }

    public static int ReadInt()
    {
        return int.Parse(ReadToken());
    }

    public static long ReadLong()
    {
        return long.Parse(ReadToken());
    }

    public static double ReadDouble()
    {
        return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
    }

    public static int[] ReadIntArray()
    {
        return ReadAndSplitLine().Select(int.Parse).ToArray();
    }

    public static long[] ReadLongArray()
    {
        return ReadAndSplitLine().Select(long.Parse).ToArray();
    }

    public static double[] ReadDoubleArray()
    {
        return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
    }

    public static int[][] ReadIntMatrix(int numberOfRows)
    {
        int[][] matrix = new int[numberOfRows][];
        for (int i = 0; i < numberOfRows; i++)
            matrix[i] = ReadIntArray();
        return matrix;
    }

    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows);
        int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = new int[numberOfRows];
            for (int j = 0; j < numberOfRows; j++)
                ret[i][j] = matrix[j][i];
        }
        return ret;
    }

    public static string[] ReadLines(int quantity)
    {
        string[] lines = new string[quantity];
        for (int i = 0; i < quantity; i++)
            lines[i] = reader.ReadLine().Trim();
        return lines;
    }

    public static void WriteArray<T>(IEnumerable<T> array)
    {
        writer.WriteLine(string.Join(" ", array));
    }

    #endregion
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;

public class Solver
{
    #region I/O
    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
        #if ONLINE_JUDGE
        reader = Console.In;
        writer = Console.Out;
        #else
        reader = new StreamReader("..\\..\\input.txt");
        writer = new StreamWriter("..\\..\\output.txt");
        #endif
        Solver solver = new Solver();

        try
        {
            object result = solver.Solve();
            if (result != null)
            {
                writer.WriteLine(result);
                Console.Error.WriteLine(result);
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine(ex);
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read helpers

    static Queue<string> currentLineTokens = new Queue<string>();

    public static string ReadToken()
    {
        if (currentLineTokens.Count == 0)
        {
            currentLineTokens = new Queue<string>(reader.ReadLine().Trim().Split(' '));
        }
        return currentLineTokens.Dequeue();
    }

    public static string[] ReadTokens(bool fromCurrentLine = false)
    {
        string[] split;
        if (fromCurrentLine)
        {
            if (currentLineTokens.Count == 0)
                return new string[0];
            split = currentLineTokens.ToArray();
            currentLineTokens.Clear();
        }
        else
        {
            split = reader.ReadLine().Trim().Split(' ');
        }
        return split;
    }

    public static int ReadInt()
    {
        return int.Parse(ReadToken());
    }

    public static long ReadLong()
    {
        return long.Parse(ReadToken());
    }

    public static double ReadDouble()
    {
        return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
    }

    public static int[] ReadIntArray(bool fromCurrentLine = false)
    {
        string[] tokens = ReadTokens(fromCurrentLine);
        return tokens.Select(int.Parse).ToArray();
    }

    public static long[] ReadLongArray(bool fromCurrentLine = false)
    {
        string[] tokens = ReadTokens(fromCurrentLine);
        return tokens.Select(long.Parse).ToArray();
    }

    public static int[][] ReadIntMatrix(int numberOfRows)
    {
        int[][] matrix = new int[numberOfRows][];
        for (int i = 0; i < numberOfRows; i++)
            matrix[i] = ReadIntArray();
        return matrix;
    }

    public static string[] ReadLines(int quantity)
    {
        string[] lines = new string[quantity];
        for (int i = 0; i < quantity; i++)
        {
            lines[i] = reader.ReadLine().Trim();
        }
        return lines;
    }

    #endregion

    private string s1, s2, virus;
    int[,] C = new int[101,101];
    int LCSLength()
    {
        int m = s1.Length;
        int n = s2.Length;
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
            {
                if (s1[i - 1] == s2[j - 1])
                {
                    C[i, j] = C[i - 1, j - 1] + 1;
                }
                else
                    C[i, j] = Math.Max(C[i, j - 1], C[i - 1, j]);
            }
        return C[m, n];
    }

    string[,] M;
    string Backtrack(int i, int j)
    {
        if (i == 0 || j == 0)
            return "";
        if (M[i, j] != null)
            return M[i, j];
        if (s1[i - 1] == s2[j - 1])
        {
            string b = Backtrack(i - 1, j - 1) + s1[i - 1];
            if (!b.EndsWith(virus))
            {
                M[i, j] = b;
                return b;
            }
        }
        string ret;
        if (C[i,j-1] > C[i-1,j])
            ret = Backtrack(i, j - 1);
        else
            ret = Backtrack(i - 1, j);
        M[i, j] = ret;
        return ret;
    }

    public object Solve()
    {
        s1 = reader.ReadLine();
        s2 = reader.ReadLine();
        C = new int[s1.Length + 1, s2.Length + 1];
        M = new string[s1.Length + 1, s2.Length + 1];
        virus = reader.ReadLine();

        LCSLength();
        string ans = Backtrack(s1.Length, s2.Length);
        return ans.Length == 0 ? "0" : ans;
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);

            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch] - 1;
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch] - 1;
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch] - 1;
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch] - 1;
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }
            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            bool ab = offices / 2 - 2 - ofsC >= 0 && knap[offices / 2 - 2 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            writer.WriteLine((ab && offices / 2 - 2 - ofsB >= 0 && knap[offices / 2 - 2 - ofsB]) ? "YES": "NO");
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);
            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch];
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch];
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch];
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch];
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }

            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length && !knap[j + elms])
                        knap[j + elms] = true;
            }
            bool ab = offices / 2 - 1 - ofsC >= 0 && knap[offices / 2 - 1 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length && !knap[j + elms])
                        knap[j + elms] = true;
            }
            writer.WriteLine(ab && offices / 2 - 1 - ofsB >= 0 && knap[offices / 2 - 1 - ofsB] ? "YES": "NO");
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);

            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch] - 1;
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch] - 1;
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch] - 1;
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch] - 1;
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }
            if (a == 1208 && b == 4439 && c == 4994 && d == 4241)
            {
                writer.WriteLine(string.Join(",", new[] { ofsA, ofsB, ofsC, ofsD}));
                writer.WriteLine(string.Join(",", new[] { partsA.Count, partsB.Count, partsC.Count, partsD.Count, free.Count }));
                return;
            }
            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            bool ab = offices / 2 - 2 - ofsC >= 0 && knap[offices / 2 - 2 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            writer.WriteLine(ab && offices / 2 - 2 - ofsB >= 0 && knap[offices / 2 - 2 - ofsB] ? "YES": "NO");
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);

            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch] - 1;
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch] - 1;
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch] - 1;
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch] - 1;
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }
            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            bool ab = offices / 2 - 2 - ofsC >= 0 && knap[offices / 2 - 2 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            if (a == 1208 && b == 4439 && c == 4994 && d == 4241)
            {
                writer.WriteLine(partsC.Concat(partsD).Concat(free).Sum());
                writer.WriteLine(offices / 2 - 2 - ofsB);
                writer.WriteLine(string.Join(",", new[] { ofsA, ofsB, ofsC, ofsD, offices }));
                writer.WriteLine(string.Join(",", new[] { partsA.Count, partsB.Count, partsC.Count, partsD.Count, free.Count }));
                writer.WriteLine(string.Join(",", new[] { partsA.Sum(), partsB.Sum(), partsC.Sum(), partsD.Sum(), free.Sum() }));
                return;
            }
            writer.WriteLine((ab && offices / 2 - 2 - ofsB >= 0 && knap[offices / 2 - 2 - ofsB]) ? "YES": "NO");
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);

            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch] - 1;
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch] - 1;
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch] - 1;
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch] - 1;
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }
            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            bool ab = offices / 2 - 2 - ofsC >= 0 && knap[offices / 2 - 2 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            if (a == 1208 && b == 4439 && c == 4994 && d == 4241)
            {
                writer.WriteLine(offices / 2 - 2 - ofsB);
                writer.WriteLine(string.Join(",", new[] { ofsA, ofsB, ofsC, ofsD, offices }));
                writer.WriteLine(string.Join(",", new[] { partsA.Count, partsB.Count, partsC.Count, partsD.Count, free.Count }));
                writer.WriteLine(string.Join(",", new[] { partsA.Sum(), partsB.Sum(), partsC.Sum(), partsD.Sum(), free.Sum() }));
                return;
            }
            writer.WriteLine((ab && offices / 2 - 2 - ofsB >= 0 && knap[offices / 2 - 2 - ofsB]) ? "YES": "NO");
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);
            if (a == 1208 && b == 4439 && c == 4994 && d == 4241)
            {
                writer.WriteLine(string.Join(",", p));
                return;
            }

            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch] - 1;
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch] - 1;
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch] - 1;
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch] - 1;
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }
            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            bool ab = offices / 2 - 2 - ofsC >= 0 && knap[offices / 2 - 2 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            writer.WriteLine(ab && offices / 2 - 2 - ofsB >= 0 && knap[offices / 2 - 2 - ofsB] ? "YES": "NO");
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);

            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch] - 1;
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch] - 1;
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch] - 1;
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch] - 1;
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }
            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                        knap[j + elms] = true;
            }
            bool ab = offices / 2 - 2 - ofsC >= 0 && knap[offices / 2 - 2 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            int sume = 0;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                sume += elms;
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length)
                    {
                        if (j + elms == offices / 2 - 2 - ofsB)
                        {
                            writer.WriteLine("xx {0} {1}", sume, elms);
                        }
                        knap[j + elms] = true;
                    }
            }
            if (a == 1208 && b == 4439 && c == 4994 && d == 4241)
            {
                writer.WriteLine(partsC.Concat(partsD).Concat(free).Sum());
                writer.WriteLine(offices / 2 - 2 - ofsB);
                writer.WriteLine(knap[offices / 2 - 2 - ofsB]);
                writer.WriteLine(string.Join(",", new[] { ofsA, ofsB, ofsC, ofsD, offices }));
                writer.WriteLine(string.Join(",", new[] { partsA.Count, partsB.Count, partsC.Count, partsD.Count, free.Count }));
                writer.WriteLine(string.Join(",", new[] { partsA.Sum(), partsB.Sum(), partsC.Sum(), partsD.Sum(), free.Sum() }));
                return;
            }
            writer.WriteLine((ab && offices / 2 - 2 - ofsB >= 0 && knap[offices / 2 - 2 - ofsB]) ? "YES": "NO");
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);
            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch];
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch];
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch];
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch];
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }

            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length && !knap[j + elms])
                        knap[j + elms] = true;
            }
            bool ab = knap[offices / 2 - 1 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                for (int j = 0; j < knap.Length; ++j)
                    if (knap[j] && j + elms < knap.Length && !knap[j + elms])
                        knap[j + elms] = true;
            }
            writer.WriteLine(ab && knap[offices / 2 - 1 - ofsB] ? "YES": "NO");
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.IO;
using CodeChallenges;
using System.Diagnostics;

namespace CodeChallenges.Boilerplate.IO
{
    #region helpers
    class FormattedStreamWriter : StreamWriter { public FormattedStreamWriter(Stream stream) : base(stream) { } public FormattedStreamWriter(string filePath) : base(filePath) { } public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } } }
    static class IOExtensions
    {
        public static string ReadString(this StreamReader reader) { return reader.ReadToken(); }
        public static string[] ReadStringArray(this StreamReader reader, int n) { var array = new string[n]; for (int i = 0; i < n; ++i) { array[i] = reader.ReadToken(); } return array; }
        public static int ReadInt(this StreamReader reader) { return int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static int[] ReadIntArray(this StreamReader reader, int n) { var array = new int[n]; for (int i = 0; i < n; ++i) { array[i] = int.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static uint ReadUnsignedInt(this StreamReader reader) { return uint.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long ReadLong(this StreamReader reader) { return long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static long[] ReadLongArray(this StreamReader reader, int n) { var array = new long[n]; for (int i = 0; i < n; ++i) { array[i] = long.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static ulong ReadUnsignedLong(this StreamReader reader) { return ulong.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double ReadDouble(this StreamReader reader) { return double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static double[] ReadDoubleArray(this StreamReader reader, int n) { var array = new double[n]; for (int i = 0; i < n; ++i) { array[i] = double.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static decimal ReadDecimal(this StreamReader reader) { return decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); }
        public static decimal[] ReadDecimalArray(this StreamReader reader, int n) { var array = new decimal[n]; for (int i = 0; i < n; ++i) { array[i] = decimal.Parse(reader.ReadToken(), CultureInfo.InvariantCulture); } return array; }
        public static void ResetBuffer() { buffer = new Queue<string>(1000); }
        static Queue<string> buffer = new Queue<string>(1000);
        static string ReadToken(this StreamReader reader) { while (buffer.Count == 0) { reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach((t) => { buffer.Enqueue(t); }); } return buffer.Dequeue(); }
    }
    #endregion
}

#region launch
class Program
{
    static void Main(string[] args)
    {
#if SOLVER_ATWORKSPACE
        var run = true; var outputFile = "output.txt"; var inputFile = "input.txt";
        switch (args[0])
        {
            case "g": run = false; outputFile = "input.txt"; inputFile = "output.txt"; break;
            case "r":
            default: run = true; inputFile = "input.txt"; outputFile = "output.txt"; break;
        }
#endif

        using (var writer = new CodeChallenges.Boilerplate.IO.FormattedStreamWriter(
#if SOLVER_ATWORKSPACE
outputFile
#else
            Console.OpenStandardOutput()
#endif
))
        {
            using (var reader = new StreamReader(
#if SOLVER_ATWORKSPACE
inputFile
#else
            Console.OpenStandardInput()
#endif
))
            {
#if SOLVER_ATWORKSPACE
                var stopw = new Stopwatch(); stopw.Start();
#endif
#if SOLVER_ATWORKSPACE
                if (run) new Solver(reader, writer).Do(); else new Generator(reader, writer).Create();

#else
                new Solver(reader, writer).Do();
#endif
#if SOLVER_ATWORKSPACE
                stopw.Stop(); writer.WriteLine("> {0}ms", stopw.ElapsedMilliseconds);
#endif
            }
        }
    }
}
#endregion

namespace CodeChallenges
{
    using CodeChallenges.Boilerplate.IO;

    public class Solver
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;

        public Solver(StreamReader reader, StreamWriter writer)
        {
            this.reader = reader;
            this.writer = writer;
        }

        public void Do()
        {
            var n = reader.ReadInt();
            var a = reader.ReadInt();
            var b = reader.ReadInt();
            var c = reader.ReadInt();
            var d = reader.ReadInt();
            var p = reader.ReadIntArray(n - 1);

            var nodes = new List<int>[n + 1];
            var ofs = new int[n + 1];
            var child = new int[n + 1];
            var hasA = new bool[n + 1];
            var hasB = new bool[n + 1];
            var hasC = new bool[n + 1];
            var hasD = new bool[n + 1];
            for (int i = 0; i < p.Length; ++i)
            {
                nodes[p[i]] = nodes[p[i]] ?? new List<int>();
                nodes[p[i]].Add(i + 2);
                ++child[p[i]];
            }
            var que = new Queue<int>();
            for (int i = 1; i <= n; ++i)
                if (child[i] == 0)
                {
                    que.Enqueue(i);
                    ofs[i] = 1;
                }
            var offices = que.Count;
            if (offices % 2 == 1)
            {
                writer.WriteLine("NO");
                return;
            }
            hasA[a] = true;
            hasB[b] = true;
            hasC[c] = true;
            hasD[d] = true;
            while (que.Count > 0)
            {
                var el = que.Dequeue();
                if (el > 1)
                {
                    var par = p[el - 2];
                    ofs[par] += ofs[el];
                    hasA[par] |= hasA[el];
                    hasB[par] |= hasB[el];
                    hasC[par] |= hasC[el];
                    hasD[par] |= hasD[el];
                    --child[par];
                    if (child[par] == 0)
                    {
                        que.Enqueue(par);
                    }
                }
            }
            var free = new List<int>();
            var partsA = new List<int>();
            var partsB = new List<int>();
            var partsC = new List<int>();
            var partsD = new List<int>();
            int ofsA = 0;
            int ofsB = 0;
            int ofsC = 0;
            int ofsD = 0;
            foreach (var ch in nodes[1])
            {
                if (!hasA[ch] && !hasB[ch] && !hasC[ch] && !hasD[ch])
                    free.Add(ofs[ch]);
                else
                {
                    List<int> parts;
                    bool[] hasG;
                    int g;
                    if (hasA[ch])
                    {
                        g = a;
                        hasG = hasA;
                        parts = partsA;
                        ofsA = ofs[ch] - 1;
                    }
                    else if (hasB[ch])
                    {
                        g = b;
                        hasG = hasB;
                        parts = partsB;
                        ofsB = ofs[ch] - 1;
                    }
                    else if (hasC[ch])
                    {
                        g = c;
                        hasG = hasC;
                        parts = partsC;
                        ofsC = ofs[ch] - 1;
                    }
                    else
                    {
                        g = d;
                        hasG = hasD;
                        parts = partsD;
                        ofsD = ofs[ch] - 1;
                    }
                    var st = ch;
                    while (st != g)
                    {
                        if (nodes[st] != null)
                        {
                            var dests = nodes[st];
                            foreach (var nch in dests)
                            {
                                if (hasG[nch])
                                    st = nch;
                                else
                                    parts.Add(ofs[nch]);
                            }
                        }
                        else
                            st = g;
                    }
                }
            }
            var knap = new bool[n + 1];
            knap[0] = true;
            foreach (var elms in partsA.Concat(partsB).Concat(free))
            {
                for (int j = knap.Length - 1 - elms; j >= 0 ; --j)
                    if (knap[j])
                        knap[j + elms] = true;
            }
            bool ab = offices / 2 - 2 - ofsC >= 0 && knap[offices / 2 - 2 - ofsC];
            knap = new bool[n + 1];
            knap[0] = true;
            int sume = 0;
            foreach (var elms in partsC.Concat(partsD).Concat(free))
            {
                sume += elms;
                for (int j = knap.Length - 1 - elms; j >= 0; --j)
                    if (knap[j])
                        knap[j + elms] = true;
            }

            writer.WriteLine((ab && offices / 2 - 2 - ofsB >= 0 && knap[offices / 2 - 2 - ofsB]) ? "YES": "NO");
        }
    }
}