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 Rust (1.15.1) (judge verdict: Wrong Answer)

/// Thank you tanakh!!!
/// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

const NONE: usize = 1 << 15;

struct Node {
    right: usize,
    left: usize,
    depth: usize,
}

impl Node {
    fn new(depth: usize) -> Self {
        Node {
            right: NONE,
            left: NONE,
            depth: depth,
        }
    }
    fn size(&self) -> usize {
        let mut count = 0;
        if self.right != NONE {
            count += 1;
        }
        if self.left != NONE {
            count += 1;
        }
        count
    }
}

struct Trie {
    nodes: Vec<Node>,
}

impl Trie {
    fn add(&mut self, s: &Vec<char>) {
        let mut cur = 0;
        for pos in 0..s.len() {
            let depth = self.nodes[cur].depth;
            if s[pos] == '0' {
                if self.nodes[cur].left == NONE {
                    self.nodes[cur].left = self.nodes.len();
                    self.nodes.push(Node::new(depth + 1));
                }
                cur = self.nodes[cur].left;
            } else {
                if self.nodes[cur].right == NONE {
                    self.nodes[cur].right = self.nodes.len();
                    self.nodes.push(Node::new(depth + 1));
                }
                cur = self.nodes[cur].right;
            }
        }
    }
}

fn main() {
    input!(n: usize, l: usize, s: [chars; n]);
    let mut trie = Trie {
        nodes: vec![Node::new(0)],
    };
    for s in s.iter() {
        trie.add(s);
    }

    let mut grundy = vec![];
    for node in trie.nodes.iter() {
        if node.size() == 1 {
            let depth = node.depth;
            let level = l - depth;
            let mut cur = 1;
            while level % (cur * 2) == 0 {
                cur *= 2;
            }
            grundy.push(cur);
        }
    }

    let mut a = 0;
    for &grundy in grundy.iter() {
        a ^= grundy;
    }
    println!("{}", if a == 0 { "Bob" } else { "Alice" });
}