// ---------- begin ModInt ----------
mod modint {

    #[allow(dead_code)]
    pub struct Mod;
    impl ConstantModulo for Mod {
        const MOD: u32 = 1_000_000_007;
    }

    #[allow(dead_code)]
    pub struct StaticMod;
    static mut STATIC_MOD: u32 = 0;
    impl Modulo for StaticMod {
        fn modulo() -> u32 {
            unsafe { STATIC_MOD }
        }
    }

    #[allow(dead_code)]
    impl StaticMod {
        pub fn set_modulo(p: u32) {
            unsafe {
                STATIC_MOD = p;
            }
        }
    }

    use std::marker::*;
    use std::ops::*;

    pub trait Modulo {
        fn modulo() -> u32;
    }

    pub trait ConstantModulo {
        const MOD: u32;
    }

    impl<T> Modulo for T
    where
        T: ConstantModulo,
    {
        fn modulo() -> u32 {
            T::MOD
        }
    }

    pub struct ModInt<T>(pub u32, PhantomData<T>);

    impl<T> Clone for ModInt<T> {
        fn clone(&self) -> Self {
            ModInt::new_unchecked(self.0)
        }
    }

    impl<T> Copy for ModInt<T> {}

    impl<T: Modulo> Add for ModInt<T> {
        type Output = ModInt<T>;
        fn add(self, rhs: Self) -> Self::Output {
            let mut d = self.0 + rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            ModInt::new_unchecked(d)
        }
    }

    impl<T: Modulo> AddAssign for ModInt<T> {
        fn add_assign(&mut self, rhs: Self) {
            *self = *self + rhs;
        }
    }

    impl<T: Modulo> Sub for ModInt<T> {
        type Output = ModInt<T>;
        fn sub(self, rhs: Self) -> Self::Output {
            let mut d = T::modulo() + self.0 - rhs.0;
            if d >= T::modulo() {
                d -= T::modulo();
            }
            ModInt::new_unchecked(d)
        }
    }

    impl<T: Modulo> SubAssign for ModInt<T> {
        fn sub_assign(&mut self, rhs: Self) {
            *self = *self - rhs;
        }
    }

    impl<T: Modulo> Mul for ModInt<T> {
        type Output = ModInt<T>;
        fn mul(self, rhs: Self) -> Self::Output {
            let v = self.0 as u64 * rhs.0 as u64 % T::modulo() as u64;
            ModInt::new_unchecked(v as u32)
        }
    }

    impl<T: Modulo> MulAssign for ModInt<T> {
        fn mul_assign(&mut self, rhs: Self) {
            *self = *self * rhs;
        }
    }

    impl<T: Modulo> Neg for ModInt<T> {
        type Output = ModInt<T>;
        fn neg(self) -> Self::Output {
            if self.0 == 0 {
                Self::zero()
            } else {
                Self::new_unchecked(T::modulo() - self.0)
            }
        }
    }

    impl<T> std::fmt::Display for ModInt<T> {
        fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
            write!(f, "{}", self.0)
        }
    }

    impl<T> std::fmt::Debug for ModInt<T> {
        fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
            write!(f, "{}", self.0)
        }
    }

    impl<T: Modulo> std::str::FromStr for ModInt<T> {
        type Err = std::num::ParseIntError;
        fn from_str(s: &str) -> Result<Self, Self::Err> {
            let val = s.parse::<u32>()?;
            Ok(ModInt::new(val))
        }
    }

    impl<T: Modulo> From<usize> for ModInt<T> {
        fn from(val: usize) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as usize) as u32)
        }
    }

    impl<T: Modulo> From<u64> for ModInt<T> {
        fn from(val: u64) -> ModInt<T> {
            ModInt::new_unchecked((val % T::modulo() as u64) as u32)
        }
    }

    impl<T: Modulo> From<i64> for ModInt<T> {
        fn from(val: i64) -> ModInt<T> {
            let m = T::modulo() as i64;
            ModInt::new((val % m + m) as u32)
        }
    }

    #[allow(dead_code)]
    impl<T> ModInt<T> {
        pub fn new_unchecked(d: u32) -> Self {
            ModInt(d, PhantomData)
        }
        pub fn zero() -> Self {
            ModInt::new_unchecked(0)
        }
        pub fn one() -> Self {
            ModInt::new_unchecked(1)
        }
        pub fn is_zero(&self) -> bool {
            self.0 == 0
        }
    }

    #[allow(dead_code)]
    impl<T: Modulo> ModInt<T> {
        pub fn new(d: u32) -> Self {
            ModInt::new_unchecked(d % T::modulo())
        }
        pub fn pow(&self, mut n: u64) -> Self {
            let mut t = Self::one();
            let mut s = *self;
            while n > 0 {
                if n & 1 == 1 {
                    t *= s;
                }
                s *= s;
                n >>= 1;
            }
            t
        }
        pub fn inv(&self) -> Self {
            assert!(self.0 != 0);
            self.pow(T::modulo() as u64 - 2)
        }
    }
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
mod precalc {
    use super::modint::*;
    #[allow(dead_code)]
    pub struct Precalc<T> {
        inv: Vec<ModInt<T>>,
        fact: Vec<ModInt<T>>,
        ifact: Vec<ModInt<T>>,
    }
    #[allow(dead_code)]
    impl<T: Modulo> Precalc<T> {
        pub fn new(n: usize) -> Precalc<T> {
            let mut inv = vec![ModInt::one(); n + 1];
            let mut fact = vec![ModInt::one(); n + 1];
            let mut ifact = vec![ModInt::one(); n + 1];
            for i in 2..(n + 1) {
                fact[i] = fact[i - 1] * ModInt::new_unchecked(i as u32);
            }
            ifact[n] = fact[n].inv();
            if n > 0 {
                inv[n] = ifact[n] * fact[n - 1];
            }
            for i in (1..n).rev() {
                ifact[i] = ifact[i + 1] * ModInt::new_unchecked((i + 1) as u32);
                inv[i] = ifact[i] * fact[i - 1];
            }
            Precalc {
                inv: inv,
                fact: fact,
                ifact: ifact,
            }
        }
        pub fn inv(&self, n: usize) -> ModInt<T> {
            assert!(n > 0);
            self.inv[n]
        }
        pub fn fact(&self, n: usize) -> ModInt<T> {
            self.fact[n]
        }
        pub fn ifact(&self, n: usize) -> ModInt<T> {
            self.ifact[n]
        }
        pub fn perm(&self, n: usize, k: usize) -> ModInt<T> {
            if k > n {
                return ModInt::zero();
            }
            self.fact[n] * self.ifact[n - k]
        }
        pub fn comb(&self, n: usize, k: usize) -> ModInt<T> {
            if k > n {
                return ModInt::zero();
            }
            self.fact[n] * self.ifact[k] * self.ifact[n - k]
        }
    }
}
// ---------- end Precalc ----------

use modint::*;
type M = ModInt<StaticMod>;

// ---------- begin input macro ----------
// reference: 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 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, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
// ---------- end input macro ----------

fn run() {
    input! {
        n: usize,
        m: u32,
    }
    StaticMod::set_modulo(m);
    let pc = precalc::Precalc::new(n);
    let mut pow = vec![M::one(); n + 1];
    let two = M::new(2);
    for i in 1..=n {
        pow[i] = pow[i - 1] * two;
    }
    // dp[a][b]: 最後の空白がa, b個置いた
    let mut dp = vec![vec![M::zero(); n + 2]; n + 2];
    dp[0][0] = M::one();
    for i in 0..=n {
        for j in 0..=i {
            let way = dp[i][j];
            if way.is_zero() {
                continue;
            }
            for k in 1..=(n - i) {
                dp[i + k + 1][j + k] += pow[k - 1] * way * pc.comb(j + k, j);
            }
        }
    }
    let mut ans = M::zero();
    for dp in dp[n + 1].iter() {
        ans += *dp;
    }
    println!("{}", ans);
}

fn main() {
    run();
}


// codesnip-guard: main
fn main() {
    #![allow(unused_imports, unused_macros)]
    prepare_io!(_in_buf, scanner, _out);
    macro_rules ! print { ($ ($ arg : tt) *) => (:: std :: write ! (_out , $ ($ arg) *) . expect ("io error")) }
    macro_rules ! println { ($ ($ arg : tt) *) => (:: std :: writeln ! (_out , $ ($ arg) *) . expect ("io error")) }
    scan!(scanner, n, m);
    mint_basic::DynModuloU32::set_mod(m as _);
    let f = MemorizedFactorial::new(n * 2);
    let mut ans = M::zero();
    let mut dp = vec![vec![M::zero(); n + 1]; n + 1];
    let mut pre = vec![M::zero(); n + 1];
    for i in 1..=n {
        for j in 0..i {
            pre[i] += f.inv_fact[j] * f.inv_fact[i - j - 1];
        }
        pre[i] *= M::from(i).inv();
    }
    // processed, sikiri
    dp[0][0] = M::one();
    for i in 0..n {
        for j in 0..=i {
            let d = dp[i][j];
            if d.is_zero() {
                continue;
            }
            for k in 1..=n - i {
                let mut ni = i + k;
                let mut nj = j;
                if i > 0 {
                    ni += 1;
                    nj += 1;
                }
                if ni <= n {
                    dp[ni][nj] += d * pre[k];
                }
            }
        }
    }
    for j in 0..=n {
        ans += dp[n][j] * f.fact[n - j];
    }
    println!("{}", ans);
}
pub type M = mint_basic::DynMIntU32;
#[macro_export]
macro_rules! prepare_io {
    ($ in_buf : ident , $ scanner : ident , $ out : ident) => {
        use std::io::{stdout, BufWriter, Write as _};
        let $in_buf = read_stdin_all_unchecked();
        let mut $scanner = Scanner::new(&$in_buf);
        let $out = stdout();
        let mut $out = BufWriter::new($out.lock());
    };
}
// codesnip-guard: _echo
pub fn echo<T: std::fmt::Display>(
    mut writer: impl std::io::Write,
    iter: impl IntoIterator<Item = T>,
    sep: impl std::fmt::Display,
) -> std::io::Result<()> {
    let mut iter = iter.into_iter();
    if let Some(item) = iter.next() {
        write!(writer, "{}", item)?;
    }
    for item in iter {
        write!(writer, "{}{}", sep, item)?;
    }
    writeln!(writer)
}
// codesnip-guard: scanner
pub fn read_stdin_all_unchecked() -> String {
    use std::io::Read as _;
    let mut buf = Vec::new();
    std::io::stdin().read_to_end(&mut buf).expect("io error");
    unsafe { String::from_utf8_unchecked(buf) }
}
pub fn read_stdin_line() -> String {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).expect("io error");
    s
}
pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Clone, Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
mod scanner_impls {
    use super::*;
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn new(s: &'a str) -> Self {
            let iter = s.split_ascii_whitespace();
            Self { iter }
        }
        #[inline]
        pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
            <T as IterScan>::scan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
            marker.mscan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
            (0..size)
                .map(|_| <T as IterScan>::scan(&mut self.iter).expect("scan error"))
                .collect()
        }
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
    macro_rules ! iter_scan_impls { ($ ($ t : ty) *) => { $ (impl IterScan for $ t { type Output = Self ; # [inline] fn scan <'a , I : Iterator < Item = &'a str >> (iter : & mut I) -> Option < Self > { iter . next () ?. parse ::<$ t > () . ok () } }) * } ; }
    iter_scan_impls ! (char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String);
    macro_rules ! iter_scan_tuple_impl { ($ ($ T : ident) *) => { impl <$ ($ T : IterScan) ,*> IterScan for ($ ($ T ,) *) { type Output = ($ (<$ T as IterScan >:: Output ,) *) ; # [inline] fn scan <'a , It : Iterator < Item = &'a str >> (_iter : & mut It) -> Option < Self :: Output > { Some (($ (<$ T as IterScan >:: scan (_iter) ?,) *)) } } } ; }
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl ! (A B);
    iter_scan_tuple_impl ! (A B C);
    iter_scan_tuple_impl ! (A B C D);
    iter_scan_tuple_impl ! (A B C D E);
    iter_scan_tuple_impl ! (A B C D E F);
    iter_scan_tuple_impl ! (A B C D E F G);
    iter_scan_tuple_impl ! (A B C D E F G H);
    iter_scan_tuple_impl ! (A B C D E F G H I);
    iter_scan_tuple_impl ! (A B C D E F G H I J);
    iter_scan_tuple_impl ! (A B C D E F G H I J K);
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            <T as IterScan>::scan(&mut self.inner.iter)
        }
    }
}
#[derive(Debug, Copy, Clone)]
pub struct Usize1;
#[derive(Debug, Copy, Clone)]
pub struct CharWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Chars;
#[derive(Debug, Copy, Clone)]
pub struct CharsWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Collect<T: IterScan, B: std::iter::FromIterator<<T as IterScan>::Output>> {
    size: usize,
    _marker: std::marker::PhantomData<fn() -> (T, B)>,
}
mod marker_impls {
    use super::*;
    use std::{iter::FromIterator, marker::PhantomData};
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            <usize as IterScan>::scan(iter)?.checked_sub(1)
        }
    }
    impl MarkedIterScan for CharWithBase {
        type Output = usize;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some((<char as IterScan>::scan(iter)? as u8 - self.0 as u8) as usize)
        }
    }
    impl IterScan for Chars {
        type Output = Vec<char>;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(iter.next()?.chars().collect())
        }
    }
    impl MarkedIterScan for CharsWithBase {
        type Output = Vec<usize>;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                iter.next()?
                    .chars()
                    .map(|c| (c as u8 - self.0 as u8) as usize)
                    .collect(),
            )
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> Collect<T, B> {
        pub fn new(size: usize) -> Self {
            Self {
                size,
                _marker: PhantomData,
            }
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> MarkedIterScan for Collect<T, B> {
        type Output = B;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                (0..self.size)
                    .map(|_| <T as IterScan>::scan(iter).expect("scan error"))
                    .collect::<B>(),
            )
        }
    }
}
#[macro_export]
macro_rules ! scan_value { ($ scanner : expr , ($ ($ t : tt) ,*)) => { ($ ($ crate :: scan_value ! ($ scanner , $ t)) ,*) } ; ($ scanner : expr , [$ t : tt ; $ len : expr]) => { (0 ..$ len) . map (| _ | $ crate :: scan_value ! ($ scanner , $ t)) . collect ::< Vec < _ >> () } ; ($ scanner : expr , [$ t : ty ; $ len : expr]) => { $ scanner . scan_vec ::<$ t > ($ len) } ; ($ scanner : expr , [$ t : ty]) => { $ scanner . iter ::<$ t > () } ; ($ scanner : expr , { $ e : expr }) => { $ scanner . mscan ($ e) } ; ($ scanner : expr , $ t : ty) => { $ scanner . scan ::<$ t > () } ; }
#[macro_export]
macro_rules ! scan { ($ scanner : expr) => { } ; ($ scanner : expr ,) => { } ; ($ scanner : expr , mut $ var : tt : $ t : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , $ var : tt : $ t : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , mut $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , mut $ var : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , $ var : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , mut $ var : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; }
// codesnip-guard: MInt
pub mod mint_basic {
    use super::*;
    #[macro_export]
    macro_rules ! define_basic_mintbase { ($ name : ident , $ m : expr , $ basety : ty , $ signedty : ty , $ upperty : ty , [$ ($ unsigned : ty) ,*] , [$ ($ signed : ty) ,*]) => { pub struct $ name ; impl MIntBase for $ name { type Inner = $ basety ; # [inline] fn get_mod () -> Self :: Inner { $ m } # [inline] fn mod_zero () -> Self :: Inner { 0 } # [inline] fn mod_one () -> Self :: Inner { 1 } # [inline] fn mod_add (x : Self :: Inner , y : Self :: Inner) -> Self :: Inner { let z = x + y ; let m = Self :: get_mod () ; if z >= m { z - m } else { z } } # [inline] fn mod_sub (x : Self :: Inner , y : Self :: Inner) -> Self :: Inner { if x < y { x + Self :: get_mod () - y } else { x - y } } # [inline] fn mod_mul (x : Self :: Inner , y : Self :: Inner) -> Self :: Inner { (x as $ upperty * y as $ upperty % Self :: get_mod () as $ upperty) as $ basety } # [inline] fn mod_div (x : Self :: Inner , y : Self :: Inner) -> Self :: Inner { Self :: mod_mul (x , Self :: mod_inv (y)) } # [inline] fn mod_neg (x : Self :: Inner) -> Self :: Inner { if x == 0 { 0 } else { Self :: get_mod () - x } } fn mod_inv (x : Self :: Inner) -> Self :: Inner { let p = Self :: get_mod () as $ signedty ; let (mut a , mut b) = (x as $ signedty , p) ; let (mut u , mut x) = (1 , 0) ; while a != 0 { let k = b / a ; x -= k * u ; b -= k * a ; std :: mem :: swap (& mut x , & mut u) ; std :: mem :: swap (& mut b , & mut a) ; } (if x < 0 { x + p } else { x }) as _ } } $ (impl MIntConvert <$ unsigned > for $ name { # [inline] fn from (x : $ unsigned) -> Self :: Inner { (x % < Self as MIntBase >:: get_mod () as $ unsigned) as $ basety } # [inline] fn into (x : Self :: Inner) -> $ unsigned { x as $ unsigned } # [inline] fn mod_into () -> $ unsigned { < Self as MIntBase >:: get_mod () as $ unsigned } }) * $ (impl MIntConvert <$ signed > for $ name { # [inline] fn from (x : $ signed) -> Self :: Inner { let x = x % < Self as MIntBase >:: get_mod () as $ signed ; if x < 0 { (x + < Self as MIntBase >:: get_mod () as $ signed) as $ basety } else { x as $ basety } } # [inline] fn into (x : Self :: Inner) -> $ signed { x as $ signed } # [inline] fn mod_into () -> $ signed { < Self as MIntBase >:: get_mod () as $ signed } }) * } ; }
    #[macro_export]
    macro_rules ! define_basic_mint32 { ($ ([$ name : ident , $ m : expr , $ mint_name : ident]) ,*) => { $ (crate :: define_basic_mintbase ! ($ name , $ m , u32 , i32 , u64 , [u32 , u64 , u128 , usize] , [i32 , i64 , i128 , isize]) ; pub type $ mint_name = MInt <$ name >;) * } ; }
    define_basic_mint32!(
        [Modulo998244353, 998_244_353, MInt998244353],
        [Modulo1000000007, 1_000_000_007, MInt1000000007],
        [Modulo1000000009, 1_000_000_009, MInt1000000009],
        [
            DynModuloU32,
            DYN_MODULUS_U32.with(|cell| unsafe { *cell.get() }),
            DynMIntU32
        ]
    );
    thread_local ! (static DYN_MODULUS_U32 : std :: cell :: UnsafeCell < u32 > = std :: cell :: UnsafeCell :: new (1_000_000_007));
    impl DynModuloU32 {
        pub fn set_mod(m: u32) {
            DYN_MODULUS_U32.with(|cell| unsafe { *cell.get() = m })
        }
    }
    thread_local ! (static DYN_MODULUS_U64 : std :: cell :: UnsafeCell < u64 > = std :: cell :: UnsafeCell :: new (1_000_000_007));
    define_basic_mintbase!(
        DynModuloU64,
        DYN_MODULUS_U64.with(|cell| unsafe { *cell.get() }),
        u64,
        i64,
        u128,
        [u64, u128, usize],
        [i64, i128, isize]
    );
    impl DynModuloU64 {
        pub fn set_mod(m: u64) {
            DYN_MODULUS_U64.with(|cell| unsafe { *cell.get() = m })
        }
    }
    pub type DynMIntU64 = MInt<DynModuloU64>;
    pub struct Modulo2;
    impl MIntBase for Modulo2 {
        type Inner = u32;
        #[inline]
        fn get_mod() -> Self::Inner {
            2
        }
        #[inline]
        fn mod_zero() -> Self::Inner {
            0
        }
        #[inline]
        fn mod_one() -> Self::Inner {
            1
        }
        #[inline]
        fn mod_add(x: Self::Inner, y: Self::Inner) -> Self::Inner {
            x ^ y
        }
        #[inline]
        fn mod_sub(x: Self::Inner, y: Self::Inner) -> Self::Inner {
            x ^ y
        }
        #[inline]
        fn mod_mul(x: Self::Inner, y: Self::Inner) -> Self::Inner {
            x | y
        }
        #[inline]
        fn mod_div(x: Self::Inner, y: Self::Inner) -> Self::Inner {
            assert_ne!(y, 0);
            x
        }
        #[inline]
        fn mod_neg(x: Self::Inner) -> Self::Inner {
            x
        }
        #[inline]
        fn mod_inv(x: Self::Inner) -> Self::Inner {
            assert_ne!(x, 0);
            x
        }
        #[inline]
        fn mod_pow(x: Self::Inner, y: usize) -> Self::Inner {
            if y == 0 {
                1
            } else {
                x
            }
        }
    }
    macro_rules ! impl_to_mint_base_for_modulo2 { ($ name : ident , $ basety : ty , [$ ($ t : ty) ,*]) => { $ (impl MIntConvert <$ t > for $ name { # [inline] fn from (x : $ t) -> Self :: Inner { (x & 1) as $ basety } # [inline] fn into (x : Self :: Inner) -> $ t { x as $ t } # [inline] fn mod_into () -> $ t { 1 } }) * } ; }
    impl_to_mint_base_for_modulo2!(
        Modulo2,
        u32,
        [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize]
    );
    pub type MInt2 = MInt<Modulo2>;
}
// codesnip-guard: MIntBase
#[repr(transparent)]
pub struct MInt<M>
where
    M: MIntBase,
{
    x: M::Inner,
    _marker: std::marker::PhantomData<fn() -> M>,
}
pub trait MIntBase {
    type Inner: Sized + Copy + Eq + std::fmt::Debug + std::hash::Hash;
    fn get_mod() -> Self::Inner;
    fn mod_zero() -> Self::Inner;
    fn mod_one() -> Self::Inner;
    fn mod_add(x: Self::Inner, y: Self::Inner) -> Self::Inner;
    fn mod_sub(x: Self::Inner, y: Self::Inner) -> Self::Inner;
    fn mod_mul(x: Self::Inner, y: Self::Inner) -> Self::Inner;
    fn mod_div(x: Self::Inner, y: Self::Inner) -> Self::Inner;
    fn mod_neg(x: Self::Inner) -> Self::Inner;
    fn mod_inv(x: Self::Inner) -> Self::Inner;
    fn mod_pow(x: Self::Inner, y: usize) -> Self::Inner {
        let (mut x, mut y, mut z) = (x, y, Self::mod_one());
        while y > 0 {
            if y & 1 == 1 {
                z = Self::mod_mul(z, x);
            }
            x = Self::mod_mul(x, x);
            y >>= 1;
        }
        z
    }
}
pub trait MIntConvert<T = <Self as MIntBase>::Inner>: MIntBase {
    fn from(x: T) -> <Self as MIntBase>::Inner;
    fn into(x: <Self as MIntBase>::Inner) -> T;
    fn mod_into() -> T;
}
mod mint_base {
    use super::*;
    use std::{
        fmt::{self, Debug, Display},
        hash::{Hash, Hasher},
        iter::{Product, Sum},
        marker::PhantomData,
        ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
        str::FromStr,
    };
    impl<M> MInt<M>
    where
        M: MIntConvert,
    {
        #[inline]
        pub fn new(x: M::Inner) -> Self {
            Self::new_unchecked(<M as MIntConvert<M::Inner>>::from(x))
        }
        #[inline]
        pub fn inner(self) -> M::Inner {
            <M as MIntConvert<M::Inner>>::into(self.x)
        }
    }
    impl<M> MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        pub fn new_unchecked(x: M::Inner) -> Self {
            Self {
                x,
                _marker: PhantomData,
            }
        }
        #[inline]
        pub fn get_mod() -> M::Inner {
            M::get_mod()
        }
        #[inline]
        pub fn pow(self, y: usize) -> Self {
            Self::new_unchecked(M::mod_pow(self.x, y))
        }
        #[inline]
        pub fn inv(self) -> Self {
            Self::new_unchecked(M::mod_inv(self.x))
        }
    }
    impl<M> Clone for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn clone(&self) -> Self {
            Self {
                x: Clone::clone(&self.x),
                _marker: PhantomData,
            }
        }
    }
    impl<M> Copy for MInt<M> where M: MIntBase {}
    impl<M> Debug for MInt<M>
    where
        M: MIntBase,
    {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            Debug::fmt(&self.x, f)
        }
    }
    impl<M> Default for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn default() -> Self {
            <Self as Zero>::zero()
        }
    }
    impl<M> PartialEq for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn eq(&self, other: &Self) -> bool {
            PartialEq::eq(&self.x, &other.x)
        }
    }
    impl<M> Eq for MInt<M> where M: MIntBase {}
    impl<M> Hash for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn hash<H: Hasher>(&self, state: &mut H) {
            Hash::hash(&self.x, state)
        }
    }
    macro_rules ! impl_mint_from { ($ ($ t : ty) ,*) => { $ (impl < M > From <$ t > for MInt < M > where M : MIntConvert <$ t >, { # [inline] fn from (x : $ t) -> Self { Self :: new_unchecked (< M as MIntConvert <$ t >>:: from (x)) } } impl < M > From < MInt < M >> for $ t where M : MIntConvert <$ t >, { # [inline] fn from (x : MInt < M >) -> $ t { < M as MIntConvert <$ t >>:: into (x . x) } }) * } ; }
    impl_mint_from!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
    impl<M> Zero for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn zero() -> Self {
            Self::new_unchecked(M::mod_zero())
        }
    }
    impl<M> One for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn one() -> Self {
            Self::new_unchecked(M::mod_one())
        }
    }
    impl<M> Add for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn add(self, rhs: Self) -> Self::Output {
            Self::new_unchecked(M::mod_add(self.x, rhs.x))
        }
    }
    impl<M> Sub for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn sub(self, rhs: Self) -> Self::Output {
            Self::new_unchecked(M::mod_sub(self.x, rhs.x))
        }
    }
    impl<M> Mul for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn mul(self, rhs: Self) -> Self::Output {
            Self::new_unchecked(M::mod_mul(self.x, rhs.x))
        }
    }
    impl<M> Div for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn div(self, rhs: Self) -> Self::Output {
            Self::new_unchecked(M::mod_div(self.x, rhs.x))
        }
    }
    impl<M> Neg for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn neg(self) -> Self::Output {
            Self::new_unchecked(M::mod_neg(self.x))
        }
    }
    impl<M> Sum for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(<Self as Zero>::zero(), Add::add)
        }
    }
    impl<M> Product for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(<Self as One>::one(), Mul::mul)
        }
    }
    impl<'a, M: 'a> Sum<&'a MInt<M>> for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
            iter.fold(<Self as Zero>::zero(), Add::add)
        }
    }
    impl<'a, M: 'a> Product<&'a MInt<M>> for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
            iter.fold(<Self as One>::one(), Mul::mul)
        }
    }
    impl<M> Display for MInt<M>
    where
        M: MIntConvert,
        M::Inner: Display,
    {
        fn fmt<'a>(&self, f: &mut fmt::Formatter<'a>) -> Result<(), fmt::Error> {
            write!(f, "{}", self.inner())
        }
    }
    impl<M> FromStr for MInt<M>
    where
        M: MIntConvert,
        M::Inner: FromStr,
    {
        type Err = <M::Inner as FromStr>::Err;
        #[inline]
        fn from_str(s: &str) -> Result<Self, Self::Err> {
            s.parse::<M::Inner>().map(Self::new)
        }
    }
    impl<M> IterScan for MInt<M>
    where
        M: MIntConvert,
        M::Inner: FromStr,
    {
        type Output = Self;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            iter.next()?.parse::<MInt<M>>().ok()
        }
    }
    macro_rules! impl_mint_ref_binop {
        ($ imp : ident , $ method : ident , $ t : ty) => {
            impl<M> $imp<$t> for &$t
            where
                M: MIntBase,
            {
                type Output = <$t as $imp<$t>>::Output;
                #[inline]
                fn $method(self, other: $t) -> <$t as $imp<$t>>::Output {
                    $imp::$method(*self, other)
                }
            }
            impl<M> $imp<&$t> for $t
            where
                M: MIntBase,
            {
                type Output = <$t as $imp<$t>>::Output;
                #[inline]
                fn $method(self, other: &$t) -> <$t as $imp<$t>>::Output {
                    $imp::$method(self, *other)
                }
            }
            impl<M> $imp<&$t> for &$t
            where
                M: MIntBase,
            {
                type Output = <$t as $imp<$t>>::Output;
                #[inline]
                fn $method(self, other: &$t) -> <$t as $imp<$t>>::Output {
                    $imp::$method(*self, *other)
                }
            }
        };
    }
    impl_mint_ref_binop!(Add, add, MInt<M>);
    impl_mint_ref_binop!(Sub, sub, MInt<M>);
    impl_mint_ref_binop!(Mul, mul, MInt<M>);
    impl_mint_ref_binop!(Div, div, MInt<M>);
    macro_rules! impl_mint_ref_unop {
        ($ imp : ident , $ method : ident , $ t : ty) => {
            impl<M> $imp for &$t
            where
                M: MIntBase,
            {
                type Output = <$t as $imp>::Output;
                #[inline]
                fn $method(self) -> <$t as $imp>::Output {
                    $imp::$method(*self)
                }
            }
        };
    }
    impl_mint_ref_unop!(Neg, neg, MInt<M>);
    macro_rules! impl_mint_ref_op_assign {
        ($ imp : ident , $ method : ident , $ t : ty , $ fromimp : ident , $ frommethod : ident) => {
            impl<M> $imp<$t> for $t
            where
                M: MIntBase,
            {
                #[inline]
                fn $method(&mut self, rhs: $t) {
                    *self = $fromimp::$frommethod(*self, rhs);
                }
            }
            impl<M> $imp<&$t> for $t
            where
                M: MIntBase,
            {
                #[inline]
                fn $method(&mut self, other: &$t) {
                    $imp::$method(self, *other);
                }
            }
        };
    }
    impl_mint_ref_op_assign!(AddAssign, add_assign, MInt<M>, Add, add);
    impl_mint_ref_op_assign!(SubAssign, sub_assign, MInt<M>, Sub, sub);
    impl_mint_ref_op_assign!(MulAssign, mul_assign, MInt<M>, Mul, mul);
    impl_mint_ref_op_assign!(DivAssign, div_assign, MInt<M>, Div, div);
}
// codesnip-guard: zero_one
pub trait Zero: Sized {
    fn zero() -> Self;
    #[inline]
    fn is_zero(&self) -> bool
    where
        Self: PartialEq,
    {
        self == &Self::zero()
    }
    #[inline]
    fn set_zero(&mut self) {
        *self = Self::zero();
    }
}
pub trait One: Sized {
    fn one() -> Self;
    #[inline]
    fn is_one(&self) -> bool
    where
        Self: PartialEq,
    {
        self == &Self::one()
    }
    #[inline]
    fn set_one(&mut self) {
        *self = Self::one();
    }
}
macro_rules ! zero_one_impls { ($ ({ $ Trait : ident $ method : ident $ ($ t : ty) *, $ e : expr }) *) => { $ ($ (impl $ Trait for $ t { fn $ method () -> Self { $ e } }) *) * } ; }
zero_one_impls ! ({ Zero zero u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 , 0 } { Zero zero f32 f64 , 0. } { One one u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 , 1 } { One one f32 f64 , 1. });
// codesnip-guard: factorial
#[derive(Clone, Debug)]
pub struct MemorizedFactorial<M: MIntConvert<usize>> {
    pub fact: Vec<MInt<M>>,
    pub inv_fact: Vec<MInt<M>>,
}
impl<M: MIntConvert<usize>> MemorizedFactorial<M> {
    pub fn new(max_n: usize) -> Self {
        let mut fact = vec![MInt::one(); max_n + 1];
        let mut inv_fact = vec![MInt::one(); max_n + 1];
        for i in 2..=max_n {
            fact[i] = fact[i - 1] * MInt::from(i);
        }
        inv_fact[max_n] = fact[max_n].inv();
        for i in (3..=max_n).rev() {
            inv_fact[i - 1] = inv_fact[i] * MInt::from(i);
        }
        Self { fact, inv_fact }
    }
    #[inline]
    pub fn combination(&self, n: usize, r: usize) -> MInt<M> {
        debug_assert!(n < self.fact.len());
        if r <= n {
            self.fact[n] * self.inv_fact[r] * self.inv_fact[n - r]
        } else {
            MInt::zero()
        }
    }
    #[inline]
    pub fn permutation(&self, n: usize, r: usize) -> MInt<M> {
        debug_assert!(n < self.fact.len());
        if r <= n {
            self.fact[n] * self.inv_fact[n - r]
        } else {
            MInt::zero()
        }
    }
    #[inline]
    pub fn homogeneous_product(&self, n: usize, r: usize) -> MInt<M> {
        debug_assert!(n + r < self.fact.len() + 1);
        if n != 0 && r != 0 {
            self.combination(n + r - 1, r)
        } else {
            MInt::one()
        }
    }
    #[inline]
    pub fn inv(&self, n: usize) -> MInt<M> {
        debug_assert!(n < self.fact.len());
        debug_assert!(n > 0);
        self.inv_fact[n] * self.fact[n - 1]
    }
}


use std::io;

fn readstring() -> String {
    read_string_from_buffer(&io::stdin())
}

fn readint() -> i32 {
    read_int_from_buffer(&io::stdin())
}

fn read_string_from_buffer(buf: &io::Stdin) -> String {
    let mut input_text = String::new();
    buf.read_line(&mut input_text)
        .expect("failed to read from stdin");
    input_text.trim_right().to_string()
}

fn read_int_from_buffer(buf: &io::Stdin) -> i32 {
    read_string_from_buffer(buf)
        .parse::<i32>()
        .expect("couldn't parse data to an integer")
}

fn read_line_of_integers() -> Vec<i32> {
    readstring()
        .split_whitespace()
        .map(|x| x.parse::<i32>().unwrap())
        .collect()
}

fn read_line_of_longs() -> Vec<i64> {
    readstring()
        .split_whitespace()
        .map(|x| x.parse::<i64>().unwrap())
        .collect()
}

fn main() {
    let (x, y) = (readint(), readint());
    let z = (y - x).abs() / 2;
    let r = (y - x).abs() % 2;
    println!("{}", z * (z + 1) + r * (z + 1));
}


fn main() {
    let mut input = String::new();
    use std::io;
    use std::io::prelude::*;
    io::stdin().read_to_string(&mut input).unwrap();

    let mut it = input.split_whitespace();

    let a: i32 = it.next().unwrap().parse().unwrap();
    let b: i32 = it.next().unwrap().parse().unwrap();

    let d = (b - a).abs();

    let q = d / 2;
    let r = d % 2;

    let ans = q * (q + 1) + if r == 1 { q + 1 } else { 0 };

    println!("{}", ans);
}


#[allow(unused_imports)]
use std::cmp::{min,max};
//const INF: i32 = 0x3f3f3f3f;

struct Scanner {
    buffer: std::collections::VecDeque<String>
}

impl Scanner {
    fn new() -> Scanner {
        Scanner {
            buffer: std::collections::VecDeque::new()
        }
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        while self.buffer.is_empty() {
            let mut input = String::new();
            std::io::stdin().read_line(&mut input).ok();
            self.buffer = input.split_whitespace()
                .map(ToString::to_string).collect();
        }
        let front = self.buffer.pop_front().unwrap();
        front.parse::<T>().ok().unwrap()
    }
}

fn main1() {
    let mut scan = Scanner::new();
    let n = scan.next::<usize>();

    let mut lo = 99;
    let mut rep = 0;
    for _ in 0..n {
        let a = scan.next::<usize>();
        if lo > a {
            lo = a;
            rep = 0;
        }
        if lo == a {
            rep += 1;
        }
    }
    if rep <= n / 2 {
        println!("Alice");
    } else {
        println!("Bob");
    }
}

fn main() {
    std::thread::Builder::new().stack_size(50 << 20)
        .spawn(main1).unwrap().join().unwrap();
}


//spnauti-rusT {{{
use std::io::*; use std::str::{self,*}; use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::{self,*};
#[allow(unused_imports)] use std::iter::{self,*};
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_imports)] use std::cell::*;
#[allow(unused_macros)] macro_rules! min {
	($x:expr,$y:expr) => {{ let b=$y; let a=&mut$x; if b < *a {*a=b; true} else {false} }};
}
#[allow(unused_macros)] macro_rules! max {
	($x:expr,$y:expr) => {{ let b=$y; let a=&mut$x; if b > *a {*a=b; true} else {false} }};
}
#[allow(unused_macros)] macro_rules! l {
	($($v:ident),+ =$e:expr) => {$(let$v=$e;)+};
	($($v:ident),+:$t:ty=$e:expr) => {$(let$v:$t=$e;)+};
	(mut $($v:ident),+ =$e:expr) => {$(let mut$v=$e;)+};
	(mut $($v:ident),+:$t:ty=$e:expr) => {$(let mut$v:$t=$e;)+};
}
#[allow(unused_macros)] macro_rules! v {
	([$d:expr]$($s:tt)+) => {vec![v!($($s)+);$d]};
	([]) => {Vec::new()}; ([$e:expr]) => {Vec::with_capacity($e)}; (=$e:expr) => {$e};
}
#[allow(unused_macros)] macro_rules! rep { {[$c:expr]$($s:tt)+} => {for _ in 0..$c {$($s)+}} }
#[allow(dead_code)] fn reader() -> WordReaderC { WordReaderC::new() }
#[allow(dead_code)] fn writer() -> BufWriter<Stdout> { BufWriter::new(stdout()) }
struct WordReaderC {buf: Vec<u8>, pos: usize, q: std::io::StdinLock<'static>}//'
#[allow(dead_code)] impl WordReaderC {
	fn new() -> Self {
		let r = unsafe {&*Box::into_raw(Box::new(stdin()))};
		Self { q: r.lock(), buf: Vec::new(), pos: 0 }
	}
	fn next_line(&mut self) -> bool {
		self.buf.clear(); self.pos = 0;
		self.q.read_until(b'\n', &mut self.buf).unwrap_or(0) > 0
	}
	fn is_ws(c: u8) -> bool {
		c == b' ' || c == b'\r' || c == b'\n' || c == b'\t'
	}
	fn byte(&mut self) -> Option<u8> {
		if self.pos == self.buf.len() { if !self.next_line() { return None; } }
		self.pos += 1; Some(self.buf[self.pos - 1])
	}
	fn vb(&mut self) -> Vec<u8> {
		let mut s = Vec::with_capacity(8);
		let mut f = false;
		loop {
			if let Some(c) = self.byte() {
				if !Self::is_ws(c) {
					s.push(c);
					f = true;
				} else if f { break; }
			} else { break; }
		}
		s
	}
	fn s(&mut self) -> String { String::from_utf8(self.vb()).expect("invalid utf8") }
	fn i(&mut self) ->    i32 { self.p() }
	fn l(&mut self) ->    i64 { self.p() }
	fn u(&mut self) ->  usize { self.p() }
	fn f(&mut self) ->    f64 { self.p() }
	fn vi(&mut self, n: usize) -> Vec<i32> { self.vp(n) }
	fn vl(&mut self, n: usize) -> Vec<i64> { self.vp(n) }
	fn vu(&mut self, n: usize) -> Vec<usize> { self.vp(n) }
	fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> { self.ip(n).into_iter() }
	fn iu(&mut self, n: usize) -> impl Iterator<Item=usize> { self.ip(n).into_iter() }
	fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
		let w = self.vb(); str::from_utf8(w.as_ref()).unwrap().parse::<T>().unwrap()
	}
	fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
		(0..n).map(|_|self.p()).collect()
	}
	fn ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
		self.vp(n).into_iter()
	}
}
//------------------- End rusT }}}

fn main() {
	let mut rin = reader();
	let mut rout = writer();

	let n = rin.u();
	let mut a = rin.vi(n);
	a.sort();
	let mut c = 0;
	while c < n && a[0] == a[c] {
		c += 1;
	}
	if c <= n/2 {
		writeln!(rout, "Alice").ok();
	} else {
		writeln!(rout, "Bob").ok();
	}
}


//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 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")
    };
}

//

fn run() {
    input! {
        n: usize,
        a: [usize; n],
    }
    let mut a = a;
    a.sort();
    let ans = if a[0] == a[n / 2] {
        "Bob"
    } else {
        "Alice"
    };
    println!("{}", ans);
}

fn main() {
    run();
}


struct Scan {
    buffer: std::collections::VecDeque<String>,
}

impl Scan {
    fn new() -> Scan {
        Scan {
            buffer: std::collections::VecDeque::new(),
        }
    }

    fn next_line(&self) -> String {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).expect("Fail to read");
        line
    }

    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop_front() {
                break token.parse::<T>().ok().unwrap();
            }
            let line = self.next_line();
            self.buffer = line.split_whitespace().map(String::from).collect();
        }
    }
}

fn _main() {
    let mut scan = Scan::new();
    let mut good = true;
    for _ in 0..8 {
        let line: Vec<char> = scan.next::<String>().chars().collect();
        for j in 1..8 {
            good = good && line[j] != line[j - 1];
        }
    }
    println!("{}", if good { "YES" } else { "NO" });
}

fn main() {
    std::thread::Builder::new()
        .stack_size(1 << 23)
        .spawn(_main)
        .unwrap()
        .join()
        .unwrap();
}


use std::io::stdin;
fn main() {
    let mut arr = vec!();
    for _ in 0..8 {
        arr.push(parse())
    }
    for i in arr {
        if !is_alternate(i){
            println!("NO");
            return;
        }
    }
    println!("YES")
}
enum Chess{
    W,
    B
}

fn parse()->Vec<Chess>{
    let mut input = String::new();
    stdin().read_line(&mut input).unwrap();
    let mut vec = vec!();

    for c in input.trim().chars(){
        if 'W' ==c{
            vec.push(Chess::W)
        }else{
            vec.push(Chess::B)
        }
    }
    vec
}
fn is_alternate(arr:Vec<Chess>)->bool{
    for c in 0..arr.len()-1{
         match arr[c]{
            Chess::W => match arr[c+1]{
                Chess::W => return false,
                _=> continue
            },
            Chess::B=>match arr[c+1]{
                Chess::W=> continue,
                _=> return false
            }
        }
    }
    true
}


#![allow(unused_imports)]
use std::collections::{HashSet, HashMap};
use std::cmp::{min,max};
use std::io;
use std::str;

struct Scanner<R> {
    reader: R,
    buf_str: Vec<u8>,
    buf_iter: str::SplitWhitespace<'static>,
}
impl<R: io::BufRead> Scanner<R> {
    fn new(reader: R) -> Self {
        Self { reader, buf_str: vec![], buf_iter: "".split_whitespace() }
    }
    fn token<T: str::FromStr>(&mut self) -> T {
        loop {
            // If we have another token in this line
            if let Some(token) = self.buf_iter.next() {
                return token.parse().ok().expect("Failed parse"); // calls parse::<T>() on the current token and returns it.
            }

            // If we do not have another token in the line then
            // we should go to the next line.
            self.buf_str.clear(); // empty out the buffer that holds the current line
            self.reader.read_until(b'\n', &mut self.buf_str).expect("Failed read"); // read a new line into the buffer

            // create an iterator over the white space delimited strings of the current line
            self.buf_iter = unsafe {
                let slice = str::from_utf8_unchecked(&self.buf_str); // makes a string from utf8 characters in the current line
                std::mem::transmute(slice.split_whitespace()) // transmutes the memory in place
            }
        }
    }
}

fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
    let mut ans = "YES";
    for _ in 0..8 {
        let row = scan.token::<String>();
        if !alternates(row) {
            ans = "NO";
        }
    }
    writeln!(out, "{}", ans);
}

fn alternates(s: String) -> bool {
    s.chars().collect::<Vec<char>>().windows(2).all(|win| win[0] != win[1])
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());
    solve(&mut scan, &mut out);
}


use std::io;
use std::str;

pub struct Scanner<R> {
    reader: R,
    buffer: Vec<String>,
}

impl<R: io::BufRead> Scanner<R> {
    pub fn new(reader: R) -> Self {
        Self {
            reader,
            buffer: vec![],
        }
    }

    pub fn token<T: str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            self.reader.read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
    let x1: i32 = scan.token();
    let y1: i32 = scan.token();
    let x2: i32 = scan.token();
    let y2: i32 = scan.token();
    let x: i32 = scan.token();
    let y: i32 = scan.token();
    let dx = (x2 - x1).abs();
    let dy = (y2 - y1).abs();
    if dx % (2 * x) == 0 && dy % (2 * y) == 0 {
        writeln!(out, "YES").ok();
    } else if dx % (2 * x) == x && dy % (2 * y) == y {
        writeln!(out, "YES").ok();
    } else {
        writeln!(out, "NO").ok();
    }
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());
    solve(&mut scan, &mut out);
}


#![allow(unused_imports)]
use std::io;
use std::cmp::*;
use std::collections::*;
#[allow(dead_code)]
const M: i64 = 1e9 as i64 + 7;

fn read_line() -> String {
    let stdin = io::stdin();
    let mut buf = String::new();
    stdin.read_line(&mut buf).unwrap();
    buf
}
#[allow(dead_code)]
fn read<T>() -> T where T: std::str::FromStr, T::Err : std::fmt::Debug {
    read_line().trim().parse().unwrap()
}
#[allow(dead_code)]
fn readv<T>() -> Vec<T> where T: std::str::FromStr, T::Err : std::fmt::Debug {
    read_line().split(' ').map(|a| a.trim().parse().unwrap()).collect()
}

fn main() {
    let input = readv::<i32>();
    let (x1, y1, x2, y2) = (input[0], input[1], input[2], input[3]);
    let input = readv::<i32>();
    let (x, y) = (input[0], input[1]);
    let xx = i32::abs(x2 - x1);
    let yy = i32::abs(y2 - y1);
    if xx % x != 0 || yy % y != 0 {
        println!("NO");
        return;
    }
    println!("{}", if xx / x % 2 == yy / y % 2 { "YES" } else { "NO "});
}


use std::io;

fn read_line() -> String {
    let mut line = String::new();
    io::stdin().read_line(&mut line).unwrap();
    return line.trim().to_string();
}

fn read_ints() -> Vec<i32> {
    let line = read_line();
    return line.split(" ")
        .filter(|&s| s.len() > 0)
        .map(|s| {
            s.parse::<i32>().unwrap()
        }).collect();
}

fn main() {
    let params = read_ints();
    let x1 = params[0];
    let y1 = params[1];
    let x2 = params[2];
    let y2 = params[3];
    let params = read_ints();
    let a = params[0];
    let b = params[1];
    let dx = x2 - x1;
    let dy = y2 - y1;
    if dx % a != 0 || dy % b != 0 {
        println!("NO");
        return;
    }
    let sx = dx / a;
    let sy = dy / b;
    println!("{}", if (sx - sy) %2 == 0 {"YES"} else {"NO"});
}


// codesnip-guard: main
fn main() {
    #![allow(unused_imports, unused_macros)]
    prepare_io!(_in_buf, scanner, _out);
    macro_rules ! print { ($ ($ arg : tt) *) => (:: std :: write ! (_out , $ ($ arg) *) . expect ("io error")) }
    macro_rules ! println { ($ ($ arg : tt) *) => (:: std :: writeln ! (_out , $ ($ arg) *) . expect ("io error")) }
    scan!(scanner, n, m, s: [{CharsWithBase('a')}; n]);
    let mut t = Trie::new(26);
    let mut deq = std::collections::VecDeque::new();
    deq.push_back((0, 0));
    let mut idx = Indexing::new();
    idx.get((0, 0));
    for s in s.iter() {
        t.insert(s.iter().cloned());
    }
    let mut mp = std::collections::HashMap::<_, M>::new();
    while let Some((u, v)) = deq.pop_front() {
        let i = idx.get((u, v));
        for ch in 0..26 {
            if let (Some(nu), Some(nv)) = (t.next_node(u, ch), t.next_node(v, ch)) {
                let x = minmax!(nu, nv);
                if !idx.contains(&x) {
                    deq.push_back(x);
                }
                *mp.entry((i, idx.get(x))).or_default() += M::one();
                if t.count(nv) > 0 {
                    let x = minmax!(nu, 0);
                    if !idx.contains(&x) {
                        deq.push_back(x);
                    }
                    *mp.entry((i, idx.get(x))).or_default() += M::one();
                }
                if t.count(nu) > 0 {
                    let x = minmax!(0, nv);
                    if !idx.contains(&x) {
                        deq.push_back(x);
                    }
                    *mp.entry((i, idx.get(x))).or_default() += M::one();
                }
                if t.count(nu) > 0 && t.count(nv) > 0 {
                    *mp.entry((i, 0)).or_default() += M::one();
                }
            }
        }
    }
    let k = idx.len();
    let mut mat = vec![vec![M::zero(); k]; k];
    for ((i, j), v) in mp {
        mat[i][j] += v;
    }
    let ans = Matrix::from_vec(mat).pow(m)[0][0];
    println!("{}", ans);
}
#[derive(Debug, Clone)]
pub struct Indexing<T: Eq + std::hash::Hash> {
    map: std::collections::HashMap<T, usize>,
}
impl<T: Eq + std::hash::Hash> Indexing<T> {
    pub fn new() -> Self {
        Self {
            map: Default::default(),
        }
    }
    pub fn len(&self) -> usize {
        self.map.len()
    }
    pub fn contains(&self, key: &T) -> bool {
        self.map.contains_key(key)
    }
    pub fn get(&mut self, key: T) -> usize {
        if let Some(index) = self.map.get(&key) {
            *index
        } else {
            let index = self.map.len();
            self.map.insert(key, index);
            index
        }
    }
}
pub type M = montgomery::MInt998244353;
#[macro_export]
macro_rules! prepare_io {
    ($ in_buf : ident , $ scanner : ident , $ out : ident) => {
        use std::io::{stdout, BufWriter, Write as _};
        let $in_buf = read_stdin_all_unchecked();
        let mut $scanner = Scanner::new(&$in_buf);
        let $out = stdout();
        let mut $out = BufWriter::new($out.lock());
    };
}
// codesnip-guard: _echo
pub fn echo<T: std::fmt::Display>(
    mut writer: impl std::io::Write,
    iter: impl IntoIterator<Item = T>,
    sep: impl std::fmt::Display,
) -> std::io::Result<()> {
    let mut iter = iter.into_iter();
    if let Some(item) = iter.next() {
        write!(writer, "{}", item)?;
    }
    for item in iter {
        write!(writer, "{}{}", sep, item)?;
    }
    writeln!(writer)
}
// codesnip-guard: scanner
pub fn read_stdin_all_unchecked() -> String {
    use std::io::Read as _;
    let mut buf = Vec::new();
    std::io::stdin().read_to_end(&mut buf).expect("io error");
    unsafe { String::from_utf8_unchecked(buf) }
}
pub fn read_stdin_line() -> String {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).expect("io error");
    s
}
pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Clone, Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
mod scanner_impls {
    use super::*;
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn new(s: &'a str) -> Self {
            let iter = s.split_ascii_whitespace();
            Self { iter }
        }
        #[inline]
        pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
            <T as IterScan>::scan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
            marker.mscan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
            (0..size)
                .map(|_| <T as IterScan>::scan(&mut self.iter).expect("scan error"))
                .collect()
        }
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
    macro_rules ! iter_scan_impls { ($ ($ t : ty) *) => { $ (impl IterScan for $ t { type Output = Self ; # [inline] fn scan <'a , I : Iterator < Item = &'a str >> (iter : & mut I) -> Option < Self > { iter . next () ?. parse ::<$ t > () . ok () } }) * } ; }
    iter_scan_impls ! (char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String);
    macro_rules ! iter_scan_tuple_impl { ($ ($ T : ident) *) => { impl <$ ($ T : IterScan) ,*> IterScan for ($ ($ T ,) *) { type Output = ($ (<$ T as IterScan >:: Output ,) *) ; # [inline] fn scan <'a , It : Iterator < Item = &'a str >> (_iter : & mut It) -> Option < Self :: Output > { Some (($ (<$ T as IterScan >:: scan (_iter) ?,) *)) } } } ; }
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl ! (A B);
    iter_scan_tuple_impl ! (A B C);
    iter_scan_tuple_impl ! (A B C D);
    iter_scan_tuple_impl ! (A B C D E);
    iter_scan_tuple_impl ! (A B C D E F);
    iter_scan_tuple_impl ! (A B C D E F G);
    iter_scan_tuple_impl ! (A B C D E F G H);
    iter_scan_tuple_impl ! (A B C D E F G H I);
    iter_scan_tuple_impl ! (A B C D E F G H I J);
    iter_scan_tuple_impl ! (A B C D E F G H I J K);
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            <T as IterScan>::scan(&mut self.inner.iter)
        }
    }
}
#[derive(Debug, Copy, Clone)]
pub struct Usize1;
#[derive(Debug, Copy, Clone)]
pub struct CharWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Chars;
#[derive(Debug, Copy, Clone)]
pub struct CharsWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Collect<T: IterScan, B: std::iter::FromIterator<<T as IterScan>::Output>> {
    size: usize,
    _marker: std::marker::PhantomData<fn() -> (T, B)>,
}
mod marker_impls {
    use super::*;
    use std::{iter::FromIterator, marker::PhantomData};
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            <usize as IterScan>::scan(iter)?.checked_sub(1)
        }
    }
    impl MarkedIterScan for CharWithBase {
        type Output = usize;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some((<char as IterScan>::scan(iter)? as u8 - self.0 as u8) as usize)
        }
    }
    impl IterScan for Chars {
        type Output = Vec<char>;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(iter.next()?.chars().collect())
        }
    }
    impl MarkedIterScan for CharsWithBase {
        type Output = Vec<usize>;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                iter.next()?
                    .chars()
                    .map(|c| (c as u8 - self.0 as u8) as usize)
                    .collect(),
            )
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> Collect<T, B> {
        pub fn new(size: usize) -> Self {
            Self {
                size,
                _marker: PhantomData,
            }
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> MarkedIterScan for Collect<T, B> {
        type Output = B;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                (0..self.size)
                    .map(|_| <T as IterScan>::scan(iter).expect("scan error"))
                    .collect::<B>(),
            )
        }
    }
}
#[macro_export]
macro_rules ! scan_value { ($ scanner : expr , ($ ($ t : tt) ,*)) => { ($ ($ crate :: scan_value ! ($ scanner , $ t)) ,*) } ; ($ scanner : expr , [$ t : tt ; $ len : expr]) => { (0 ..$ len) . map (| _ | $ crate :: scan_value ! ($ scanner , $ t)) . collect ::< Vec < _ >> () } ; ($ scanner : expr , [$ t : ty ; $ len : expr]) => { $ scanner . scan_vec ::<$ t > ($ len) } ; ($ scanner : expr , [$ t : ty]) => { $ scanner . iter ::<$ t > () } ; ($ scanner : expr , { $ e : expr }) => { $ scanner . mscan ($ e) } ; ($ scanner : expr , $ t : ty) => { $ scanner . scan ::<$ t > () } ; }
#[macro_export]
macro_rules ! scan { ($ scanner : expr) => { } ; ($ scanner : expr ,) => { } ; ($ scanner : expr , mut $ var : tt : $ t : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , $ var : tt : $ t : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , mut $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , mut $ var : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , $ var : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , mut $ var : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; }
// codesnip-guard: Trie
pub struct Trie {
    child: Vec<Vec<usize>>,
    accept: Vec<usize>,
    char_size: usize,
}
impl Trie {
    pub fn new(char_size: usize) -> Self {
        Self {
            child: vec![vec![0; char_size]],
            accept: vec![0],
            char_size,
        }
    }
    pub fn insert_at(
        &mut self,
        mut node: usize,
        iter: impl IntoIterator<Item = usize>,
    ) -> Vec<usize> {
        let mut path = Vec::new();
        for ch in iter.into_iter() {
            path.push(node);
            if self.child[node][ch] == 0 {
                self.child[node][ch] = self.child.len();
                self.child.push(vec![0; self.char_size]);
                self.accept.push(0);
            }
            node = self.child[node][ch];
        }
        path.push(node);
        self.accept[node] += 1;
        path
    }
    pub fn insert(&mut self, iter: impl IntoIterator<Item = usize>) -> Vec<usize> {
        self.insert_at(0, iter)
    }
    pub fn find_at(
        &self,
        mut node: usize,
        iter: impl IntoIterator<Item = usize>,
    ) -> Result<usize, usize> {
        for ch in iter.into_iter() {
            if let Some(v) = self.child.get(node) {
                node = v[ch];
            } else {
                return Err(node);
            }
        }
        Ok(node)
    }
    pub fn find(&self, iter: impl IntoIterator<Item = usize>) -> Result<usize, usize> {
        self.find_at(0, iter)
    }
    pub fn next_node(&self, node: usize, ch: usize) -> Option<usize> {
        if self.child[node][ch] == 0 {
            None
        } else {
            Some(self.child[node][ch])
        }
    }
    pub fn count(&self, node: usize) -> usize {
        self.accept[node]
    }
    pub fn next_count(&self, node: usize, ch: usize) -> usize {
        if let Some(node) = self.next_node(node, ch) {
            self.count(node)
        } else {
            0
        }
    }
}
// codesnip-guard: ord_tools
pub trait PartialOrdExt: Sized {
    fn chmin(&mut self, other: Self);
    fn chmax(&mut self, other: Self);
    fn minmax(self, other: Self) -> (Self, Self);
}
impl<T> PartialOrdExt for T
where
    T: PartialOrd,
{
    #[inline]
    fn chmin(&mut self, other: Self) {
        if *self > other {
            *self = other;
        }
    }
    #[inline]
    fn chmax(&mut self, other: Self) {
        if *self < other {
            *self = other;
        }
    }
    #[inline]
    fn minmax(self, other: Self) -> (Self, Self) {
        if self < other {
            (self, other)
        } else {
            (other, self)
        }
    }
}
#[macro_export]
macro_rules ! min { ($ l : expr) => { $ l } ; ($ l : expr ,) => { $ crate :: min ! ($ l) } ; ($ l : expr , $ r : expr) => { ($ l) . min ($ r) } ; ($ l : expr , $ r : expr ,) => { $ crate :: min ! ($ l , $ r) } ; ($ l : expr , $ r : expr , $ ($ t : tt) *) => { $ crate :: min ! ($ crate :: min ! ($ l , $ r) , $ ($ t) *) } ; }
#[macro_export]
macro_rules ! chmin { ($ l : expr) => { } ; ($ l : expr ,) => { } ; ($ l : expr , $ r : expr) => { { let r = $ r ; if $ l > r { $ l = r ; } } } ; ($ l : expr , $ r : expr ,) => { $ crate :: chmin ! ($ l , $ r) } ; ($ l : expr , $ r : expr , $ ($ t : tt) *) => { $ crate :: chmin ! ($ l , $ r) ; $ crate :: chmin ! ($ l , $ ($ t) *) } ; }
#[macro_export]
macro_rules ! max { ($ l : expr) => { $ l } ; ($ l : expr ,) => { $ crate :: max ! ($ l) } ; ($ l : expr , $ r : expr) => { ($ l) . max ($ r) } ; ($ l : expr , $ r : expr ,) => { $ crate :: max ! ($ l , $ r) } ; ($ l : expr , $ r : expr , $ ($ t : tt) *) => { $ crate :: max ! ($ crate :: max ! ($ l , $ r) , $ ($ t) *) } ; }
#[macro_export]
macro_rules ! chmax { ($ l : expr) => { } ; ($ l : expr ,) => { } ; ($ l : expr , $ r : expr) => { { let r = $ r ; if $ l < r { $ l = r ; } } } ; ($ l : expr , $ r : expr ,) => { $ crate :: chmax ! ($ l , $ r) } ; ($ l : expr , $ r : expr , $ ($ t : tt) *) => { $ crate :: chmax ! ($ l , $ r) ; $ crate :: chmax ! ($ l , $ ($ t) *) } ; }
#[macro_export]
macro_rules ! minmax { ($ ($ t : tt) *) => { ($ crate :: min ! ($ ($ t) *) , $ crate :: max ! ($ ($ t) *)) } ; }
// codesnip-guard: montgomery
pub mod montgomery {
    use super::*;
    pub struct Modulo998244353;
    pub type MInt998244353 = MInt<Modulo998244353>;
    impl<M> MIntBase for M
    where
        M: MontgomeryReduction32,
    {
        type Inner = u32;
        #[inline]
        fn get_mod() -> Self::Inner {
            <Self as MontgomeryReduction32>::get_mod()
        }
        #[inline]
        fn mod_zero() -> Self::Inner {
            0
        }
        #[inline]
        fn mod_one() -> Self::Inner {
            Self::n1()
        }
        #[inline]
        fn mod_add(x: Self::Inner, y: Self::Inner) -> Self::Inner {
            let z = x + y;
            let m = Self::get_mod();
            if z >= m {
                z - m
            } else {
                z
            }
        }
        #[inline]
        fn mod_sub(x: Self::Inner, y: Self::Inner) -> Self::Inner {
            if x < y {
                x + Self::get_mod() - y
            } else {
                x - y
            }
        }
        #[inline]
        fn mod_mul(x: Self::Inner, y: Self::Inner) -> Self::Inner {
            Self::reduce(x as u64 * y as u64)
        }
        #[inline]
        fn mod_div(x: Self::Inner, y: Self::Inner) -> Self::Inner {
            Self::mod_mul(x, Self::mod_inv(y))
        }
        #[inline]
        fn mod_neg(x: Self::Inner) -> Self::Inner {
            if x == 0 {
                0
            } else {
                Self::get_mod() - x
            }
        }
        fn mod_inv(x: Self::Inner) -> Self::Inner {
            let mut a = x;
            let m = Self::get_mod();
            let (mut b, mut u, mut s) = (m, 1, 0);
            let k = a.trailing_zeros();
            a >>= k;
            for _ in 0..k {
                if u & 1 == 1 {
                    u += m;
                }
                u /= 2;
            }
            while a != b {
                if b < a {
                    std::mem::swap(&mut a, &mut b);
                    std::mem::swap(&mut u, &mut s);
                }
                b -= a;
                if s < u {
                    s += m;
                }
                s -= u;
                let k = b.trailing_zeros();
                b >>= k;
                for _ in 0..k {
                    if s & 1 == 1 {
                        s += m;
                    }
                    s /= 2;
                }
            }
            Self::reduce(s as u64 * Self::n3() as u64)
        }
    }
    impl<M> MIntConvert<u32> for M
    where
        M: MontgomeryReduction32,
    {
        #[inline]
        fn from(x: u32) -> Self::Inner {
            Self::reduce(x as u64 * Self::n2() as u64)
        }
        #[inline]
        fn into(x: Self::Inner) -> u32 {
            Self::reduce(x as u64) as u32
        }
        #[inline]
        fn mod_into() -> u32 {
            <Self as MIntBase>::get_mod() as u32
        }
    }
    impl<M> MIntConvert<u64> for M
    where
        M: MontgomeryReduction32,
    {
        #[inline]
        fn from(x: u64) -> Self::Inner {
            Self::reduce(x % Self::get_mod() as u64 * Self::n2() as u64)
        }
        #[inline]
        fn into(x: Self::Inner) -> u64 {
            Self::reduce(x as u64) as u64
        }
        #[inline]
        fn mod_into() -> u64 {
            <Self as MIntBase>::get_mod() as u64
        }
    }
    impl<M> MIntConvert<usize> for M
    where
        M: MontgomeryReduction32,
    {
        #[inline]
        fn from(x: usize) -> Self::Inner {
            Self::reduce(x as u64 % Self::get_mod() as u64 * Self::n2() as u64)
        }
        #[inline]
        fn into(x: Self::Inner) -> usize {
            Self::reduce(x as u64) as usize
        }
        #[inline]
        fn mod_into() -> usize {
            <Self as MIntBase>::get_mod() as usize
        }
    }
    impl MIntConvert<i32> for Modulo998244353 {
        #[inline]
        fn from(x: i32) -> Self::Inner {
            let x = x % <Self as MIntBase>::get_mod() as i32;
            let x = if x < 0 {
                (x + <Self as MIntBase>::get_mod() as i32) as u64
            } else {
                x as u64
            };
            Self::reduce(x as u64 * Self::n2() as u64)
        }
        #[inline]
        fn into(x: Self::Inner) -> i32 {
            Self::reduce(x as u64) as i32
        }
        #[inline]
        fn mod_into() -> i32 {
            <Self as MIntBase>::get_mod() as i32
        }
    }
    impl MIntConvert<i64> for Modulo998244353 {
        #[inline]
        fn from(x: i64) -> Self::Inner {
            let x = x % <Self as MIntBase>::get_mod() as i64;
            let x = if x < 0 {
                (x + <Self as MIntBase>::get_mod() as i64) as u64
            } else {
                x as u64
            };
            Self::reduce(x as u64 * Self::n2() as u64)
        }
        #[inline]
        fn into(x: Self::Inner) -> i64 {
            Self::reduce(x as u64) as i64
        }
        #[inline]
        fn mod_into() -> i64 {
            <Self as MIntBase>::get_mod() as i64
        }
    }
    impl MIntConvert<isize> for Modulo998244353 {
        #[inline]
        fn from(x: isize) -> Self::Inner {
            let x = x % <Self as MIntBase>::get_mod() as isize;
            let x = if x < 0 {
                (x + <Self as MIntBase>::get_mod() as isize) as u64
            } else {
                x as u64
            };
            Self::reduce(x as u64 * Self::n2() as u64)
        }
        #[inline]
        fn into(x: Self::Inner) -> isize {
            Self::reduce(x as u64) as isize
        }
        #[inline]
        fn mod_into() -> isize {
            <Self as MIntBase>::get_mod() as isize
        }
    }
    /// m is prime, n = 2^32
    pub trait MontgomeryReduction32 {
        /// m
        fn get_mod() -> u32;
        /// (-m)^{-1} mod n
        fn r() -> u32 {
            let m = Self::get_mod();
            let mut r = 0;
            let mut t = 0;
            for i in 0..32 {
                if t % 2 == 0 {
                    t += m;
                    r += 1 << i;
                }
                t /= 2;
            }
            r
        }
        /// n^1 mod m
        fn n1() -> u32;
        /// n^2 mod m
        fn n2() -> u32;
        /// n^3 mod m
        fn n3() -> u32;
        /// n^{-1}x = (x + (xr mod n)m) / n
        fn reduce(x: u64) -> u32 {
            let m: u32 = Self::get_mod();
            let r = Self::r();
            let mut x = ((x + r.wrapping_mul(x as u32) as u64 * m as u64) >> 32) as u32;
            if x >= m {
                x -= m;
            }
            x
        }
    }
    macro_rules! impl_montgomery_reduction_32 {
        ($ name : ident , $ m : expr , $ r : expr , $ n1 : expr , $ n2 : expr , $ n3 : expr) => {
            impl MontgomeryReduction32 for $name {
                #[inline]
                fn get_mod() -> u32 {
                    $m
                }
                #[inline]
                fn r() -> u32 {
                    $r
                }
                #[inline]
                fn n1() -> u32 {
                    $n1
                }
                #[inline]
                fn n2() -> u32 {
                    $n2
                }
                #[inline]
                fn n3() -> u32 {
                    $n3
                }
            }
        };
    }
    impl_montgomery_reduction_32!(
        Modulo998244353,
        998_244_353,
        998_244_351,
        301_989_884,
        932_051_910,
        679_058_953
    );
}
// codesnip-guard: MIntBase
#[repr(transparent)]
pub struct MInt<M>
where
    M: MIntBase,
{
    x: M::Inner,
    _marker: std::marker::PhantomData<fn() -> M>,
}
pub trait MIntBase {
    type Inner: Sized + Copy + Eq + std::fmt::Debug + std::hash::Hash;
    fn get_mod() -> Self::Inner;
    fn mod_zero() -> Self::Inner;
    fn mod_one() -> Self::Inner;
    fn mod_add(x: Self::Inner, y: Self::Inner) -> Self::Inner;
    fn mod_sub(x: Self::Inner, y: Self::Inner) -> Self::Inner;
    fn mod_mul(x: Self::Inner, y: Self::Inner) -> Self::Inner;
    fn mod_div(x: Self::Inner, y: Self::Inner) -> Self::Inner;
    fn mod_neg(x: Self::Inner) -> Self::Inner;
    fn mod_inv(x: Self::Inner) -> Self::Inner;
    fn mod_pow(x: Self::Inner, y: usize) -> Self::Inner {
        let (mut x, mut y, mut z) = (x, y, Self::mod_one());
        while y > 0 {
            if y & 1 == 1 {
                z = Self::mod_mul(z, x);
            }
            x = Self::mod_mul(x, x);
            y >>= 1;
        }
        z
    }
}
pub trait MIntConvert<T = <Self as MIntBase>::Inner>: MIntBase {
    fn from(x: T) -> <Self as MIntBase>::Inner;
    fn into(x: <Self as MIntBase>::Inner) -> T;
    fn mod_into() -> T;
}
mod mint_base {
    use super::*;
    use std::{
        fmt::{self, Debug, Display},
        hash::{Hash, Hasher},
        iter::{Product, Sum},
        marker::PhantomData,
        ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
        str::FromStr,
    };
    impl<M> MInt<M>
    where
        M: MIntConvert,
    {
        #[inline]
        pub fn new(x: M::Inner) -> Self {
            Self::new_unchecked(<M as MIntConvert<M::Inner>>::from(x))
        }
        #[inline]
        pub fn inner(self) -> M::Inner {
            <M as MIntConvert<M::Inner>>::into(self.x)
        }
    }
    impl<M> MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        pub fn new_unchecked(x: M::Inner) -> Self {
            Self {
                x,
                _marker: PhantomData,
            }
        }
        #[inline]
        pub fn get_mod() -> M::Inner {
            M::get_mod()
        }
        #[inline]
        pub fn pow(self, y: usize) -> Self {
            Self::new_unchecked(M::mod_pow(self.x, y))
        }
        #[inline]
        pub fn inv(self) -> Self {
            Self::new_unchecked(M::mod_inv(self.x))
        }
    }
    impl<M> Clone for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn clone(&self) -> Self {
            Self {
                x: Clone::clone(&self.x),
                _marker: PhantomData,
            }
        }
    }
    impl<M> Copy for MInt<M> where M: MIntBase {}
    impl<M> Debug for MInt<M>
    where
        M: MIntBase,
    {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            Debug::fmt(&self.x, f)
        }
    }
    impl<M> Default for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn default() -> Self {
            <Self as Zero>::zero()
        }
    }
    impl<M> PartialEq for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn eq(&self, other: &Self) -> bool {
            PartialEq::eq(&self.x, &other.x)
        }
    }
    impl<M> Eq for MInt<M> where M: MIntBase {}
    impl<M> Hash for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn hash<H: Hasher>(&self, state: &mut H) {
            Hash::hash(&self.x, state)
        }
    }
    macro_rules ! impl_mint_from { ($ ($ t : ty) ,*) => { $ (impl < M > From <$ t > for MInt < M > where M : MIntConvert <$ t >, { # [inline] fn from (x : $ t) -> Self { Self :: new_unchecked (< M as MIntConvert <$ t >>:: from (x)) } } impl < M > From < MInt < M >> for $ t where M : MIntConvert <$ t >, { # [inline] fn from (x : MInt < M >) -> $ t { < M as MIntConvert <$ t >>:: into (x . x) } }) * } ; }
    impl_mint_from!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
    impl<M> Zero for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn zero() -> Self {
            Self::new_unchecked(M::mod_zero())
        }
    }
    impl<M> One for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn one() -> Self {
            Self::new_unchecked(M::mod_one())
        }
    }
    impl<M> Add for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn add(self, rhs: Self) -> Self::Output {
            Self::new_unchecked(M::mod_add(self.x, rhs.x))
        }
    }
    impl<M> Sub for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn sub(self, rhs: Self) -> Self::Output {
            Self::new_unchecked(M::mod_sub(self.x, rhs.x))
        }
    }
    impl<M> Mul for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn mul(self, rhs: Self) -> Self::Output {
            Self::new_unchecked(M::mod_mul(self.x, rhs.x))
        }
    }
    impl<M> Div for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn div(self, rhs: Self) -> Self::Output {
            Self::new_unchecked(M::mod_div(self.x, rhs.x))
        }
    }
    impl<M> Neg for MInt<M>
    where
        M: MIntBase,
    {
        type Output = Self;
        #[inline]
        fn neg(self) -> Self::Output {
            Self::new_unchecked(M::mod_neg(self.x))
        }
    }
    impl<M> Sum for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(<Self as Zero>::zero(), Add::add)
        }
    }
    impl<M> Product for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(<Self as One>::one(), Mul::mul)
        }
    }
    impl<'a, M: 'a> Sum<&'a MInt<M>> for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
            iter.fold(<Self as Zero>::zero(), Add::add)
        }
    }
    impl<'a, M: 'a> Product<&'a MInt<M>> for MInt<M>
    where
        M: MIntBase,
    {
        #[inline]
        fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
            iter.fold(<Self as One>::one(), Mul::mul)
        }
    }
    impl<M> Display for MInt<M>
    where
        M: MIntConvert,
        M::Inner: Display,
    {
        fn fmt<'a>(&self, f: &mut fmt::Formatter<'a>) -> Result<(), fmt::Error> {
            write!(f, "{}", self.inner())
        }
    }
    impl<M> FromStr for MInt<M>
    where
        M: MIntConvert,
        M::Inner: FromStr,
    {
        type Err = <M::Inner as FromStr>::Err;
        #[inline]
        fn from_str(s: &str) -> Result<Self, Self::Err> {
            s.parse::<M::Inner>().map(Self::new)
        }
    }
    impl<M> IterScan for MInt<M>
    where
        M: MIntConvert,
        M::Inner: FromStr,
    {
        type Output = Self;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            iter.next()?.parse::<MInt<M>>().ok()
        }
    }
    macro_rules! impl_mint_ref_binop {
        ($ imp : ident , $ method : ident , $ t : ty) => {
            impl<M> $imp<$t> for &$t
            where
                M: MIntBase,
            {
                type Output = <$t as $imp<$t>>::Output;
                #[inline]
                fn $method(self, other: $t) -> <$t as $imp<$t>>::Output {
                    $imp::$method(*self, other)
                }
            }
            impl<M> $imp<&$t> for $t
            where
                M: MIntBase,
            {
                type Output = <$t as $imp<$t>>::Output;
                #[inline]
                fn $method(self, other: &$t) -> <$t as $imp<$t>>::Output {
                    $imp::$method(self, *other)
                }
            }
            impl<M> $imp<&$t> for &$t
            where
                M: MIntBase,
            {
                type Output = <$t as $imp<$t>>::Output;
                #[inline]
                fn $method(self, other: &$t) -> <$t as $imp<$t>>::Output {
                    $imp::$method(*self, *other)
                }
            }
        };
    }
    impl_mint_ref_binop!(Add, add, MInt<M>);
    impl_mint_ref_binop!(Sub, sub, MInt<M>);
    impl_mint_ref_binop!(Mul, mul, MInt<M>);
    impl_mint_ref_binop!(Div, div, MInt<M>);
    macro_rules! impl_mint_ref_unop {
        ($ imp : ident , $ method : ident , $ t : ty) => {
            impl<M> $imp for &$t
            where
                M: MIntBase,
            {
                type Output = <$t as $imp>::Output;
                #[inline]
                fn $method(self) -> <$t as $imp>::Output {
                    $imp::$method(*self)
                }
            }
        };
    }
    impl_mint_ref_unop!(Neg, neg, MInt<M>);
    macro_rules! impl_mint_ref_op_assign {
        ($ imp : ident , $ method : ident , $ t : ty , $ fromimp : ident , $ frommethod : ident) => {
            impl<M> $imp<$t> for $t
            where
                M: MIntBase,
            {
                #[inline]
                fn $method(&mut self, rhs: $t) {
                    *self = $fromimp::$frommethod(*self, rhs);
                }
            }
            impl<M> $imp<&$t> for $t
            where
                M: MIntBase,
            {
                #[inline]
                fn $method(&mut self, other: &$t) {
                    $imp::$method(self, *other);
                }
            }
        };
    }
    impl_mint_ref_op_assign!(AddAssign, add_assign, MInt<M>, Add, add);
    impl_mint_ref_op_assign!(SubAssign, sub_assign, MInt<M>, Sub, sub);
    impl_mint_ref_op_assign!(MulAssign, mul_assign, MInt<M>, Mul, mul);
    impl_mint_ref_op_assign!(DivAssign, div_assign, MInt<M>, Div, div);
}
// codesnip-guard: zero_one
pub trait Zero: PartialEq + Sized {
    fn zero() -> Self;
    #[inline]
    fn is_zero(&self) -> bool {
        self == &Self::zero()
    }
}
pub trait One: PartialEq + Sized {
    fn one() -> Self;
    #[inline]
    fn is_one(&self) -> bool {
        self == &Self::one()
    }
}
macro_rules ! zero_one_impls { ($ ({ $ Trait : ident $ method : ident $ ($ t : ty) *, $ e : expr }) *) => { $ ($ (impl $ Trait for $ t { # [inline] fn $ method () -> Self { $ e } }) *) * } ; }
zero_one_impls ! ({ Zero zero u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 , 0 } { Zero zero f32 f64 , 0. } { One one u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 , 1 } { One one f32 f64 , 1. });
// codesnip-guard: Matrix
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Matrix<T> {
    pub shape: (usize, usize),
    pub data: Vec<Vec<T>>,
}
mod matrix_impls {
    use super::*;
    use std::ops::{Add, Div, Index, IndexMut, Mul, Sub};
    impl<T: Clone> Matrix<T> {
        pub fn new(shape: (usize, usize), z: T) -> Self {
            Self {
                shape,
                data: vec![vec![z; shape.1]; shape.0],
            }
        }
    }
    impl<T> Matrix<T> {
        pub fn from_vec(data: Vec<Vec<T>>) -> Self {
            Self {
                shape: (data.len(), data.first().map(Vec::len).unwrap_or_default()),
                data,
            }
        }
    }
    impl<T: Clone + Zero> Matrix<T> {
        pub fn zeros(shape: (usize, usize)) -> Self {
            Self {
                shape,
                data: vec![vec![Zero::zero(); shape.1]; shape.0],
            }
        }
    }
    impl<T: Clone + Zero + One> Matrix<T> {
        pub fn eye(shape: (usize, usize)) -> Self {
            let mut data = vec![vec![Zero::zero(); shape.1]; shape.0];
            for (i, d) in data.iter_mut().enumerate() {
                d[i] = One::one();
            }
            Self { shape, data }
        }
    }
    impl<T> Index<usize> for Matrix<T> {
        type Output = Vec<T>;
        fn index(&self, index: usize) -> &Self::Output {
            &self.data[index]
        }
    }
    impl<T> IndexMut<usize> for Matrix<T> {
        fn index_mut(&mut self, index: usize) -> &mut Self::Output {
            &mut self.data[index]
        }
    }
    impl<T> Index<(usize, usize)> for Matrix<T> {
        type Output = T;
        fn index(&self, index: (usize, usize)) -> &Self::Output {
            &self.data[index.0][index.1]
        }
    }
    impl<T> IndexMut<(usize, usize)> for Matrix<T> {
        fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
            &mut self.data[index.0][index.1]
        }
    }
    impl<'a, T: Copy + Zero + Add<Output = T>> Add for &'a Matrix<T> {
        type Output = Matrix<T>;
        fn add(self, rhs: Self) -> Self::Output {
            assert_eq!(self.shape, rhs.shape);
            let mut res = Matrix::zeros(self.shape);
            for i in 0..self.shape.0 {
                for j in 0..self.shape.1 {
                    res[i][j] = self[i][j] + rhs[i][j];
                }
            }
            res
        }
    }
    impl<'a, T: Copy + Zero + Sub<Output = T>> Sub for &'a Matrix<T> {
        type Output = Matrix<T>;
        fn sub(self, rhs: Self) -> Self::Output {
            assert_eq!(self.shape, rhs.shape);
            let mut res = Matrix::zeros(self.shape);
            for i in 0..self.shape.0 {
                for j in 0..self.shape.1 {
                    res[i][j] = self[i][j] - rhs[i][j];
                }
            }
            res
        }
    }
    impl<'a, T: Copy + Zero + Add<Output = T> + Mul<Output = T>> Mul for &'a Matrix<T> {
        type Output = Matrix<T>;
        fn mul(self, rhs: Self) -> Self::Output {
            assert_eq!(self.shape.1, rhs.shape.0);
            let mut res = Matrix::zeros((self.shape.0, rhs.shape.1));
            for i in 0..self.shape.0 {
                for j in 0..rhs.shape.1 {
                    for k in 0..self.shape.1 {
                        res[i][j] = res[i][j] + self[i][k] * rhs[k][j];
                    }
                }
            }
            res
        }
    }
    impl<T: Copy + Zero + One + Add<Output = T> + Mul<Output = T>> Matrix<T> {
        pub fn pow(&self, mut n: usize) -> Self {
            assert_eq!(self.shape.0, self.shape.1);
            let mut x = self.clone();
            let mut res = Matrix::eye(self.shape);
            while n > 0 {
                if n & 1 == 1 {
                    res = &res * &x;
                }
                x = &x * &x;
                n >>= 1;
            }
            res
        }
    }
    impl<T: Copy + Zero + One + Sub<Output = T> + Mul<Output = T> + Div<Output = T>> Matrix<T> {
        pub fn row_reduction(&mut self) {
            let (n, m) = self.shape;
            let mut c = 0;
            for r in 0..n {
                loop {
                    if c >= m {
                        return;
                    }
                    if let Some(pivot) = (r..n).find(|&p| !self[p][c].is_zero()) {
                        self.data.swap(r, pivot);
                        break;
                    };
                    c += 1;
                }
                let d = T::one() / self[r][c];
                for j in c..m {
                    self[r][j] = self[r][j] * d;
                }
                for i in (0..n).filter(|&i| i != r) {
                    let d = self[i][c];
                    for j in c..m {
                        self[i][j] = self[i][j] - d * self[r][j];
                    }
                }
                c += 1;
            }
        }
        pub fn rank(&mut self) -> usize {
            let n = self.shape.0;
            self.row_reduction();
            (0..n)
                .filter(|&i| !self.data[i].iter().all(|x| x.is_zero()))
                .count()
        }
        pub fn solve_system_of_linear_equations(&self, b: &[T]) -> Option<Vec<T>> {
            assert_eq!(self.shape.0, self.shape.1);
            assert_eq!(self.shape.0, b.len());
            let n = self.shape.0;
            let mut c = Matrix::<T>::zeros((n, n + 1));
            for i in 0..n {
                c[i][..n].clone_from_slice(&self[i]);
                c[i][n] = b[i];
            }
            c.row_reduction();
            if (0..n).any(|i| c[i][i].is_zero()) {
                None
            } else {
                Some((0..n).map(|i| c[i][n]).collect::<Vec<_>>())
            }
        }
        pub fn inverse(&self) -> Option<Matrix<T>> {
            assert_eq!(self.shape.0, self.shape.1);
            let n = self.shape.0;
            let mut c = Matrix::<T>::zeros((n, n * 2));
            for i in 0..n {
                c[i][..n].clone_from_slice(&self[i]);
                c[i][n + i] = T::one();
            }
            c.row_reduction();
            if (0..n).any(|i| c[i][i].is_zero()) {
                None
            } else {
                Some(Self::from_vec(
                    c.data.into_iter().map(|r| r[n..].to_vec()).collect(),
                ))
            }
        }
    }
}