#define _USE_MATH_DEFINES
#define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING
#define _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#include<iostream>
#include<unordered_set>

using namespace std;

#define dprint(Exp,...) if(Exp){fprintf(stderr, __VA_ARGS__);}
#define printe(...) fprintf(stderr, __VA_ARGS__);
//#define printe(...) void();
#define printE(...) fprintf(stderr, __VA_ARGS__);
//#define printE(...) void();


#define PrtExp(_Exp)  cerr<< #_Exp <<" = "<< (_Exp)
#define PrtExpN(_Exp)  cerr<< #_Exp <<" = "<< (_Exp) <<"\n"

#define SINT(n) scanf("%d",&n)
#define SINT2(n,m) scanf("%d %d",&n,&m)
#define SINT3(n,m,o) scanf("%d %d %d",&n,&m,&o)
#define SINT4(n,m,o,P) scanf("%d %d %d %d",&n,&m,&o,&P)
#define SINT5(n,m,o,P,q) scanf("%d %d %d %d %d",&n,&m,&o,&P,&q)
#define SLL(n) scanf("%lld",&n)
#define SLL2(n,m) scanf("%lld %lld",&n,&m)
#define SLL3(n,m,o) scanf("%lld %lld %lld",&n,&m,&o)
#define SST(s) scanf("%s",s)
#define SCH(c) scanf("%c",&c)

#define GC() getchar()

#define PINT(n) printf("%d",(int)(n))
#define PINT2(n,m) printf("%d %d",(int)(n),(int)(m))
#define PINT3(n,m,l) printf("%d %d %d",(int)(n),(int)(m),(int)(l))
#define PLL(n) printf("%lld",(long long)(n))
#define PST(s) printf("%s",(s))
#define PCH(s) printf("%c",(s))

#define PINTN(n) printf("%d\n",(int)(n))
#define PINT2N(n,m) printf("%d %d\n",(int)(n),(int)(m))
#define PINT3N(n,m,l) printf("%d %d %d\n",(int)(n),(int)(m),(int)(l))
#define PLLN(n) printf("%lld\n",(long long)(n))
#define PSTN(s) printf("%s\n",(s))
#define PCHN(s) printf("%c\n",(s))

#define PSP() printf(" ")
#define PN() printf("\n")

#define PC(c) putchar(c)
#define CSP (' ')
#define SN ("\n")

#define rep(i,a) for(int i=0;i<a;i++)
#define reP(i,a) for(int i=0;i<=a;i++)
#define Rep(i,a) for(int i=a-1;i>=0;i--)
#define ReP(i,a) for(int i=a;i>=0;i--)

#define rEp(i,a) for(i=0;i<a;i++)
#define rEP(i,a) for(i=0;i<=a;i++)
#define REp(i,a) for(i=a-1;i>=0;i--)
#define REP(i,a) for(i=a;i>=0;i--)

#define repft(i,a,b) for(int i=a;i<b;i++)
#define repfT(i,a,b) for(int i=a;i<=b;i++)
#define Repft(i,a,b) for(int i=a-1;i>=b;i--)
#define RepfT(i,a,b) for(int i=a;i>=b;i--)

#define foreach(a,it) for(auto it = a.begin(); it != a.end(); ++it)

#define FILL(a,v) fill(begin(a),end(a), v)
#define FILL0(a) memset(a,0,sizeof(a))
#define FILL1(a) memset(a,-1,sizeof(a))

typedef long long ll;

typedef unsigned long long ull;
typedef pair<int, int> Pi;
typedef pair<ll, ll>   Pll;


const int INF = 1'010'000'000; // 0x3C33'6080
const ll INFLL = 0x1f1f1f1f1f1f1f1fLL;//2,242,545,357,980,376,863

template <class A, class B> inline ostream& operator<<(ostream& st, const pair<A, B>& P) { return st << "(" << P.first << "," << P.second << ")"; };
template <class A, class B> inline pair<A, B> operator+(const pair<A, B>& P, const pair<A, B>& Q) { return pair<A, B>(P.first + Q.first, P.second + Q.second); };
template <class A, class B> inline pair<A, B> operator-(const pair<A, B>& P, const pair<A, B>& Q) { return pair<A, B>(P.first - Q.first, P.second - Q.second); };

#define fs  first
#define sc  second

int bitCount(unsigned int bits) {
	bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);    //  2bitごとに計算
	bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);    //  4bitごとに計算
	bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);    //  8bitごとに計算
	bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);    //  16ビットごとに計算   
	return (bits & 0x0000ffff) + (bits >> 16);    //  32ビット分を計算   
}


uint32_t xor64(void) {
	static uint64_t x = 88172645463325252ULL;
	x = x ^ (x << 13); x = x ^ (x >> 7);
	return x = x ^ (x << 17);
}


template <typename monoid>
struct segment_tree {
	using M = monoid;
	using T = typename M::value_type;

	std::size_t sz;
	std::vector<T> x;

	segment_tree(std::size_t n = 0) {
		sz = 1;
		while (sz < n) sz *= 2;
		x.assign(sz * 2, M::id());
		initialize();
	}

	template <typename iterator>
	segment_tree(iterator first, iterator last) {
		sz = 1;
		std::size_t n = std::distance(first, last);
		while (sz < n) sz *= 2;
		x.assign(sz * 2, M::id());
		std::copy(first, last, x.begin() + sz);
		initialize();
	}

	void fill(const T &val) {
		std::fill(x.begin() + sz, x.end(), val);
		initialize();
	}

	void initialize() {
		for (int i = (int)sz - 1; i >= 1; --i) {
			x[i] = M::op(x[i * 2 + 0], x[i * 2 + 1]);
		}
	}

	T accumulate(std::size_t l, std::size_t r) const {
		T al = M::id(), ar = M::id();
		for (l += sz, r += sz; l < r; l /= 2, r /= 2) {
			if (l & 1) al = M::op(al, x[l++]);
			if (r & 1) ar = M::op(x[--r], ar);
		}
		return M::op(al, ar);
	}

	void update(std::size_t i, const T &val) {
		x[i += sz] = val;
		while (i > 1) {
			x[i / 2] = M::op(x[i], x[i ^ 1]);
			i /= 2;
		}
	}

	T operator[](std::size_t i) const { return x[sz + i]; }
};

template <typename T>
struct xor_monoid {
	using value_type = T;
	static constexpr value_type id() { return 0; }
	static value_type op(const value_type &a, const value_type &b) { return a ^ b; }
};

template <typename value_type>
using rxq = segment_tree<xor_monoid<value_type>>;



int a[1 << 19];
int b[1 << 19];
int c[1 << 19];

int p[1 << 19];

void solve(const int m) {
	rep(i, m) {
		a[i * 2] = i;
		a[i * 2 + 1] = i;
	}
	rep(i, m * 2) {
		b[i] = i;
	}

	do {
		rep(i, m*2) c[i] = a[b[i]];
		rxq<int> s(m * 2);
		rep(i, m * 2) {
			s.update(i, c[i]);
		}
		FILL1(p);
		int V = -1;
		bool ok = true;
		rep(i, m * 2) {
			if (p[c[i]] < 0) {
				p[c[i]] = i;
			} else {
				int v = s.accumulate(p[c[i]], i+1);
				if (V < 0) {
					V = v;
				} else if(V != v){
					ok = false;
					break;
				}
			}
		}
		if (ok && V != 0) {
			printf("%d ", V);
			rep(i, m * 2) {
				printf(" %d", c[i]);
			}
			puts("");
		}



	} while (std::next_permutation(b, b+m*2));

	cout << "---------" << endl;


}

void calc(const int M, const int k) {
	vector<int> r;
	r.reserve(M * 2);

	r.push_back(k);
	rep(i, M) {
		if (i == k) continue;
		r.push_back(i);
	}
	r.push_back(k);
	Rep(i, M) {
		if (i == k) continue;
		r.push_back(i);
	}



	FILL1(p);
	bool ok = true;
	rxq<int> s(M * 2);
	rep(i, M * 2) {
		s.update(i, r[i]);
	}
	rep(i, M * 2) {
		if (p[r[i]] < 0) {
			p[r[i]] = i;
		} else {
			int v = s.accumulate(p[r[i]], i + 1);
			if (k != v) {
				ok = false;
				break;
			}
		}
	}
	if (!ok) {
		cout << "M" << M << " k" << k << "   ";
		rep(i, M * 2) {
			cout << r[i] << " ";
		}
		cout << endl;
	}


}



int main() {
	/*
	for (int m = 0; m <= 17; ++m) {
		cout << "m : " << m << endl;
		rep(k, 1 << m) {
			calc(1 << m, k);
		}

	}
	*/

	/*
	rep(i, 10) {
		solve(1<<i);
	}
	*/


	int m, k;
	while (cin >> m >> k) {
		int M = 1 << m;
		if (k == 0) {
			rep(i, M) {
				if (i > 0) printf(" ");
				printf("%d %d", i, i);
			}
			puts("");
			continue;
		}
		if (k >= M) {
			puts(("-1")); continue;
		}
		if (m <= 1) {
			puts(("-1")); continue;
		}

		printf("%d", k);
		rep(i, M) {
			if (i == k) continue;
			printf(" %d", i);
		}
		printf(" %d", k);
		Rep(i, M) {
			if (i == k) continue;
			printf(" %d", i);
		}
		puts("");
	}


	return 0;
}

Measured memory_bytes: 1792