#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_imports)]
use std::io::stdin;

mod util {
    use std::io::stdin;
    use std::str::FromStr;
    use std::fmt::Debug;

    #[allow(dead_code)]
    pub fn line() -> String {
        let mut line: String = String::new();
        stdin().read_line(&mut line).unwrap();
        line.trim().to_string()
    }

    #[allow(dead_code)]
    pub fn gets<T: FromStr>() -> Vec<T>
    where
        <T as FromStr>::Err: Debug,
    {
        let mut line: String = String::new();
        stdin().read_line(&mut line).unwrap();
        line.split_whitespace()
            .map(|t| t.parse().unwrap())
            .collect()
    }
}

#[allow(unused_macros)]
macro_rules! get {
    ($t:ty) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.trim().parse::<$t>().unwrap()
        }
    };
    ($($t:ty),*) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            (
                $(iter.next().unwrap().parse::<$t>().unwrap(),)*
            )
        }
    };
    ($t:ty; $n:expr) => {
        (0..$n).map(|_|
                    get!($t)
                   ).collect::<Vec<_>>()
    };
    ($($t:ty),*; $n:expr) => {
        (0..$n).map(|_|
                    get!($($t),*)
                   ).collect::<Vec<_>>()
    };
    ($t:ty ;;) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.split_whitespace()
                .map(|t| t.parse::<$t>().unwrap())
                .collect::<Vec<_>>()
        }
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

use std::cell::RefCell;

struct Trie {
    depth: u64,
    left: Option<Box<RefCell<Trie>>>,
    right: Option<Box<RefCell<Trie>>>,
}

impl Trie {
    fn new(depth: u64) -> Trie {
        Trie {
            depth: depth,
            left: None,
            right: None,
        }
    }

    fn add(&mut self, s: &[char]) {
        if s.is_empty() {
        } else if s[0] == '0' {
            if self.left.is_none() {
                self.left = Some(Box::new(RefCell::new(Trie::new(self.depth + 1))));
            }
            self.left.as_mut().unwrap().borrow_mut().add(&s[1..]);
        } else {
            if self.right.is_none() {
                self.right = Some(Box::new(RefCell::new(Trie::new(self.depth + 1))));
            }
            self.right.as_mut().unwrap().borrow_mut().add(&s[1..]);
        }
    }

    fn tails(&self) -> Vec<u64> {
        let mut l = self.left
            .as_ref()
            .map(|c| c.borrow().tails())
            .unwrap_or(vec![self.depth]);

        let mut r = self.right
            .as_ref()
            .map(|c| c.borrow().tails())
            .unwrap_or(vec![self.depth]);

        if l.len() > r.len() {
            l.append(&mut r);
            l
        } else {
            r.append(&mut l);
            r
        }
    }
}

fn main() {
    let (n, l) = get!(usize, u64);
    let ss = get!(String; n);

    let mut trie = Trie::new(0);

    for s in &ss {
        let v = s.chars().collect::<Vec<_>>();
        trie.add(&v);
    }

    // debug!(trie.tails());

    if trie.tails()
        .iter()
        .map(|&d| l - d)
        .map(|x| {
            if x == 0 {
                0
            } else {
                1u64 << x.trailing_zeros()
            }
        })
        .fold(0, |a, b| a ^ b) == 0
    {
        println!("Bob");
    } else {
        println!("Alice");
    }
}


Measured memory_bytes: 24060