Problem:
Score : 800 points

Problem Statement

You are given integers N,\ A and B.
Determine if there exists a permutation (P_0,\ P_1,\ ...\ P_{2^N-1}) of (0,\ 1,\ ...\ 2^N-1) that satisfies all of the following conditions, and create one such permutation if it exists.

P_0=A

P_{2^N-1}=B

For all 0 \leq i < 2^N-1, the binary representations of P_i and P_{i+1} differ by exactly one bit.

Constraints

1 \leq N \leq 17

0 \leq A \leq 2^N-1

0 \leq B \leq 2^N-1

A \neq B

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N A B

Output

If there is no permutation that satisfies the conditions, print NO.

If there is such a permutation, print YES in the first line.
Then, print (P_0,\ P_1,\ ...\ P_{2^N-1}) in the second line, with spaces in between.
If there are multiple solutions, any of them is accepted.

Sample Input 1

2 1 3

Sample Output 1

YES
1 0 2 3

The binary representation of P=(1,0,2,3) is (01,00,10,11), where any two adjacent elements differ by exactly one bit.

Sample Input 2

3 2 1

Sample Output 2

NO

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

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Linq;
using static System.Math;

class Program
{
    static int N;
    static long A;
    static long B;

    static void Main()
    {
        string[] input = Console.ReadLine().Split();
        N = int.Parse(input[0]);
        A = long.Parse(input[1]);
        B = long.Parse(input[2]);


        int d = dis(A, B);
        if (d % 2 == 0)
        {
            Console.WriteLine("NO");
            return;
        }
        Console.WriteLine("YES");
        /* 0,...,AxorBになるものを求める */
        B ^= A;
        List<long> l;
        for (int i = 0; i < N; i++)
        {
            try
            {
                l = Solv(B, N, i);
                foreach (var k in l)
                    Console.Write("{0} ", k ^ A);
                Console.WriteLine("\b");
                return;
            }
            catch { continue; }
        }
        Console.WriteLine("NO");
    }

    static List<long> Solv(long x, int n, int k)
    {
        List<long> ans = new List<long>();
        List<long> r1 = Nums(k);
        List<long> r2 = Nums(n - k);
        int p = -1;
        int q = -1;
        for (int i = 0; i < r1.Count; i++)
        {
            if ((x >> (k)) == r1[i])
            {
                p = i;
                continue;
            }
        }
        for (int i = 0; i < r2.Count; i++)
        {
            if (x % ((long)Pow(2, k)) == r2[i])
            {
                q = i;
                continue;
            }
        }
        int r = n / 2;
        int l = k;
        if (p % 2 == q % 2) throw new Exception();
        if (q % 2 == 1)
        {
            var t = p;
            p = q;
            q = t;
            var t2 = r1;
            r1 = r2;
            r2 = t2;
            t = r;
            r = l;
            l = t;
        }
        for (int i = 0; i < p; i++)
        {
            if (i % 2 == 0)
            {
                for (int j = 0; j < r2.Count; j++)
                {
                    ans.Add((r1[i] << (l)) | r2[j]);
                }
            }
            else
            {
                for (int j = r2.Count - 1; j >= 0; j--)
                {
                    ans.Add((r1[i] << (l)) | r2[j]);
                }
            }
        }
        for (int i = p; i < r1.Count; i++)
        {
            if (i % 2 == 0)
            {
                for (int j = q + 1; j < r2.Count; j++)
                {
                    ans.Add((r1[i] << (l)) | r2[j]);
                }
            }
            else
            {
                for (int j = r2.Count - 1; j > q; j--)
                {
                    ans.Add((r1[i] << (l)) | r2[j]);
                }
            }
        }
        for (int j = q; j >= 0; j--)
            ans.Add((r1[r1.Count - 1] << (l)) | r2[j]);
        for (int j = 0; j <= q; j++)
        {
            if (j % 2 == 0)
            {
                for (int i = r1.Count - 2; i >= p; i--)
                    ans.Add((r1[i] << (l)) | r2[j]);
            }
            else
            {
                for (int i = p; i < r1.Count - 1; i++)
                {
                    ans.Add((r1[i] << (l)) | r2[j]);
                }
            }
        }
        return ans;
    }

    /* a,bのハミング距離を求める */
    static int dis(long a, long b)
    {
        long d = a ^ b;
        int i = 0;
        while (d != 0)
        {
            d &= d - 1;
            i++;
        }
        return i;
    }

    static List<long> Nums(int k)
    {
        List<long> r = new List<long>();
        if (k == 0) return r;
        if (k == 1)
        {
            r.Add(0);
            r.Add(1);
            return r;
        }
        if (k == 2)
        {
            r.Add(0);
            r.Add(1);
            r.Add(3);
            r.Add(2);
            return r;
        }
        int kh = k / 2;
        List<long> r1 = Nums(kh);
        List<long> r2 = Nums(k - kh);
        for (int i = 0; i < r1.Count; i++)
        {
            if (i % 2 == 0)
            {
                for (int j = 0; j < r2.Count; j++)
                {
                    long a = (r1[i] << (k - kh)) | r2[j];
                    r.Add(a);
                }
            }
            else
            {
                for (int j = 1; j <= r2.Count; j++)
                {
                    long a = (r1[i] << (k - kh)) | r2[r2.Count - j];
                    r.Add(a);
                }
            }
        }
        return r;
    }
}