#include <stdio.h>
#include <vector>

std::vector<int> digitcount(int a){ // Count the number of '1's
	std::vector<int> result;
	for(int i=0; i<32; i++) if((a&(1<<i)) != 0) result.push_back(i);
	return result;
}
int changebit(int x, int digit){ // Change x at bit digit
	return x ^ (1<<digit);
}

void append(std::vector<int> &origin, const std::vector<int> &add){
	for(auto it: add) origin.push_back(it);
}

void binaryprint(int x, int minlen){
	std::vector<char> dig;
	while(x>0){
		dig.push_back(x%2 == 0 ? '0':'1');
		x>>=1;
	}
	while(dig.size() < minlen) dig.push_back('0');
	while(!dig.empty()){
		printf("%c", dig.back());
		dig.pop_back();
	} return;
}

std::vector<int> newconstruct(int upbound, int changing){
	
	if(upbound+1 < changing){
		printf("Too large changing = %d for upbound = %d\n", changing, upbound);
		throw "ERROR";
	}
	else if(upbound == 2 && changing == 3) return {0, 1, 0, 2, 1, 0, 1};
	else if(upbound == 0){
		if(changing == 1) return {0};
		else{
			printf("upbound = 0, changing = %d ??\n", changing);
			throw "ERROR";
		}
	}
	else if(changing == 1){
		std::vector<int> result, half = newconstruct(upbound-1, 1);
		append(result, half);
		result.push_back(upbound);
		append(result, half);
		return result;
	}
	else{
		std::vector<int> quarter1 = newconstruct(upbound-2, changing-2);
		std::vector<int> pure = newconstruct(upbound-2, 1);
		std::vector<int> result;
		
		append(result, quarter1);
		result.push_back(upbound-1);
		append(result, pure);
		result.push_back(upbound);
		
		std::vector<int> backhalf;
		append(backhalf, pure);
		backhalf.push_back(upbound-1);
		append(backhalf, pure);
		for(int i=0; i<backhalf.size(); i++){
			if(backhalf[i] == upbound-1) backhalf[i] = upbound-2;
			else if(backhalf[i] == upbound-2) backhalf[i] = upbound-1;
		}
		append(result, backhalf);
		return result;
	}
	
}

int main(void){
	
	//std::vector<int> test = newconstruct(4, 5); for(auto it: test) printf("%d ", it); return 0;
	
	int n, a, b; scanf("%d %d %d", &n, &a, &b);
	
	std::vector<int> bitdiffvec = digitcount(a^b);
	if(bitdiffvec.size() % 2 != 1){ // a and b must be exact odd bit difference
		printf("NO");
		return 0;
	} 
	
	std::vector<int> digitchange = newconstruct(n-1, bitdiffvec.size());
	std::vector<int> translate(n, -1);
	//for(auto it: digitchange) printf("%d -> ", it); printf("\n");
	
	int head_change = n-1, head_nochange = n-bitdiffvec.size()-1;
	for(int i=0; i<n; i++){
		if(((a^b) & (1<<i)) == 0){ // No change on i-th digit
			//printf("a^b = %d, a^b & 1<<%d = %d nochange\n", a^b, i, (a^b)&(1<<i));
			translate[head_nochange--] = i;
		} else{
			//printf("a^b = %d, a^b & 1<<%d = %d yeschange\n", a^b, i, (a^b)&(1<<i));
			translate[head_change--] = i;
		}
	}
	//printf("translate: "); for(auto it: translate) printf("%d ", it); printf("\n");
	
	int test = 0;
	for(int i=0; i<(1<<n)-1; i++) test = changebit(test, digitchange[i]);
	//printf("TEST: "); binaryprint(test, n); printf("\n");
	
	test = 0;
	for(int i=0; i<(1<<n)-1; i++) test = changebit(test, translate[digitchange[i]]);
	//printf("TEST translated: "); binaryprint(test, n); printf("\n");
	
	int now = a; printf("YES\n");
	std::vector<bool> alreadyused(1<<n, false);
	for(int i=0; i<(1<<n); i++){
		printf("%d ", now);
		//binaryprint(now, n); printf("\n");
		if(alreadyused[now]) throw "ERROR";
		else alreadyused[now] = true;
		if(i<(1<<n)-1) now = changebit(now, translate[digitchange[i]]);
	}
	if(now != b){
		printf("Final value(=%d) is not b(=%d)\n", now, b);
		throw "ERROR";
	}
	return 0;
}

Measured memory_bytes: 1644