#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <functional>
#include <queue>
#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))
using namespace std;

typedef pair<int, int> pii;
typedef long long li;
typedef unsigned long long lu;
const int inf = ~0U >> 2;
const li infl = ~0LLU >> 2;

template <class T> inline void Min(T &x, T y) { if (y < x) x = y; }
template <class T> inline void Max(T &x, T y) { if (y > x) x = y; }

const int mod = 1e9 + 7;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) { int z = 1;
  for (; y; y >>= 1, x = Mul(x, x)) { if (y & 1) z = Mul(z, x); } return z; }
inline int Inv(int x) { return Pow(x, mod - 2); }
inline int Fix(li x) { x %= mod; if (x < 0) x += mod; return (int)x; }
inline int Fix(int x) { x %= mod; if (x < 0) x += mod; return x; }

// ----------------------------------------

const int maxn = 20;

int n, k;
char str[(1 << maxn + 1) + 1];
int slen[1 << maxn + 1];
int dp[1 << maxn + 1][maxn + 1];

int Insert(int x, int i, int b) {
  int L = slen[x];
  x -= 1 << L;
  int low = x & (1 << i) - 1;
  x = (x - low) << 1 | (b << i) | low;
  x += 1 << L + 1;
  return x;
}

// int ans[maxn], L;

// void Dfs(int i, int bit) {
//   if (i == n) {
//     if (dp[(1 << L) + bit][0] >= k) {
//       for (int j = 0; j < L; ++j) {
//         putchar('0' + ans[j]);
//       }
//       putchar('\n');
//       exit(0);
//     }
//     return;
//   }
//   for (ans[i] = 0; ans[i] <= 1; ++ans[i]) {
//     int nxt = bit | ans[i] << i;
//     Dfs(i + 1, nxt);
//   }
// }

// void Smallest(int l) {
//   L = l;
//   Dfs(0, 0);
// }

int main(void) {
  scanf("%d%d", &n, &k);
  for (int i = 0; i <= n; ++i) {
    scanf("%s", str + (1 << i));
    fill(slen + (1 << i), slen + (1 << i + 1), i);
  }
  for (int x = (1 << n + 1) - 1; x >= 1; --x) {
    int L = slen[x];
    for (int i = L; i >= 0; --i) {
      dp[x][i] = 0;

      // end here
      if (i == L) {
        dp[x][i] += str[x] - '0';
      }

      // insert 0
      if (L < n && (i == L || (x >> i & 1) == 1)) {
        dp[x][i] += dp[Insert(x, i, 0)][i + 1];
      }

      // insert 1
      if (L < n && (i == L || (x >> i & 1) == 0)) {
        dp[x][i] += dp[Insert(x, i, 1)][i + 1];
      }

      // advance
      if (i < L) {
        dp[x][i] += dp[x][i + 1];
      }
    }
  }

  // for (int L = n; L >= 0; --L) {
  //   bool exist = false;
  //   for (int x = (1 << L); x < (1 << L + 1); ++x) {
  //     if (dp[x][0] >= k) {
  //       exist = true;
  //       break;
  //     }
  //   }
  //   if (exist) {
  //     Smallest(L);
  //     return 0;
  //   }
  // }

  // for (int x = (1 << n + 1) - 1; x >= 1; --x) {
  for (int L = n; L >= 0; --L) {
    for (int x = 1 << L; x < 1 << L + 1; ++x) {
      if (dp[x][0] >= k) {
        int y = x - (1 << L);
        for (int i = 0; i < L; ++i) {
          putchar('0' + (y >> L - i - 1 & 1));
        }
        putchar('\n');
        return 0;
      }
    }
  }

  throw;
}


Measured memory_bytes: 182656