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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

// package arc.arc087;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        
        int n = in.nextInt();
        long L = in.nextLong();
        char[][] s = new char[n][];
        for (int i = 0; i < n ; i++) {
            s[i] = in.nextToken().toCharArray();
        }

        zero  = new int[SIZE];
        one   = new int[SIZE];
        depth = new int[SIZE];
        flg   = new int[SIZE];
        Arrays.fill(zero, -1);
        Arrays.fill(one, -1);
        Arrays.fill(flg, -1);
        ID = 1;
        depth[0] = 0;
        flg[0] = 1;

        for (char[] si : s) {
            dfs(si, 0, 0);
        }

        long xor = 0;
        for (int i = 0 ; i < ID ; i++) {
            if (flg[i] == 0) {
                long D = L - depth[i] + 1;
                xor ^= solve(D);
            }
        }

        out.println(xor == 0 ? "Bob" : "Alice");
        out.flush();
    }

    private static long solve(long D) {
        if (D == 0) {
            return 0;
        }
        long a = 1;
        while ((D & 1) == 0) {
            a *= 2;
            D >>= 1;
        }
        return a;
    }

    static void dfs(char[] s, int idx, int node) {
        flg[node] = 1;
        if (idx >= s.length) {
            return;
        }
        if (zero[node] == -1) {
            int L = ID++;
            int R = ID++;
            zero[node] = L;
            one[node] = R;
            depth[L] = idx+1;
            depth[R] = idx+1;
            flg[L] = flg[R] = 0;
        }
        int next = s[idx] == '0' ? zero[node] : one[node];
        dfs(s, idx+1, next);
    }



    static int SIZE = 400000;
    static int ID;
    static int[] flg;
    static int[] zero;
    static int[] one;
    static int[] depth;

    public static void debug(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }

    public static class InputReader {
        private static final int BUFFER_LENGTH = 1 << 12;
        private InputStream stream;
        private byte[] buf = new byte[BUFFER_LENGTH];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        private int next() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public char nextChar() {
            return (char) skipWhileSpace();
        }

        public String nextToken() {
            int c = skipWhileSpace();
            StringBuilder res = new StringBuilder();
            do {
                res.append((char) c);
                c = next();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public long nextLong() {
            int c = skipWhileSpace();
            long sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = next();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = next();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public double nextDouble() {
            return Double.valueOf(nextToken());
        }

        int skipWhileSpace() {
            int c = next();
            while (isSpaceChar(c)) {
                c = next();
            }
            return c;
        }

        boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }
    }
}