#ifdef __GNUC__ 
#pragma GCC optimize(2)
#endif

#include <cassert>
#include <iostream>
#include <functional>
#include <iomanip>
#include <set>
#include <unordered_map>
#include <map>
#include <queue>
#include <stack>
#include <complex>
#include <vector>
#include <deque>
#include <algorithm>
#include  <cstring>
#include <string>
#include <cmath> 
#include <random>

#pragma warning(disable: 4996)

using namespace std;
 
namespace Bigcat {
	template <typename T> inline void max_s(T&a, const T&b) { a = max(a, b); }
	template <typename T> inline void min_s(T&a, const T&b) { a = min(a, b); }

	template <typename T>  void sort_v(T & x) { sort(x.begin(), x.end()); }
	template <typename T>  void erase_dup(T & x) { x.erase(unique(x.begin(), x.end()), x.end()); }    // erase duplicate
	template <typename T, typename V>  int pos_l(const T & x, const V & v) { return lower_bound(x.begin(), x.end(), v) - x.begin(); }
	template <typename T, typename V>  int pos_u(const T & x, const V & v) { return upper_bound(x.begin(), x.end(), v) - x.begin(); }

	inline unsigned rand_g() {
		static mt19937 mt_rand((int)time(0));
		return mt_rand();
	}
	using LL = long long;
	using VI = vector<int>;
	using VVI = vector< VI >;
	using VL = vector<LL>;
	using PII = pair<int, int>;
	using VPII = vector< PII >;
}
#define Rep(i, a) for(int i = 0; i < (int)(a); i++)
#define Loop(i, a, b) for(int i = (int)(a); i < (int)(b); i++)
#define Loop_r(i, n) for(int i = (int)(n) - 1; i >= 0; i--)

    using namespace Bigcat;
const LL base = LL(1e9 + 7);
const LL INFL =  1LL << 62;
const int INF = 1 << 30 ;
const int MAX = int ( 2e5 + 100 ) ;

struct Node {
	int x, y, w;
};
bool operator < (const Node & n0, const Node & n1) {
	return n0.x< n1.y;
}
int n;
int fa, fb;

vector<int> work(int na, int nb, int dep, int totd ) {
	if (dep == n-1) return{na, nb};
	if (totd == 1) {
		int ta = na / 2;
		assert(ta == nb / 2);
		int ea = na % 2;
		int eb = nb % 2;
		auto r0 = work(ta, ta ^ 1, dep + 1, 1);
		auto r1 = work(ta ^ 1, ta, dep + 1, 1);
		vector<int> zr;
		//zr.push_back(na);
		for (auto x : r0) {
			zr.push_back(x * 2 + ea);
		}
		for (auto x : r1) {
			zr.push_back(x * 2 + eb);
		}
		//zr.push_back(nb);
		return move(zr);
	}

	int ta = na / 4;
	int tb = nb / 4;
	int ea = na % 4;

	auto r0 = work(ta, ta^1, dep + 2, 1);
	auto r1 = work(ta^1, tb^1, dep + 2, totd-2);
	auto r2 = work(tb^1, tb, dep + 2, 1);

 
	vector<int> zr;

	for (auto x : r0) {
		zr.push_back(x * 4 + ea );
	}
	for (auto x : r1) {
		zr.push_back(x * 4 + ea ^ 1);
	} 
	int i;
	for (i = 0; i < r2.size(); ++i)  {
		int x = r2[i];
		if (i > 0 && (x & 1) != (r2[i - 1] & 1) ) break;
		zr.push_back(x * 4 + ea ^ 3); 
	}
	
	auto r3 = work(r2[i-1], r2[i ], dep + 2, 1);
	for (auto x : r3) {
		zr.push_back(x * 4 + ea ^ 2);
	}

	for (; i < r2.size(); ++i) {
		int x = r2[i];
		zr.push_back(x * 4 + ea ^ 3);
	}
	return zr;
}

int getbit(int g, int t) {
	return (g >> t) & 1;
}

int swapback(int g, int t) {
	int a = getbit(g, t);
	int b = getbit(g, 0);
	if (a == b) return g;
	g = g ^ (1 << t);
	return g ^ 1;
}

void test(string s, set<string> tt, vector<string> path) {
	path.push_back(s);
	tt.insert(s);
	if (tt.size() == (1 << s.size()) ) {
		if (s != "11111") return;
		for (auto x : path) {
			cout << x << ' ';
		}
		cout << endl;
		return;
	}
	for (int i = 0; i < s.size(); ++i) {
		string s1 = s;
		if (s[i] == '0') {
			s1[i] = '1';
		}
		else {
			s1[i] = '0';
		}
		if (tt.count(s1) > 0) continue;
		test(s1, tt, path);
	}

}
vector<bool> dif;
int totd;
int rec1(int g) {
	int r0  = 0;
	int r1  = 0;
	Loop_r(i, n) {
		if (dif[i]) {
			r0= r0*2 + getbit(g, i);
		}
		else {
			r1 = r1 * 2 + getbit(g, i);
		}
	}
	return (r1 << totd) + r0;
}
int rec2(int g) {
	int nd = totd-1;
	int ns = n-1;
	int r = 0;
	Loop_r(i, n) {
		int x;
		if (dif[i]) {
			x = getbit(g, nd);
			--nd;
		}
		else {
			x = getbit(g, ns);
			--ns;
		}
		r = r * 2 + x;
	}
	return r;
}

void solve1() {

	set<string > tt;
	//test("00000", tt, {});

	LL result = 0;
	cin >> n>>fa>>fb;
	int ac = 0;
	int t = 0;
	dif.resize(n);

	Rep(i, n) {
		if (getbit(fa,i) != getbit(fb,i)) {
			dif[i] = true;
			ac++;
			t = i;
		}
	}
	totd = ac;
	if (ac %2 != 1) {
		cout << "NO" << endl;
		return;
	}
	
	int ma = rec1(fa);
	int mb = rec1(fb);

	auto zr = work(ma, mb, 0, totd );
	cout << "YES"<<endl;
	set<int> ccc;
	Rep(i, n) ccc.insert(1 << i);
	for (auto &x : zr) {
		x = rec2(x);
	}
	assert(zr.size() == 1 << n);
	Loop(i, 1, 1<<n) {
		assert(ccc.count(zr[i] ^ zr[i - 1]) > 0);
	}
	
	for (auto x : zr) {
		cout << x << ' ';
	}
	cout <<  endl;
}
void solve() {
	int t = 1;
	//cin >> t;
#ifdef _DEBUG
	cerr << " now base "<< base << endl;
#endif
	for (int i = 0; i < t; ++i) {
 #ifdef _DEBUG
    cerr<<" tasks: " << i+1<<endl;
#endif       
		solve1();
	}
    int x = 1;
}

void io_init() {
   	const int inId = 0;
	const int outId = 0;
	if (inId>0) {
		cerr << "redirect stdin to input " << inId << endl;
		string s = "input";
		s += to_string(inId);
		s += ".txt";
		auto r = freopen(s.c_str(), "r", stdin);
		if (r == nullptr) {
			cerr << "invalid input file " << s << endl;;
			r = freopen("CON", "r", stdin); // to do  con??
		}
	}
	if (outId>0) {
		cerr << "redirect stdout to stdout " << outId << endl;
		string s = "stdout";
		s += to_string(outId);
		s += ".txt";
		auto r = freopen(s.c_str(), "w", stdout);
		if (r == nullptr) {
			cerr << "invalid output file " << s << endl;;
			r = freopen("CON", "w", stdout);
		}
	}
}

int main(int argc,  char * argv[]) {
    
#ifdef _DEBUG    
	if (argc ==1) {
		io_init();
	}
#endif
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // close sync between cout and printf
	cout.precision(11); 
    
	solve();
}


Measured memory_bytes: 1920