#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
constexpr int M = 22, N = (1 << M) + 9;
int a[N], rt[N], cnt[60 * N], ls[60 * N], rs[60 * N], rtl[(1 << (M + 1)) + 10], rtr[(1 << (M + 1)) + 10], b[N];
int n, k, idx;
inline int read() {
int x = 0; char c = getchar(), fs = 0; while(! isdigit(c)) fs |= (c == '-'), c = getchar();
while(isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return fs ? -x : x;
}
void build(int p, int l, int r) {
rtl[p] = l, rtr[p] = r;
if (l == r) {
b[l] = p;
return;
}
int m = (l + r) >> 1;
build(2 * p, l, m);
build(2 * p + 1, m + 1, r);
}
void add(int p, int &q, int l, int r, int x, int v) {
cnt[q = ++idx] = cnt[p];
ls[q] = ls[p];
rs[q] = rs[p];
if (l == r) {
cnt[q] += v;
return;
}
int m = l + r >> 1;
if (x <= m) {
add(ls[p], ls[q], l, m, x, v);
} else {
add(rs[p], rs[q], m + 1, r, x, v);
}
cnt[q] = cnt[ls[q]] + cnt[rs[q]];
}
int query(int p, int q, int l, int r, int x, int y) {
if (l > y || r < x) {
return 0;
}
if (l >= x && r <= y) {
return cnt[q] - cnt[p];
}
int m = l + r >> 1;
return query(ls[p], ls[q], l, m, x, y) + query(rs[p], rs[q], m + 1, r, x, y);
}
bool check(int i, int x) {
int now = b[i] / (1 << x);
int l = rtl[now], r = rtr[now], cnt = query(rt[l - 1], rt[r], 1, (1 << n), a[i] + 1, (1 << n));
int len = r - l + 1, has = a[i] - 1, use = len - cnt - 1;
has -= use;
if (cnt <= k && has >= cnt) {
return true;
}
return false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
n = read(), k = read();
const int m = (1 << n);
for (int i = 1; i <= m; i++) {
a[i] = read();
add(rt[i - 1], rt[i], 1, m, a[i], 1);
}
build(1, 1, m);
for (int i = 1; i <= m; i++) {
int lo = 0, hi = n;
while (lo < hi) {
int m = (lo + hi + 1) / 2;
if (check(i, m)) {
lo = m;
} else {
hi = m - 1;
}
}
cout << lo << " \n"[i == m];
}
return 0;
}