Problem:
Score : 700 points

Problem Statement

For strings s and t, we will say that s and t are prefix-free when neither is a prefix of the other.

Let L be a positive integer. A set of strings S is a good string set when the following conditions hold true:

Each string in S has a length between 1 and L (inclusive) and consists of the characters 0 and 1.

Any two distinct strings in S are prefix-free.

We have a good string set S = \{ s_1, s_2, ..., s_N \}. Alice and Bob will play a game against each other. They will alternately perform the following operation, starting from Alice:

Add a new string to S. After addition, S must still be a good string set.

The first player who becomes unable to perform the operation loses the game. Determine the winner of the game when both players play optimally.

Constraints

1 \leq N \leq 10^5

1 \leq L \leq 10^{18}

s_1, s_2, ..., s_N are all distinct.

{ s_1, s_2, ..., s_N } is a good string set.

|s_1| + |s_2| + ... + |s_N| \leq 10^5

Input

Input is given from Standard Input in the following format:

N L
s_1
s_2
:
s_N

Output

If Alice will win, print Alice; if Bob will win, print Bob.

Sample Input 1

2 2
00
01

Sample Output 1

Alice

If Alice adds 1, Bob will be unable to add a new string.

Sample Input 2

2 2
00
11

Sample Output 2

Bob

There are two strings that Alice can add on the first turn: 01 and 10.
In case she adds 01, if Bob add 10, she will be unable to add a new string.
Also, in case she adds 10, if Bob add 01, she will be unable to add a new string.

Sample Input 3

3 3
0
10
110

Sample Output 3

Alice

If Alice adds 111, Bob will be unable to add a new string.

Sample Input 4

2 1
0
1

Sample Output 4

Bob

Alice is unable to add a new string on the first turn.

Sample Input 5

1 2
11

Sample Output 5

Alice

Sample Input 6

2 3
101
11

Sample Output 6

Bob

Solution in C++ (GCC 9.2.1) (judge verdict: Time Limit Exceeded)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define REP(i,n) for(int i=0,_n=(int)(n);i<_n;++i)
#define ALL(v) (v).begin(),(v).end()
#define CLR(t,v) memset(t,(v),sizeof(t))
template<class T1,class T2>ostream& operator<<(ostream& os,const pair<T1,T2>&a){return os<<"("<<a.first<<","<<a.second<< ")";}
template<class T>void pv(T a,T b){for(T i=a;i!=b;++i)cout<<(*i)<<" ";cout<<endl;}
template<class T>void chmin(T&a,const T&b){if(a>b)a=b;}
template<class T>void chmax(T&a,const T&b){if(a<b)a=b;}

ll nextLong() { ll x; scanf("%lld", &x); return x;}

ll grundy(ll H) {
  if (H <= 0) return 0;
  int lsb = 0;
  while ((H & 1)==0) {
    H >>= 1;
    lsb++;
  }
  return 1LL << lsb;
}

struct Trie {
  int l, r;
  Trie(){
    l = -1;
    r = -1;
  }
};

vector<Trie> tree;

void add(int id, int i, const string s) {

  if (i == (int)s.size()) {
    return;
  }

  if (s[i] == '0' && tree[id].l == -1) {
    tree[id].l = tree.size();
    tree.push_back(Trie());
  }
  if (s[i] == '1' && tree[id].r == -1) {
    tree[id].r = tree.size();
    tree.push_back(Trie());
  }
  add((s[i]=='0' ? (tree[id].l) : (tree[id].r)), i+1, s);
}

ll ans = 0;
void run(int id, string s, const ll L) {

  Trie &node = tree[id];

  if (node.l == -1 && node.r == -1) {
    return;
  }

  if (node.l != -1) {
    run(node.l, s + string("0"), L);
  }
  if (node.r != -1) {
    run(node.r, s + string("1"), L);
  }


  if ((node.l == -1) ^ (node.r == -1)) {
    // cout << "s=" << s << " ";
    ll h = L - s.size();
    // cout << "h=" << h << " " << grundy(h) << endl;
    ans ^= grundy(h);
  }


}

int main2() {
  int N = nextLong();
  ll L = nextLong();

  tree.clear();
  Trie root = Trie();
  tree.push_back(root);

  REP(i, N) {
    string s; cin >> s;
    add(0, 0, s);
  }

  ans = 0;
  run(0, "", L);

  return ans != 0;
}

int main() {

  // int N = 20;
  // vector<int> gg(N+1);

  // gg[0] = 0;
  // gg[1] = 1;
  // for (int i = 2; i <= N; i++) {
  //   set<int> vis;
  //   vis.insert(0);
  //   int acc = 0;
  //   for (int j = i-1; j >= 0; j--) {
  //     acc ^= gg[j];
  //     vis.insert(acc);
  //   }

  //   int g = 0;
  //   while (vis.count(g) > 0) g++;
  //   gg[i] = g;

  //   cout << i << " " << gg[i] << " " << grundy(i) << endl;
  // }

  // return 0;


#ifdef LOCAL
  // for (;!cin.eof();cin>>ws)
#endif
    cout << (main2() ? "Alice" : "Bob") << endl;
  return 0;
}