Problem: 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

Solution (in CPP):

Solution:
#include <bits/stdc++.h>

using ll = long long;
#define REP(i, n) for (int i = 0; i < n; ++i)
using namespace std;

struct Edge {
	int from, to;
};
using Graph = vector<vector<Edge>>;

int scc(Graph &g, vector<int> &cmp) {
	int n = g.size();
	vector<int> used(n);
	vector<int> ord(n, -1);
	int k = 0;
	function<void(int)> dfs = [&](int v) {
		if (used[v]) return;
		used[v] = true;
		for (auto &e : g[v]) {
			dfs(e.to);
		}
		ord[k++] = v;
	};
	for (int i = 0; i < n; ++i) {
		if (!used[i]) dfs(i);
	}
	vector<vector<int>> rg(n);
	for (int i = 0; i < n; ++i) {
		for (auto &e : g[i])
			rg[e.to].push_back(i);
	}
	k = 0;
	cmp.assign(n, -1);
	function<void(int)> rdfs = [&](int v) {
		if (cmp[v] != -1) return;
		cmp[v] = k;
		for (auto &to : rg[v])
			rdfs(to);
	};
	for (int i = n - 1; i >= 0; --i) {
		if (cmp[ord[i]] == -1) rdfs(ord[i]), k++;
	}
	return k;
}

int main() {
	int n, x, a, o;
	cin >> n >> x >> a >> o;
	if (x == 0) {
		cout << "No" << endl;
		return 0;
	}
	int m = 1 << (n + 1);
	Graph g(m);
	REP(i, m) {
		if (i == o || i == a) {
			g[i].push_back({i, i ^ x});
			continue;
		}

		for (int j = i + 1; j < m; ++j) {
			if (j == o || j == a) continue;
			if ((i & j) == a || (i | j) == o || (i ^ j) == x) {
				g[i].push_back({i, j ^ x});
				g[j].push_back({j, i ^ x});
			}
		}
	}
	vector<int> cmp(n);
	int k = scc(g, cmp);

	vector<int> used(k, -1);
	used[cmp[a]] = 0;
	used[cmp[o]] = 0;
	vector<int> ans;
	REP(i, m) {
		if (i > (i ^ x)) continue;
		if (cmp[i] == cmp[i ^ x]) {
			cout << "No" << endl;
			return 0;
		}
		int a = cmp[i], b = cmp[i ^ x];
		if (used[cmp[i]] == 1 || used[cmp[i ^ x]] == 0) {
			ans.push_back(i);
			used[a] = 1;
			used[b] = 0;
		} else if (used[cmp[i]] == 0 || used[cmp[i ^ x]] == 1) {
			ans.push_back(i ^ x);
			used[a] = 0;
			used[b] = 1;
		} else if (cmp[i] > cmp[i ^ x]) {
			ans.push_back(i);
			used[a] = 1;
			used[b] = 0;
		} else {
			ans.push_back(i ^ x);
			used[a] = 0;
			used[b] = 1;
		}
	}
	cout << "Yes" << endl;
	assert(ans.size() == m / 2);
	REP(i, ans.size()) {
		if (i) cout << " ";
		cout << ans[i];
	}
	cout << endl;
}