D: XORANDORBAN

Problem Statement

You are given a positive integer N. Your task is to determine a set S of 2^N integers satisfying the following conditions:

* All the integers in S are at least 0  and less than 2^{N+1}.
* All the integers in S are distinct.
* You are also given three integers X, A, and O, where 0 \leq X, A, O < 2^{N+1}. Then, any two integers (a, b) in S must satisfy a {\it xor} b \neq X, a {\it and} b \neq A, a {\it or} b \neq O, where {\it xor}, {\it and}, {\it or} are bitwise xor, bitwise and, bitwise or, respectively. Note that a and b are not necessarily different.



Input


N X A O

Constraints

* 1 \leq N \leq 13
* 0 \leq X, A, O < 2^{N+1}
* Inputs consist only of integers.



Output

If there is no set satisfying the conditions mentioned in the problem statement, output `No` in a line. Otherwise, output `Yes` in the first line, and then output 2^N integers in such a set in the second line. If there are multiple sets satisfying the conditions, you can output any of them.

Sample Input 1


2 6 1 5

Output for Sample Input 1


Yes
0 3 4 7


Sample Input 2


3 0 5 1

Output for Sample Input 2


No

Sample Input 3


3 4 2 5

Output for Sample Input 3


Yes
1 0 6 15 8 9 14 7






Example

Input

2 6 1 5


Output

Yes
0 3 4 7
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#define llint long long
#define inf 1000000000

using namespace std;
typedef pair<llint, llint> P;

int n, X, A, O;
vector<int> G[1<<14], revG[1<<14];
vector<int> ans;
vector<int> topo;
bool used[1<<14];
int scc[1<<14];

void tpsort(int v)
{
	used[v] = true;
	for(int i = 0; i < G[v].size(); i++){
		if(!used[G[v][i]]) tpsort(G[v][i]);
	}
	topo.push_back(v);
}
void sccdfs(int v, int id)
{
	used[v] = true;
	scc[v] = id;
	for(int i = 0; i < revG[v].size(); i++){
		if(!used[revG[v][i]]) sccdfs(revG[v][i], id);
	}
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> X >> A >> O;
	if(X == 0){
		cout << "No" << endl;
		return 0;
	}
	
	int N = 1<<(n+1);
	for(int i = 0; i < N; i++){
		for(int j = 0; j < N; j++){
			if((i & j) == A || (i | j) == O){
				G[i].push_back(j^X);
				revG[j^X].push_back(i);
			}
		}
	}
	
	for(int i = 0; i < N; i++) if(!used[i]) tpsort(i);
	reverse(topo.begin(), topo.end());
	
	int id = 1;
	for(int i = 0; i < N; i++) used[i] = false;
	for(int i = 0; i < topo.size(); i++) if(!used[topo[i]]) sccdfs(topo[i], id++);
	
	//for(int i = 0; i < N; i++) cout<< scc[i] << " "; cout << endl;
	
	for(int i = 0; i < N; i++){
		if(i > (i^X)) continue;
		if(scc[i] == scc[i^X]){
			cout << "No" << endl;
			return 0;
		}
		if(scc[i] > scc[i^X]) ans.push_back(i);
		else ans.push_back(i^X);
	}
	cout << "Yes" << endl;
	for(int i = 0; i < ans.size(); i++){
		cout << ans[i];
		if(i < (int)ans.size()-1) cout << " ";
	}
	cout << endl;
	
	return 0;
}

