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: Accepted)

fn grundy(mut level: usize) -> i64 {
    assert!(level != 0);
    let mut res = 1;
    while level & 1 == 0 {
        level >>= 1;
        res += 1;
    }
    res
}

struct Node {
    next: (Option<usize>, Option<usize>),
}

impl Node {
    fn new() -> Node {
        Node { next: (None, None) }
    }
}

fn add(v: &Vec<char>, trie: &mut Vec<Node>) {
    let mut cur = 0;
    for c in v {
        let next = match *c {
            '0' => trie[cur].next.0,
            '1' => trie[cur].next.1,
            _ => panic!(),
        };
        let next = match next {
            Some(idx) => idx,
            None => {
                trie.push(Node::new());
                trie.len() - 1
            }
        };
        match *c {
            '0' => trie[cur].next.0 = Some(next),
            '1' => trie[cur].next.1 = Some(next),
            _ => panic!(),
        };
        cur = next;
    }
}

fn dfs(cur: usize, l: usize, trie: &Vec<Node>) -> i64 {
    if l >= 1 {
        match trie[cur].next {
            (Some(left), Some(right)) => dfs(left, l - 1, trie) ^ dfs(right, l - 1, trie),
            (Some(left), None) => dfs(left, l - 1, trie) ^ grundy(l),
            (None, Some(right)) => grundy(l) ^ dfs(right, l - 1, trie),
            (None, None) => 0,
        }
    } else {
        0
    }
}

fn main() {
    let (n, l): (usize, usize) = readln();
    let v: Vec<Vec<char>> = readlns(n);

    let mut trie = vec![Node::new()];
    for s in &v {
        add(s, &mut trie);
    }

    let grundy = dfs(0, l, &trie);
    if grundy == 0 {
        println!("Bob");
    } else {
        println!("Alice");
    }
}

// --- template ---
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::{HashMap, HashSet};

pub trait FromLn {
    fn fromln(s: &str) -> Self;
}
pub fn readln<T: FromLn>() -> T {
    let mut buf = String::new();
    let _ = ::std::io::stdin().read_line(&mut buf).unwrap();
    T::fromln(buf.trim())
}
pub fn readlns<T: FromLn>(n: usize) -> Vec<T> {
    let mut vs = vec![];
    for _ in 0..n {
        vs.push(readln());
    }
    vs
}
macro_rules! fromln_primitives {
    ($($t:ty),*) => { $(
        impl FromLn for $t {
            fn fromln(s: &str) -> $t {
                s.parse().unwrap()
            }
        }
    )* }
}
fromln_primitives!(
    String,
    bool,
    f32,
    f64,
    isize,
    i8,
    i16,
    i32,
    i64,
    usize,
    u8,
    u16,
    u32,
    u64
);
impl<T> FromLn for Vec<T>
where
    T: FromLn,
{
    fn fromln(s: &str) -> Vec<T> {
        s.split_whitespace().map(T::fromln).collect()
    }
}
impl FromLn for Vec<char> {
    fn fromln(s: &str) -> Vec<char> {
        s.chars().collect()
    }
}
macro_rules! fromln_tuple {
    ($($t:ident),*) => {
        impl<$($t),*> FromLn for ($($t),*) where $($t: FromLn),* {
            fn fromln(s: &str) -> ($($t),*) {
                let mut it = s.split_whitespace();
                let t = ($($t::fromln(it.next().unwrap())),*);
                assert_eq!(it.next(), None);
                t
            }
        }
    }
}
fromln_tuple!(A, B);
fromln_tuple!(A, B, C);
fromln_tuple!(A, B, C, D);
fromln_tuple!(A, B, C, D, E);
fromln_tuple!(A, B, C, D, E, F);