#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define int ll

#define REP(i,n) for(int i=0;i<n;++i)
#define SORT(name) sort(name.begin(), name.end())
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
#if 1
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
const int MOD = 1000000007;
#define MAX_M 20

#define SUBMIT

ll M, K;
ll fact[MAX_M];

void Disp(vector<ll> v) {
    REP(i, v.size()) { printf("%lld%c", v[i], (i == v.size()-1) ? '\n' : ' '); }
}

// val が 2 回出てくるとき、 2 回目の方のインデックスを返す
ll get_tail(const vector<ll>& v, ll val) {
    int cnt = 0;
    REP(i, v.size()) {
        if(v[i] == val) {
            cnt++;
            if(cnt == 2) { return i; }
        }
    }
    assert(false);
    return -1;
}

vector<ll> blute_force() {
    vector<ll> v;
    v.push_back(0);
    v.push_back(0);
    for(int i = 1; i < fact[M]; ++i) {
        v.push_back(i);
        v.push_back(i);
    }

    do {
        bool isAnswer = true;
        // val_to_pos の作成
        vector< pair<ll, ll> > val_to_pos(fact[M], make_pair(-1, -1));
        REP(i, v.size()) {
            if(val_to_pos[v[i]].first < 0) { val_to_pos[v[i]].first = i; }
            else { val_to_pos[v[i]].second = i; }
        }

        REP(i, v.size()) {
            ll tail = val_to_pos[v[i]].second;
            if(i == tail){ continue; }
            ll cur = 0;
            for(int j = i; j <= tail; ++j) {
                cur ^= v[j];
            }
            if(cur != K) {
                isAnswer = false;
                break;
            }
        }
        if(isAnswer) { return v; }
    } while( next_permutation(v.begin(), v.end()) );

    // 条件を満たす v はなかった
    vector<ll> ret = {-1};
    return ret;
}

// M のとき、条件を満たす K がある数列を出力
void experiment() {
    vector<ll> v;
    v.push_back(0);
    v.push_back(0);
    for(int i = 1; i < fact[M]; ++i) {
        v.push_back(i);
        v.push_back(i);
    }

    do {
        bool isAnswer = true;
        // val_to_pos の作成
        vector< pair<ll, ll> > val_to_pos(fact[M], make_pair(-1, -1));
        REP(i, v.size()) {
            if(val_to_pos[v[i]].first < 0) { val_to_pos[v[i]].first = i; }
            else { val_to_pos[v[i]].second = i; }
        }

        int cur_k = -1;

        REP(i, v.size()) {
            ll tail = val_to_pos[v[i]].second;
            if(i == tail){ continue; }
            ll cur = 0;
            for(int j = i; j <= tail; ++j) {
                cur ^= v[j];
            }
            if(cur_k == -1) {
                cur_k = cur;
            }
            else {
                if(cur != cur_k) {
                    isAnswer = false;
                    break;
                }
            }
        }
        if(isAnswer) {
            //return v;
            printf("k: %lld ans:", cur_k);
            Disp(v);
        }
    } while( next_permutation(v.begin(), v.end()) );
}

vector<ll> solve() {
    if(M <= 2) { return blute_force(); }
    vector<ll> ret;
    // K が 2^M 以上なら不可能
    if(K >= fact[M]) {
        ret.push_back(-1);
        return ret;
    }

    // 自分より小さいもので挟む部分を作成
    for(int i = 0; i < K; ++i) { ret.push_back(i); }
    ret.push_back(K);
    for(int i = K-1; i >= 0; --i) { ret.push_back(i); }
    // K より大きいもので順に K をはさむ
    for(int i = fact[M]-1; i > K; --i) { ret.push_back(i); }
    ret.push_back(K);
    for(int i = K + 1; i < fact[M]; ++i) { ret.push_back(i); }

    return ret;
}

signed main()
{
    fact[0] = 1;
    for(int i = 1; i < MAX_M; ++i) { fact[i] = fact[i-1] * 2; }
#ifdef SUBMIT
    cin >> M >> K;
    vector<ll> ans = solve();
    //vector<ll> ans = blute_force();
    Disp(ans);
#else
    const int m_limit = 2;
    const int k_limit = fact[m_limit];
    for(M = 0; M <= m_limit; ++M) {
        printf("M: %lld\n", M);
        //experiment();
        for(K = 0; K <= k_limit; ++K) {
            vector<ll> ans = blute_force();
            printf("K: %lld ans: ", K);
            Disp(ans);
        }
    }
    //M = 4; K = 3;
    //vector<ll> ans = blute_force();
    //printf("M; %lld K: %lld ans: ", M, K);
    //Disp(ans);
#endif
    return 0;
}


Measured memory_bytes: 6000