// Original C++ solution (slower):
#include<bits/stdc++.h>

#define rep(i,a,b) for(int i=a;i<b;i++)

#define rrep(i,a,b) for(int i=a;i>=b;i--)

#define fore(i,a) for(auto &i:a)

#define all(x) (x).begin(),(x).end()

//#pragma GCC optimize ("-O3")

using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }

typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;

template<class T>bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }

template<class T>bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }

//---------------------------------------------------------------------------------------------------

#ifdef _MSC_VER

inline unsigned int __builtin_popcount(unsigned int x) { return __popcnt(x); }

#endif // _MSC_VER

/*---------------------------------------------------------------------------------------------------

　　　　　　　　　　　 ∧＿∧

　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!

　　　　 （ ´_ゝ`）　/　 ⌒i

　　　　／　　　＼　 　 |　|

　　　 /　　 /￣￣￣￣/　　|

　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿

　 　　　＼/＿＿＿＿/　（u　⊃

---------------------------------------------------------------------------------------------------*/









int N, A, B;

vector<int> E[1 << 17];

//---------------------------------------------------------------------------------------------------

void add(int a, int b) {

    E[a].push_back(b);

    E[b].push_back(a);



    int x = a ^ b;

    //if (__builtin_popcount(x) != 1) printf("[!!] ");

    //assert(__builtin_popcount(x) == 1);



    if (__builtin_popcount(x) != 1) {

        printf("%d %d\n", a, b);

        //exit(1);

    }



    //printf("%d - %d\n", a, b);

}

//---------------------------------------------------------------------------------------------------

void connect2(int L, int R, int from, int to, int len);

int go1(int L, int R, int from, int len) {

    if (len == 1) return from;

    else if (len == 2) {

        if (L == from) {

            add(L + 1, from);

            return L + 1;

        }

        else {

            add(L, from);

            return L;

        }

    }



    int C = (L + R) / 2;



    // 上にある

    if (from < C) {

        rep(i, L, C) if (i != from) {

            if (__builtin_popcount(i) % 2 != __builtin_popcount(from) % 2) {

                connect2(L, C, min(from,i), max(from,i), len / 2);



                add(i, i + len / 2);



                return go1(C, R, i + len / 2, len / 2);

            }

        }

    }



    // 下にある

    if (C <= from) {

        rep(i, C, R) if (i != from) {

            if (__builtin_popcount(i) % 2 != __builtin_popcount(from) % 2) {

                connect2(C, R, min(from, i), max(from, i), len / 2);



                add(i, i - len / 2);



                return go1(L, C, i - len / 2, len / 2);

            }

        }

    }

}

pair<int, int> go2(int L, int R, int from, int to, int len) {

    if (len == 2) return { from, to };



    int C = (L + R) / 2;



    // 上に2つともある

    if (to < C) {

        auto p = go2(L, C, from, to, len / 2);



        add(p.first, p.first + len / 2);

        add(p.second, p.second + len / 2);



        return go2(C, R, p.first + len / 2, p.second + len / 2, len / 2);

    }



    // 下に2つともある

    if (C <= from) {

        auto p = go2(C, R, from, to, len / 2);



        add(p.first, p.first - len / 2);

        add(p.second, p.second - len / 2);



        return go2(L, C, p.first - len / 2, p.second - len / 2, len / 2);

    }



    return { go1(L, C, from, len / 2), go1(C, R, to, len / 2) };

}

void connect2(int L, int R, int from, int to, int len) {

    if (len == 2) {

        add(from, to);

        return;

    }



    int C = (L + R) / 2;



    // 上に2つともある

    if (to < C) {

        auto p = go2(L, C, from, to, len / 2);



        add(p.first, p.first + len / 2);

        add(p.second, p.second + len / 2);



        connect2(C, R, p.first + len / 2, p.second + len / 2, len / 2);

        return;

    }



    // 下に2つともある

    if (C <= from) {

        auto p = go2(C, R, from, to, len / 2);



        add(p.first, p.first - len / 2);

        add(p.second, p.second - len / 2);



        connect2(L, C, p.first - len / 2, p.second - len / 2, len / 2);

        return;

    }



    rep(i, L, C) if(i != from and i + len / 2 != to) {

        if (__builtin_popcount(i) % 2 != __builtin_popcount(from) % 2) {



            add(i, i + len / 2);



            connect2(L, C, min(i, from), max(i, from), len / 2);

            connect2(C, R, min(i + len/2, to), max(i + len/2, to), len / 2);

            return;

        }

    }

}

//---------------------------------------------------------------------------------------------------

int vis[1 << 17];

vector<int> ans;

void dfs(int cu) {

    ans.push_back(cu);

    vis[cu] = 1;

    fore(to, E[cu]) if (!vis[to]) dfs(to);

}

//---------------------------------------------------------------------------------------------------

void solve() {

    rep(i, 0, 1 << 17) E[i].clear(), vis[i] = 0;

    ans.clear();



    if (__builtin_popcount(A) % 2 == __builtin_popcount(B) % 2) {

        printf("NO\n");

        return;

    }



    int f = 0;

    if (A > B) {

        swap(A, B);

        f = 1;

    }



    connect2(0, 1 << N, A, B, 1 << N);

    dfs(A);



    //return;



    assert(ans.size() == (1 << N));



    printf("YES\n");



    if(f) reverse(all(ans));



    rep(i, 0, 1 << N) {

        if (i) printf(" ");

        printf("%d", ans[i]);

    }

    printf("\n");

}

//---------------------------------------------------------------------------------------------------

void _main() {

    



    cin >> N >> A >> B;

    solve();

    return;



    rep(i, 1, 6) {

        N = i;

        rep(a, 0, 1 << N) rep(b, 0, 1 << N) {

            A = a;

            B = b;



            

        }



        

    }



    

}




// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define rep(i,a,b) for(int i=a;i<b;i++)

#define rrep(i,a,b) for(int i=a;i>=b;i--)

#define fore(i,a) for(auto &i:a)

#define all(x) (x).begin(),(x).end()

//#pragma GCC optimize ("-O3")

using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }

typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;

template<class T>bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }

template<class T>bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }

//---------------------------------------------------------------------------------------------------

#ifdef _MSC_VER

inline unsigned int __builtin_popcount(unsigned int x) { return __popcnt(x); }

#endif // _MSC_VER

/*---------------------------------------------------------------------------------------------------

　　　　　　　　　　　 ∧＿∧

　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!

　　　　 （ ´_ゝ`）　/　 ⌒i

　　　　／　　　＼　 　 |　|

　　　 /　　 /￣￣￣￣/　　|

　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿

　 　　　＼/＿＿＿＿/　（u　⊃

---------------------------------------------------------------------------------------------------*/









int N, A, B;

vector<int> E[1 << 17];

//---------------------------------------------------------------------------------------------------

void add(int a, int b) {

    E[a].push_back(b);

    E[b].push_back(a);

}

//---------------------------------------------------------------------------------------------------

void connect2(int L, int R, int from, int to, int len);

int go1(int L, int R, int from, int len) {

    if (len == 1) return from;

    else if (len == 2) {

        if (L == from) {

            add(L + 1, from);

            return L + 1;

        }

        else {

            add(L, from);

            return L;

        }

    }



    int C = (L + R) / 2;



    // 上にある

    if (from < C) {

        rep(i, L, C) if (i != from) {

            if (__builtin_popcount(i) % 2 != __builtin_popcount(from) % 2) {

                connect2(L, C, min(from,i), max(from,i), len / 2);



                add(i, i + len / 2);



                return go1(C, R, i + len / 2, len / 2);

            }

        }

    }



    // 下にある

    if (C <= from) {

        rep(i, C, R) if (i != from) {

            if (__builtin_popcount(i) % 2 != __builtin_popcount(from) % 2) {

                connect2(C, R, min(from, i), max(from, i), len / 2);



                add(i, i - len / 2);



                return go1(L, C, i - len / 2, len / 2);

            }

        }

    }

}

pair<int, int> go2(int L, int R, int from, int to, int len) {

    if (len == 2) return { from, to };



    int C = (L + R) / 2;



    // 上に2つともある

    if (to < C) {

        auto p = go2(L, C, from, to, len / 2);



        add(p.first, p.first + len / 2);

        add(p.second, p.second + len / 2);



        return go2(C, R, p.first + len / 2, p.second + len / 2, len / 2);

    }



    // 下に2つともある

    if (C <= from) {

        auto p = go2(C, R, from, to, len / 2);



        add(p.first, p.first - len / 2);

        add(p.second, p.second - len / 2);



        return go2(L, C, p.first - len / 2, p.second - len / 2, len / 2);

    }



    return { go1(L, C, from, len / 2), go1(C, R, to, len / 2) };

}

void connect2(int L, int R, int from, int to, int len) {

    if (len == 2) {

        add(from, to);

        return;

    }



    int C = (L + R) / 2;



    // 上に2つともある

    if (to < C) {

        auto p = go2(L, C, from, to, len / 2);



        add(p.first, p.first + len / 2);

        add(p.second, p.second + len / 2);



        connect2(C, R, p.first + len / 2, p.second + len / 2, len / 2);

        return;

    }



    // 下に2つともある

    if (C <= from) {

        auto p = go2(C, R, from, to, len / 2);



        add(p.first, p.first - len / 2);

        add(p.second, p.second - len / 2);



        connect2(L, C, p.first - len / 2, p.second - len / 2, len / 2);

        return;

    }



    rep(i, L, C) if(i != from and i + len / 2 != to) {

        if (__builtin_popcount(i) % 2 != __builtin_popcount(from) % 2) {



            add(i, i + len / 2);



            connect2(L, C, min(i, from), max(i, from), len / 2);

            connect2(C, R, min(i + len/2, to), max(i + len/2, to), len / 2);

            return;

        }

    }

}

//---------------------------------------------------------------------------------------------------

int vis[1 << 17];

vector<int> ans;

void dfs(int cu) {

    ans.push_back(cu);

    vis[cu] = 1;

    fore(to, E[cu]) if (!vis[to]) dfs(to);

}

//---------------------------------------------------------------------------------------------------

void _main() {

    cin >> N >> A >> B;



    if (__builtin_popcount(A) % 2 == __builtin_popcount(B) % 2) {

        printf("NO\n");

        return;

    }



    int isSwap = 0;

    if (A > B) {

        swap(A, B);

        isSwap = 1;

    }



    connect2(0, 1 << N, A, B, 1 << N);

    dfs(A);



    printf("YES\n");



    if (isSwap) reverse(all(ans));



    rep(i, 0, 1 << N) {

        if (i) printf(" ");

        printf("%d", ans[i]);

    }

    printf("\n");

}




// Fastest known solution for this problem: