#![allow(dead_code, unused_macros, unused_imports)]
use std::{cell::{Cell, RefCell, UnsafeCell}, cmp::{Ordering, Reverse, max, min}, collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque, hash_map::{DefaultHasher, RandomState}}, error::Error, fmt::{Display, Write as FmtWrite}, hash::{BuildHasher, Hash, Hasher}, io::{BufWriter, Read, Stdin, Stdout, Write}, iter::{FromIterator, Peekable}, mem::swap, ops::*, process::exit, rc::Rc, str::{FromStr, from_utf8_unchecked}, time::{Duration, Instant}, convert::{TryInto, TryFrom}, marker::PhantomData};

const IO_BUF_SIZE: usize = 1 << 16;
type Input = Scanner<Stdin>;
type Output = BufWriter<Stdout>;
fn _init_input() -> Input { Scanner::new(std::io::stdin()) }
fn _init_output() -> Output { BufWriter::with_capacity(IO_BUF_SIZE, std::io::stdout()) }

#[repr(transparent)] struct Unsync<T>(T);
unsafe impl<T> Sync for Unsync<T> {}

type BadLazy<T> = Unsync<UnsafeCell<Option<T>>>;
impl<T> BadLazy<T> {
    const fn new() -> Self { Self(UnsafeCell::new(None)) }
}

static INPUT: BadLazy<Input> = BadLazy::new();
static OUTPUT: BadLazy<Output> = BadLazy::new();

fn inp<F: FnOnce(&mut Input) -> R, R>(f: F) -> R {
    unsafe { f((&mut *INPUT.0.get()).get_or_insert_with(_init_input)) }
}
fn out<F: FnOnce(&mut Output) -> R, R>(f: F) -> R {
    unsafe { f((&mut *OUTPUT.0.get()).get_or_insert_with(_init_output)) }
}

macro_rules! read {
    () => { read() };
    ($t: ty) => { read::<$t>() };
    ($t: ty, $($tt: ty),*) => { (read::<$t>(), $(read::<$tt>(),)*) };
    [$t: ty; $n: expr] => { read_vec::<$t>($n) };
}
macro_rules! println {
    () => { out(|x| { let _ = writeln!(x); }) };
    ($exp: expr) => { out(|x| { let _ = writeln!(x, "{}", $exp); }) };
    ($fmt: expr, $($arg : tt )*) => { out(|x| { let _ = writeln!(x, $fmt, $($arg)*); }) }
}
macro_rules! print {
    ($exp: expr) => { out(|x| { let _ = write!(x, "{}", $exp); }) };
    ($fmt: expr, $($arg : tt )*) => { out(|x| { let _ = write!(x, $fmt, $($arg)*); }) }
}

fn out_flush() { out(|x| { let _ = x.flush(); }); }

fn input_is_eof() -> bool { inp(|x| x.eof()) }
fn read_byte() -> u8 { inp(|x| x.byte()) }
fn read_bytes_no_skip(n: usize) -> Vec<u8> { inp(|x| x.bytes_no_skip(n)) }
fn read_bytes(n: usize) -> Vec<u8> { inp(|x| x.bytes(n)) }
fn read_bytes2(n: usize, m: usize) -> Vec<Vec<u8>> { inp(|x| x.bytes2(n, m)) }
fn read_token() -> Vec<u8> { inp(|x| x.token_bytes()) }
fn read_token_str() -> String { unsafe { String::from_utf8_unchecked(read_token()) } }
fn read_line() -> Vec<u8> { inp(|x| x.line_bytes()) }
fn read_line_str() -> String { unsafe { String::from_utf8_unchecked(read_line()) } }
fn read<T: FromStr>() -> T { read_token_str().parse::<T>().ok().expect("failed parse") }
fn read_vec<T: FromStr>(n: usize) -> Vec<T> { (0..n).map(|_| read()).collect() }
fn read_vec2<T: FromStr>(n: usize, m: usize) -> Vec<Vec<T>> { (0..n).map(|_| read_vec(m)).collect() }

struct Scanner<R: Read> {
    src: R,
    _buf: Vec<u8>,
    _pt: usize, // pointer
    _rd: usize, // bytes read
}

#[allow(dead_code)]
impl<R: Read> Scanner<R> {
    fn new(src: R) -> Scanner<R> {
        Scanner { src, _buf: vec![0; IO_BUF_SIZE], _pt: 1, _rd: 1 }
    }

    fn _check_buf(&mut self) {
        if self._pt == self._rd {
            self._rd = self.src.read(&mut self._buf).unwrap_or(0);
            self._pt = (self._rd == 0) as usize;
        }
    }

    // returns true if end of file
    fn eof(&mut self) -> bool {
        self._check_buf();
        self._rd == 0
    }

    // filters \r, returns \0 if eof
    fn byte(&mut self) -> u8 {
        loop {
            self._check_buf();
            if self._rd == 0 { return 0; }
            let res = self._buf[self._pt];
            self._pt += 1;
            if res != b'\r' { return res; }
        }
    }

    fn bytes_no_skip(&mut self, n: usize) -> Vec<u8> { (0..n).map(|_| self.byte()).collect() }
    fn bytes(&mut self, n: usize) -> Vec<u8> {
        let res = self.bytes_no_skip(n);
        self.byte();
        res
    }
    fn bytes2(&mut self, n: usize, m: usize) -> Vec<Vec<u8>> { (0..n).map(|_| self.bytes(m)).collect() }

    fn token_bytes(&mut self) -> Vec<u8> {
        let mut res = Vec::new();
        let mut c = self.byte();
        while c <= b' ' {
            if c == b'\0' { return res; }
            c = self.byte();
        }
        loop {
            res.push(c);
            c = self.byte();
            if c <= b' ' { return res; }
        }
    }

    fn line_bytes(&mut self) -> Vec<u8> {
        let mut res = Vec::new();
        let mut c = self.byte();
        while c != b'\n' && c != b'\0' {
            res.push(c);
            c = self.byte();
        }
        res
    }
}

trait JoinToStr {
    fn join_to_str(self, sep: &str) -> String;
    fn concat_to_str(self) -> String;
}
impl<T: Display, I: Iterator<Item = T>> JoinToStr for I {
    fn join_to_str(mut self, sep: &str) -> String {
        match self.next() {
            Some(first) => {
                let mut res = first.to_string();
                while let Some(item) = self.next() {
                    res.push_str(sep);
                    res.push_str(&item.to_string());
                }
                res
            }
            None => { String::new() }
        }
    }

    fn concat_to_str(self) -> String {
        let mut res = String::new();
        for item in self { res.push_str(&item.to_string()); }
        res
    }
}
trait AsStr { fn as_str(&self) -> &str; }
impl AsStr for [u8] { fn as_str(&self) -> &str {std::str::from_utf8(self).expect("attempt to convert non-UTF8 byte string.")} }

macro_rules! veci {
    ($n:expr , $i:ident : $gen:expr) => {{
        let _veci_n = $n;
        let mut _veci_list = Vec::with_capacity(_veci_n);
        for $i in 0.._veci_n {
            _veci_list.push($gen);
        }
        _veci_list
    }};
    ($n:expr , $gen:expr) => { veci!($n, _veci_: $gen) }
}

fn abs_diff<T: Sub<Output = T> + PartialOrd>(x: T, y: T) -> T {
    if x < y { y - x } else { x - y }
}

trait CommonNumExt {
    fn div_ceil(self, b: Self) -> Self;
    fn div_floor(self, b: Self) -> Self;
    fn gcd(self, b: Self) -> Self;
    fn highest_one(self) -> Self;
    fn lowest_one(self) -> Self;
    fn sig_bits(self) -> u32;
}

macro_rules! impl_common_num_ext {
    ($($ix:tt = $ux:tt),*) => {
        $(
            impl CommonNumExt for $ux {
                fn div_ceil(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if r != 0 { q + 1 } else { q }
                }
                fn div_floor(self, b: Self) -> Self { self / b }
                fn gcd(self, mut b: Self) -> Self {
                    let mut a = self;
                    if a == 0 || b == 0 { return a | b; }
                    let shift = (a | b).trailing_zeros();
                    a >>= a.trailing_zeros();
                    b >>= b.trailing_zeros();
                    while a != b {
                        if a > b { a -= b; a >>= a.trailing_zeros(); }
                        else { b -= a; b >>= b.trailing_zeros(); }
                    }
                    a << shift
                }
                #[inline] fn highest_one(self) -> Self {
                    if self == 0 { 0 } else { const ONE: $ux = 1; ONE << self.sig_bits() - 1 }
                }
                #[inline] fn lowest_one(self) -> Self { self & self.wrapping_neg() }
                #[inline] fn sig_bits(self) -> u32 { std::mem::size_of::<$ux>() as u32 * 8 - self.leading_zeros() }
            }

            impl CommonNumExt for $ix {
                fn div_ceil(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if self ^ b >= 0 && r != 0 { q + 1 } else { q }
                }
                fn div_floor(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if self ^ b < 0 && r != 0 { q - 1 } else { q }
                }
                fn gcd(self, b: Self) -> Self {
                    fn w_abs(x: $ix) -> $ux { (if x.is_negative() { x.wrapping_neg() } else { x }) as _ }
                    w_abs(self).gcd(w_abs(b)) as _
                }
                #[inline] fn highest_one(self) -> Self { (self as $ux).highest_one() as _ }
                #[inline] fn lowest_one(self) -> Self { self & self.wrapping_neg() }
                #[inline] fn sig_bits(self) -> u32 { std::mem::size_of::<$ix>() as u32 * 8 - self.leading_zeros() }
            }
        )*
    }
}
impl_common_num_ext!(i8 = u8, i16 = u16, i32 = u32, i64 = u64, i128 = u128, isize = usize);

trait ChMaxMin<T> {
    fn chmax(&mut self, v: T) -> bool;
    fn chmin(&mut self, v: T) -> bool;
}
impl<T: PartialOrd> ChMaxMin<T> for Option<T> {
    fn chmax(&mut self, v: T) -> bool { if self.is_none() || v > *self.as_ref().unwrap() { *self = Some(v); true } else { false } }
    fn chmin(&mut self, v: T) -> bool { if self.is_none() || v < *self.as_ref().unwrap() { *self = Some(v); true } else { false } }
}
impl<T: PartialOrd> ChMaxMin<T> for T {
    fn chmax(&mut self, v: T) -> bool { if v > *self { *self = v; true } else { false } }
    fn chmin(&mut self, v: T) -> bool { if v < *self { *self = v; true } else { false } }
}

// * end commons * //
#[macro_use]
#[allow(dead_code)]
mod modint {
    use std::{fmt::{Display, Formatter}, marker::PhantomData, mem::swap, ops::*, str::FromStr, cell::Cell};
    use crate::ModInt;

    pub trait RemEuclidU32: Copy {
        /// Calculates `self` _mod_ `modulus` losslessly.
        fn rem_euclid_u32(self, modulus: u32) -> u32;
    }

    macro_rules! impl_rem_euclid_u32_for_small_signed {
        ($($ty:tt),*) => {
            $(
                impl RemEuclidU32 for $ty {
                    #[inline]
                    fn rem_euclid_u32(self, modulus: u32) -> u32 {
                        (self as i64).rem_euclid(i64::from(modulus)) as _
                    }
                }
            )*
        }
    }

    impl_rem_euclid_u32_for_small_signed!(i8, i16, i32, i64, isize);

    impl RemEuclidU32 for i128 {
        #[inline]
        fn rem_euclid_u32(self, modulus: u32) -> u32 {
            self.rem_euclid(i128::from(modulus)) as _
        }
    }

    macro_rules! impl_rem_euclid_u32_for_small_unsigned {
        ($($ty:tt),*) => {
            $(
                impl RemEuclidU32 for $ty {
                    #[inline]
                    fn rem_euclid_u32(self, modulus: u32) -> u32 {
                        self as u32 % modulus
                    }
                }
            )*
        }
    }

    macro_rules! impl_rem_euclid_u32_for_large_unsigned {
        ($($ty:tt),*) => {
            $(
                impl RemEuclidU32 for $ty {
                    #[inline]
                    fn rem_euclid_u32(self, modulus: u32) -> u32 {
                        (self % (modulus as $ty)) as _
                    }
                }
            )*
        }
    }

    impl_rem_euclid_u32_for_small_unsigned!(u8, u16, u32);
    impl_rem_euclid_u32_for_large_unsigned!(u64, u128);

    #[cfg(target_pointer_width = "32")]
    impl_rem_euclid_u32_for_small_unsigned!(usize);

    #[cfg(target_pointer_width = "64")]
    impl_rem_euclid_u32_for_large_unsigned!(usize);
    #[inline]
    pub fn mul_mod_u32(a: u32, b: u32, m: u32) -> u32 {
        (a as u64 * b as u64 % m as u64) as u32
    }

    // for a, b < m, unspecified otherwise
    #[inline]
    fn add_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        let (r, c) = a.wrapping_sub(m).overflowing_add(b);
        if c { r } else { a + b }
    }
    #[inline]
    fn sub_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        let (r, c) = a.overflowing_sub(b);
        if c { r.wrapping_add(m) } else { r }
    }
    fn pow_mod_raw(a: u32, mut k: u64, m: u32) -> u32 {
        if m == 1 { return 0; }
        let mut a = a as u64;
        let m = m as u64;
        let mut r: u64 = 1;
        while k > 0 {
            if k & 1 == 1 {
                r = r * a % m;
            }
            k >>= 1;
            a = a * a % m;
        }
        r as u32
    }

    /// # Parameters
    /// * `b` `1 <= b`
    /// # Returns
    /// (x, g) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
    fn inv_gcd(a: i64, b: i64) -> (i64, i64) {
        let a = a.rem_euclid(b);
        if a == 0 { return (0, b); }
        let mut s = b;
        let mut t = a;
        let mut m0 = 0;
        let mut m1 = 1;

        while t != 0 {
            let u = s / t;
            s -= t * u;
            m0 -= m1 * u;
            swap(&mut s, &mut t);
            swap(&mut m0, &mut m1);
        }

        if m0 < 0 { m0 += b / s; }
        (m0, s)
    }

    pub trait Modulus: Copy + Eq {
        fn get_modulus() -> u32;
        fn mul(a: u32, b: u32) -> u32;
    }

    #[derive(Clone, Copy, PartialEq, Eq, Hash)]
    #[repr(transparent)]
    pub struct ModIntBase<M: Modulus> {
        val: u32,
        _phantom: PhantomData<M>
    }

    impl <M: Modulus> ModIntBase<M> {
        #[inline(always)]
        pub fn modulus() -> u32 { M::get_modulus() }
        #[inline] pub fn new<I: RemEuclidU32>(val: I) -> Self { Self::raw(val.rem_euclid_u32(Self::modulus())) }
        #[inline] pub fn raw(val: u32) -> Self { Self { val, _phantom: PhantomData } }
        pub fn inv(self) -> Self {
            let (x, gcd) = inv_gcd(self.val.into(), Self::modulus().into());
            debug_assert!(gcd == 1, "the multiplicative inverse {}^-1 mod {} does not exist", self.val, Self::modulus());
            Self::raw(x as u32)
        }
        #[inline] pub fn val(self) -> u32 { self.val }
        #[inline] pub fn pow(self, k: u64) -> Self {
            Self::raw(pow_mod_raw(self.val, k, Self::modulus()))
        }
        pub fn powi(self, k: i64) -> Self { if k < 0 { self.inv().pow(-k as _) } else { self.pow(k as _) } }
        pub fn pow_vec(self, n: usize) -> Vec<Self> {
            let mut res = vec![Self::raw(0); n+1];
            res[0] += 1;
            for i in 1..=n {
                res[i] = res[i-1] * self;
            }
            res
        }

        pub fn invs(a: &[Self]) -> Vec<Self> {
            let n = a.len();
            if n == 0 { return vec![]; }
            let mut acc = Self::new(1);
            let mut res = Vec::with_capacity(n);
            for i in 0..n {
                if a[i].val() != 0 { acc *= a[i]; }
                res.push(acc);
            }
            acc = acc.inv();
            for i in (1..n).rev() {
                res[i] = acc * res[i-1];
                if a[i].val() != 0 { acc *= a[i]; }
            }
            res[0] = acc;
            res
        }
    }

    #[inline]
    pub fn mi<I: RemEuclidU32>(val: I) -> ModInt { ModIntBase::new(val) }
    #[inline] pub fn mir(v: u32) -> ModInt { ModIntBase::raw(v) }

    impl<V: RemEuclidU32, M: Modulus> From<V> for ModIntBase<M> {
        #[inline]
        fn from(from: V) -> Self { Self::new(from) }
    }
    impl<M: Modulus> Default for ModIntBase<M> {
        fn default() -> Self { Self::raw(0) }
    }
    impl<M: Modulus> FromStr for ModIntBase<M> {
        type Err = std::convert::Infallible;
        #[inline]
        fn from_str(s: &str) -> Result<Self, Self::Err> {
            Ok(s.parse::<i64>()
            .map(Self::new)
            .unwrap_or_else(|_| todo!("parsing as an arbitrary precision integer?")))
        }
    }
    impl<M: Modulus> Display for ModIntBase<M> {
        #[inline]
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            self.val.fmt(f)
        }
    }
    impl<M: Modulus> std::fmt::Debug for ModIntBase<M> {
        #[inline]
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            std::fmt::Debug::fmt(&self.val, f)
        }
    }
    impl<M: Modulus> Neg for ModIntBase<M> {
        type Output = Self;

        #[inline]
        fn neg(self) -> Self::Output {
            Self::raw(0) - self
        }
    }

    impl<V: Into<ModIntBase<M>>, M: Modulus> Add<V> for ModIntBase<M> {
        type Output = Self;
        #[inline]
        fn add(self, rhs: V) -> Self::Output {
            Self::raw(add_mod_raw(self.val, rhs.into().val, Self::modulus()))
        }
    }
    impl<V: Into<ModIntBase<M>>, M: Modulus> Sub<V> for ModIntBase<M> {
        type Output = Self;
        #[inline]
        fn sub(self, rhs: V) -> Self::Output {
            Self::raw(sub_mod_raw(self.val, rhs.into().val, Self::modulus()))
        }
    }
    impl<V: Into<ModIntBase<M>>, M: Modulus> Mul<V> for ModIntBase<M> {
        type Output = Self;
        #[inline]
        fn mul(self, rhs: V) -> Self::Output {
            Self::raw(M::mul(self.val, rhs.into().val))
        }
    }
    impl<V: Into<ModIntBase<M>>, M: Modulus> Div<V> for ModIntBase<M> {
        type Output = Self;
        #[inline]
        fn div(self, rhs: V) -> Self::Output { self * rhs.into().inv() }
    }

    impl <V: Into<ModIntBase<M>>, M: Modulus> AddAssign<V> for ModIntBase<M> {
        #[inline]
        fn add_assign(&mut self, rhs: V) { *self = *self + rhs; }
    }
    impl <V: Into<ModIntBase<M>>, M: Modulus> SubAssign<V> for ModIntBase<M> {
        #[inline]
        fn sub_assign(&mut self, rhs: V) { *self = *self - rhs; }
    }
    impl <V: Into<ModIntBase<M>>, M: Modulus> MulAssign<V> for ModIntBase<M> {
        #[inline]
        fn mul_assign(&mut self, rhs: V) { *self = *self * rhs; }
    }
    impl <V: Into<ModIntBase<M>>, M: Modulus> DivAssign<V> for ModIntBase<M> {
        #[inline]
        fn div_assign(&mut self, rhs: V) { *self = *self / rhs; }
    }

    impl <M: Modulus> std::iter::Sum for ModIntBase<M> {
        #[inline] fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(Self::raw(0), Add::add)
        }
    }
    impl <M: Modulus> std::iter::Product for ModIntBase<M> {
        #[inline] fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(1.into(), Mul::mul)
        }
    }
    impl<'a, M: Modulus> std::iter::Sum<&'a Self> for ModIntBase<M> {
        #[inline] fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> ModIntBase<M> {
            iter.fold(Self::raw(0), |a, &b| a + b)
        }
    }
    impl<'a, M: Modulus> std::iter::Product<&'a Self> for ModIntBase<M> {
        #[inline] fn product<I: Iterator<Item = &'a Self>>(iter: I) -> ModIntBase<M> {
            iter.fold(1.into(), |a, &b| a * b)
        }
    }

    macro_rules! const_modulus {
        ($mint: ident, $name: ident, $modulus: expr) => {
            #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
            pub enum $name {}
            impl Modulus for $name {
                #[inline(always)] fn get_modulus() -> u32 { $modulus }
                fn mul(a: u32, b: u32) -> u32 {
                    mul_mod_u32(a, b, Self::get_modulus())
                }
            }
            pub type $mint = ModIntBase<$name>;
        }
    }

    #[derive(Debug, Clone, Copy)]
    pub struct ModulusCalc {
        pub modulus: u32,
        pub inv: u64
    }

    macro_rules! dynamic_modulus {
        ($mint: ident, $name: ident, $modulus: ident) => {
            static $modulus: crate::Unsync<Cell<ModulusCalc>> = crate::Unsync(Cell::new(ModulusCalc { modulus: 0, inv: 0 }));
            #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
            pub enum $name {}
            impl Modulus for $name {
                fn get_modulus() -> u32 { $modulus.0.get().modulus }
                fn mul(a: u32, b: u32) -> u32 {
                    let ModulusCalc { modulus, inv } = $modulus.0.get();
                    let p = a as u64 * b as u64;
                    let g = ((p as u128 * inv as u128) >> 64) as u64;
                    let (r, c) = p.overflowing_sub(g * modulus as u64);
                    if c { (r as u32).wrapping_add(modulus) } else { r as u32 }
                }
            }
            impl $name {
                pub fn set_modulus(val: u32) {
                    let inv = (1u64.wrapping_neg() / val as u64).wrapping_add(1);
                    $modulus.0.set(ModulusCalc { modulus: val, inv })
                }
            }
            pub type $mint = ModIntBase<$name>;
        }
    }

    const_modulus!(ModInt998_244_353, Mod998_244_353, 998_244_353);
    const_modulus!(ModInt1_000_000_007, Mod1_000_000_007, 1_000_000_007);
    dynamic_modulus!(DynamicModInt, DynamicModulus, DYNAMIC_MODULUS);
}

use crate::modint::*;
type ModInt = ModInt998_244_353;
// type ModInt = ModInt1_000_000_007;
// const_modulus!(ModInt, DefaultModulus, 1_000_000_009);
// type ModInt = DynamicModInt;

pub struct ModFft {
    n_inv: ModInt,
    w: Vec<ModInt>
}
impl ModFft {
    pub fn primitive_root() -> ModInt { ModInt::raw(3) /* for 998244353 */}
    pub fn good_len(deg: usize) -> usize { (deg + 1).next_power_of_two() }
    pub fn prepare(arr: &[ModInt], deg: usize) -> Vec<ModInt> {
        let n = Self::good_len(deg);
        let mut res = Vec::with_capacity(n);
        res.extend_from_slice(arr);
        res.resize(n, ModInt::raw(0));
        res
    }

    pub fn new(max_deg: usize) -> Self {
        let n = Self::good_len(max_deg);
        Self {
            n_inv: ModInt::new(n).inv(),
            w: ModInt::pow_vec(Self::primitive_root().pow((ModInt::modulus() - 1) as u64 / n as u64), n-1)
        }
    }

    pub fn transform(&self, a: &mut [ModInt]) { self.transform_impl(a, false) }
    pub fn transform_inv(&self, a: &mut [ModInt]) { self.transform_impl(a, true) }

    pub fn fft(&self, a: &[ModInt]) -> Vec<ModInt> { self.fft_deg(a, a.len() - 1) }
    pub fn fft_deg(&self, a: &[ModInt], deg: usize) -> Vec<ModInt> {
        let mut a = Self::prepare(a, deg);
        self.transform(&mut a);
        a
    }
    pub fn fft_inv(&self, a: &[ModInt]) -> Vec<ModInt> {
        let mut a = Self::prepare(a, a.len() - 1);
        self.transform_inv(&mut a);
        a
    }

    pub fn max_deg(&self) -> usize { self.w.len() - 1 }

    #[inline] fn transform_impl(&self, a: &mut [ModInt], invert: bool) {
        let sz = a.len();
        if sz <= 1 { return }
        let n = self.w.len();
        debug_assert!(sz <= n && sz.is_power_of_two(), "Array size {} must be <= {} and a power of 2", sz, n);
        let sh = sz.leading_zeros() + 1;

        for i in 0..sz {
            let j = i.reverse_bits() >> sh;
            if i < j { a.swap(i, j) }
        }

        let mut len = 2usize;
        let mut ang = (n >> 1) as isize;
        if invert { ang = -ang; }
        while len <= sz {
            let h = len >> 1;
            for i in (0..sz).step_by(len) {
                let mut k = 0usize;
                for j in i..i+h {
                    let u = a[j];
                    let v = a[j+h] * self.w[k];
                    a[j] = u + v;
                    a[j+h] = u - v;
                    k = k.wrapping_add(ang as usize) & (n-1);
                }
            }
            len <<= 1;
            ang >>= 1;
        }

        if invert {
            let sz_inv = self.n_inv * (n / sz);
            for i in 0..sz { a[i] *= sz_inv; }
        }
    }

    const NAIVE_THRESHOLD: usize = 60;
    fn naive_mul(a: &[ModInt], b: &[ModInt]) -> Vec<ModInt> {
        let n = a.len();
        let m = b.len();
        let mut ans = vec![ModInt::raw(0); n + m - 1];
        for i in 0..n { for j in 0..m {
            ans[i + j] += a[i] * b[j];
        }}
        ans
    }

    pub fn mul(&self, a: &[ModInt], b: &[ModInt]) -> Vec<ModInt> {
        if a.is_empty() || b.is_empty() { return vec![]; }
        let deg = a.len() + b.len() - 2;
        debug_assert!(deg < self.w.len(), "FFT capacity {} too small for polynomial of degree {}", self.w.len(), deg);
        if min(a.len(), b.len()) <= Self::NAIVE_THRESHOLD { return Self::naive_mul(a, b); }
        let mut a = Self::prepare(a, deg);
        let mut b = Self::prepare(b, deg);
        self.transform(&mut a);
        self.transform(&mut b);
        for i in 0..a.len() { a[i] *= b[i]; }
        self.transform_inv(&mut a);
        a.truncate(deg + 1);
        a
    }

    pub fn sq(&self, a: &[ModInt]) -> Vec<ModInt> {
        if a.is_empty() { return vec![]; }
        let deg = a.len() * 2 - 2;
        debug_assert!(deg < self.w.len(), "FFT capacity {} too small for polynomial of degree {}", self.w.len(), deg);
        if a.len() <= Self::NAIVE_THRESHOLD { return Self::naive_mul(a, a); }
        let mut a = Self::prepare(a, deg);
        self.transform(&mut a);
        for i in 0..a.len() { let ai = a[i]; a[i] = ai * ai; }
        self.transform_inv(&mut a);
        a.truncate(deg + 1);
        a
    }

    pub fn pow(&self, a: &[ModInt], exp: usize) -> Vec<ModInt> {
        if a.is_empty() { return vec![]; }
        let deg = (a.len() - 1) * exp;
        debug_assert!(deg < self.w.len(), "FFT capacity {} too small for polynomial of degree {}", self.w.len(), deg);
        let mut a = Self::prepare(a, deg);
        self.transform(&mut a);
        for i in 0..a.len() { a[i] = a[i].pow(exp as u64) }
        self.transform_inv(&mut a);
        a.truncate(deg + 1);
        a
    }

    pub fn product(&self, mut polys: VecDeque<Vec<ModInt>>) -> Vec<ModInt> {
        while let Some(p) = polys.pop_front() {
            if let Some(q) = polys.pop_front() {
                polys.push_back(self.mul(&p, &q));
            } else { return p; }
        }

        vec![ModInt::new(1)]
    }
}

#[allow(non_snake_case, non_upper_case_globals)]
fn main() {
    let num_cases: usize = 1;//read();

    for _case_num in 1..=num_cases {
        let n = read!(usize);
		let k = read!(usize);
		let f = read!(usize);

		let ff = ModFft::new(2*k);
		let mut dp = vec![mi(1); k+1];
		for _ in 1..n {
			let sq = ff.sq(&dp);
			let mut sm = sq[k+1..].iter().sum::<ModInt>();
			for i in (0..=k).rev() {
				dp[i] = sq[i] * (k + 1 - i) + sm;
				sm += sq[i];
			}
		}

		dp.resize(f+1, mi(0));
		let ans = (0..=f).map(|i| dp[i] * dp[f-i]).sum::<ModInt>();
		println!(ans);
    }

    out_flush();
}


use std::collections::VecDeque;
use std::io::{self, Write};
use std::str::FromStr;
use core::cmp::min;
use core::cmp::max;

struct Scanner {
    stdin: io::Stdin,
    buffer: VecDeque<String>,
}

impl Scanner {
    fn new() -> Self {
        Scanner {
            stdin: io::stdin(),
            buffer: VecDeque::new(),
        }
    }

    fn cin<T: FromStr>(&mut self) -> T {
        while self.buffer.is_empty() {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
        self.buffer.pop_front().unwrap().parse::<T>().ok().unwrap()
    }
}

fn main() {
    let mut sc = Scanner::new();
    let n: u32 = sc.cin();
    let (mut a1, mut b1, mut c1): (u32, u32, u32) = (sc.cin(), sc.cin(), sc.cin());
    let (mut a2, mut b2, mut c2): (u32, u32, u32) = (sc.cin(), sc.cin(), sc.cin());
    let mut ans = n;
    let res = min(a1, b2) + min(b1, c2) + min(c1, a2);
    if a2 >= a1 + b1 || b2 >= b1 + c1 || c2 >= c1 + a1 {
        if a2 >= a1 + b1 {
            ans = min(ans, a2 - a1 - b1);
        }
        if b2 >= b1 + c1 {
            ans = min(ans, b2 - b1 - c1);
        }
        if c2 >= c1 + a1 {
            ans = min(ans, c2 - c1 - a1);
        }
        ans = max(ans, 0);
        print!("{}", ans);
    } else {
        print!("0");
    }
    println!(" {}", res);
}


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

fn get_pair() -> (i32, i32) {
    let mut input = String::new();

    io::stdin().read_line(&mut input).expect("");

    let v = input
        .trim()
        .split_whitespace()
        .map(|s| i32::from_str(s).unwrap())
        .collect::<Vec<_>>();

    (v[0], v[1])
}

fn main() {
    let (n, m) = get_pair();

    let mut c = 0;
    for a in 0..=1000 {
        for b in 0..=100 {
            if a * a + b == n && a + b * b == m {
                c += 1;
            }
        }
    }

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


fn main() {
    let n: u32 = get_input().parse().unwrap();
    let v= get_fib(n);
    println!("{} {} {}", v.2, v.1, v.0);

}

fn get_input() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).expect("Failed");
    buffer.trim().to_owned()
}

fn get_input_usize() -> usize {
    get_input().parse().unwrap()
}

fn get_fib(n: u32) -> (u32, u32, u32) {
    if n == 3 {
        (1,1,1)
    } else {
        let mut prev = 0;
        let mut curr = 1;
        let mut vec = vec![0, 0, 0, 0, 1];

        while curr <= n {
            vec.push(curr);
            let temp = prev;
            prev = curr;
            curr = curr + temp;

        }

        let len = vec.len();
        (vec[len - 2], vec[len - 4], vec[len - 5])
    }
}


// ---------- begin Matrix ----------
mod matrix {
    use std::ops::*;
    pub trait SemiRing: Add<Output = Self> + Mul<Output = Self> + Copy {
        fn zero() -> Self;
        fn one() -> Self;
    }
    pub trait Inverse: SemiRing {
        fn is_zero() -> bool;
        fn inv(self) -> Self;
    }
    #[derive(Clone)]
    pub struct SquareMatrix<R> {
        size: usize,
        buf: Box<[R]>,
    }
    #[allow(dead_code)]
    impl<R: SemiRing> SquareMatrix<R> {
        pub fn zero(size: usize) -> Self {
            SquareMatrix {
                size: size,
                buf: vec![R::zero(); size * size].into_boxed_slice(),
            }
        }
        pub fn identity(size: usize) -> Self {
            let mut e = Self::zero(size);
            for i in 0..size {
                e.buf[i * size + i] = R::one();
            }
            e
        }
        pub fn set_at(&mut self, x: usize, y: usize, val: R) {
            assert!(x < self.size && y < self.size);
            self.buf[x * self.size + y] = val;
        }
        pub fn get_at(&self, x: usize, y: usize) -> R {
            assert!(x < self.size && y < self.size);
            self.buf[x * self.size + y]
        }
        pub fn get_mut(&mut self, x: usize, y: usize) -> &mut R {
            assert!(x < self.size && y < self.size);
            &mut self.buf[x * self.size + y]
        }
        pub fn matadd(&self, rhs: &Self) -> Self {
            assert!(self.size == rhs.size);
            let buf: Vec<R> = self
                .buf
                .iter()
                .zip(rhs.buf.iter())
                .map(|p| *p.0 + *p.1)
                .collect();
            SquareMatrix {
                size: self.size,
                buf: buf.into_boxed_slice(),
            }
        }
        pub fn matmul(&self, rhs: &Self) -> Self {
            let size = self.size;
            assert!(size == rhs.size);
            let mut res = Self::zero(size);
            for (x, a) in res.buf.chunks_mut(size).zip(self.buf.chunks(size)) {
                for (a, b) in a.iter().zip(rhs.buf.chunks(size)) {
                    for (x, b) in x.iter_mut().zip(b.iter()) {
                        *x = *x + *a * *b;
                    }
                }
            }
            res
        }
        pub fn mat_pow(&self, mut n: usize) -> Self {
            let size = self.size;
            let mut t = Self::identity(size);
            let mut s = self.clone();
            while n > 0 {
                if n & 1 == 1 {
                    t = t.matmul(&s);
                }
                s = s.matmul(&s);
                n >>= 1;
            }
            t
        }
    }
    #[allow(dead_code)]
    impl<R: SemiRing + Sub<Output = R>> SquareMatrix<R> {
        pub fn matsub(&self, rhs: &Self) -> Self {
            assert!(self.size == rhs.size);
            let buf: Vec<R> = self
                .buf
                .iter()
                .zip(rhs.buf.iter())
                .map(|p| *p.0 - *p.1)
                .collect();
            SquareMatrix {
                size: self.size,
                buf: buf.into_boxed_slice(),
            }
        }
    }
    /*
    #[allow(dead_code)]
    impl<R: Inverse + Sub<Output = R>> SquareMatrix<R> {
        pub fn inverse(&self) -> Self {
        }
    }
    */
}
// ---------- end Matrix ----------
// ---------- begin ModInt ----------
// モンゴメリ乗算を用いる
// ほぼCodeforces用
// 注意
// new_unchecked は値xが 0 <= x < modulo であることを仮定
// ModInt の中身は正規化された値で持ってるので直接読んだり書いたりするとぶっ壊れる
// 奇素数のみ
mod modint {

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

    pub trait Modulo {
        fn modulo() -> u32;
        fn rem() -> u32;
        fn ini() -> u64;
        fn reduce(x: u64) -> u32 {
            assert!(x < (Self::modulo() as u64) << 32);
            let b = (x as u32 * Self::rem()) as u64;
            let t = x + b * Self::modulo() as u64;
            let mut c = (t >> 32) as u32;
            if c >= Self::modulo() {
                c -= Self::modulo();
            }
            c as u32
        }
    }

    #[allow(dead_code)]
    pub enum Mod1_000_000_007 {}

    impl Modulo for Mod1_000_000_007 {
        fn modulo() -> u32 {
            1_000_000_007
        }
        fn rem() -> u32 {
            2226617417
        }
        fn ini() -> u64 {
            582344008
        }
    }

    #[allow(dead_code)]
    pub enum Mod998_244_353 {}

    impl Modulo for Mod998_244_353 {
        fn modulo() -> u32 {
            998_244_353
        }
        fn rem() -> u32 {
            998244351
        }
        fn ini() -> u64 {
            932051910
        }
    }

    #[allow(dead_code)]
    pub fn generate_umekomi_modulo(p: u32) {
        assert!(
            p < (1 << 31)
                && p > 2
                && p & 1 == 1
                && (2u32..).take_while(|v| v * v <= p).all(|k| p % k != 0)
        );
        let mut t = 1u32;
        let mut s = !p + 1;
        let mut n = !0u32 >> 2;
        while n > 0 {
            if n & 1 == 1 {
                t *= s;
            }
            s *= s;
            n >>= 1;
        }
        let mut ini = (1u64 << 32) % p as u64;
        ini = (ini << 32) % p as u64;
        assert!(t * p == !0);
        println!("pub enum Mod{} {{}}", p);
        println!("impl Modulo for Mod{} {{", p);
        println!("    fn modulo() -> u32 {{");
        println!("        {}", p);
        println!("    }}");
        println!("    fn rem() -> u32 {{");
        println!("        {}", t);
        println!("    }}");
        println!("    fn ini() -> u32 {{");
        println!("        {}", ini);
        println!("    }}");
        println!("}}");
        let mut f = vec![];
        let mut n = p - 1;
        for i in 2.. {
            if i * i > n {
                break;
            }
            if n % i == 0 {
                f.push(i);
                while n % i == 0 {
                    n /= i;
                }
            }
        }
        if n > 1 {
            f.push(n);
        }
        let mut order = 1;
        let mut n = p - 1;
        while n % 2 == 0 {
            n /= 2;
            order <<= 1;
        }
        let z = (2u64..)
            .find(|z| {
                f.iter()
                    .all(|f| mod_pow(*z, ((p - 1) / *f) as u64, p as u64) != 1)
            })
            .unwrap();
        let zeta = mod_pow(z, ((p - 1) / order) as u64, p as u64);
        println!("impl transform::NTTFriendly for Mod{} {{", p);
        println!("    fn order() -> usize {{");
        println!("        {}", order);
        println!("    }}");
        println!("    fn zeta() -> u32 {{");
        println!("        {}", zeta);
        println!("    }}");
        println!("}}");
    }

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

    impl<T> Clone for ModInt<T> {
        fn clone(&self) -> Self {
            ModInt::build(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();
            }
            Self::build(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();
            }
            Self::build(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 {
            Self::build(T::reduce(self.0 as u64 * rhs.0 as u64))
        }
    }

    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::build(T::modulo() - self.0)
            }
        }
    }

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

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

    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> {
        fn build(d: u32) -> Self {
            ModInt(d, PhantomData)
        }
        pub fn zero() -> Self {
            Self::build(0)
        }
        pub fn is_zero(&self) -> bool {
            self.0 == 0
        }
    }

    #[allow(dead_code)]
    impl<T: Modulo> ModInt<T> {
        pub fn new_unchecked(d: u32) -> Self {
            Self::build(T::reduce(d as u64 * T::ini()))
        }
        pub fn new(d: u32) -> Self {
            Self::new_unchecked(d % T::modulo())
        }
        pub fn one() -> Self {
            Self::new_unchecked(1)
        }
        pub fn get(&self) -> u32 {
            T::reduce(self.0 as u64)
        }
        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.is_zero());
            self.pow((T::modulo() - 2) as u64)
        }
    }

    pub fn mod_pow(mut r: u64, mut n: u64, m: u64) -> u64 {
        let mut t = 1 % m;
        while n > 0 {
            if n & 1 == 1 {
                t = t * r % m;
            }
            r = r * r % m;
            n >>= 1;
        }
        t
    }
}
// ---------- end ModInt ----------

use modint::*;

type M = ModInt<Mod998_244_353>;

// ---------- 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 ----------

// 行列累乗っぽいが状態数厳しげでは...

use matrix::*;
type Mat = SquareMatrix<M>;

impl SemiRing for M {
    fn zero() -> Self {
        M::zero()
    }
    fn one() -> Self {
        M::one()
    }
}

fn lcp(x: &[u8], y: &[u8]) -> usize {
    x.iter().zip(y).take_while(|p| *p.0 == *p.1).count()
}

fn run() {
    input! {
        n: usize,
        m: usize,
        s: [bytes; n],
    }
    let mut id = 0;
    let mut map = std::collections::BTreeMap::new();
    for s in s.iter() {
        for i in 0..s.len() {
            let s = s[i..].iter().cloned().collect::<Vec<_>>();
            map.entry(s).or_insert_with(|| {
                let v = id;
                id += 1;
                v
            });
        }
    }
    map.insert(vec![], id);
    id += 1;
    let mut edge = vec![];
    for (x, &src) in map.iter() {
        if x.is_empty() {
            for a in s.iter() {
                for b in s.iter() {
                    let len = lcp(a, b);
                    let a = a[len..].iter().cloned().collect::<Vec<_>>();
                    let b = b[len..].iter().cloned().collect::<Vec<_>>();
                    if !a.is_empty() && !b.is_empty() {
                        continue;
                    }
                    let mut pre = src;
                    for _ in 1..len {
                        edge.push((pre, id));
                        pre = id;
                        id += 1;
                    }
                    if a.is_empty() {
                        let dst = *map.get(&b).unwrap();
                        edge.push((pre, dst));
                    } else if b.is_empty() {
                        let dst = *map.get(&a).unwrap();
                        edge.push((pre, dst));
                    }
                }
            }
        } else {
            for a in s.iter() {
                let len = lcp(a, x);
                let a = a[len..].iter().cloned().collect::<Vec<_>>();
                let b = x[len..].iter().cloned().collect::<Vec<_>>();
                if !a.is_empty() && !b.is_empty() {
                    continue;
                }
                let mut pre = src;
                for _ in 1..len {
                    edge.push((pre, id));
                    pre = id;
                    id += 1;
                }
                if a.is_empty() {
                    let dst = *map.get(&b).unwrap();
                    edge.push((pre, dst));
                } else if b.is_empty() {
                    let dst = *map.get(&a).unwrap();
                    edge.push((pre, dst));
                }
            }
        }
    }
    let mut mat = Mat::zero(id);
    for &(a, b) in edge.iter() {
        *mat.get_mut(a, b) += M::one();
    }
    let pow = mat.mat_pow(m);
    let v = *map.get(&vec![]).unwrap();
    let ans = pow.get_at(v, v);
    println!("{}", ans);
}

fn main() {
    run();
}


use std::io::{self, Write};

fn gcd(a: usize, b: usize) -> usize {
    if b == 0 {a} else {gcd(b, a % b)}
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut sc = cf_scanner::Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());

    for _ in 0..sc.next() {
        let x: usize = sc.next();
        let y = 100 - x;
        let z = gcd(x, y);
        writeln!(out, "{}", x / z + y / z).unwrap();
    }
}

#[allow(dead_code)]
mod cf_scanner {
    use std::io;
    use std::str::{FromStr, SplitAsciiWhitespace};

    pub struct Scanner<R> {
        reader: R,
        buf_str: Vec<u8>,
        buf_iter: SplitAsciiWhitespace<'static>,
    }

    impl<R: io::BufRead> Scanner<R> {
        pub fn new(reader: R) -> Scanner<R> {
            Scanner {
                reader,
                buf_str: Vec::new(),
                buf_iter: "".split_ascii_whitespace(),
            }
        }

        pub fn next<T: FromStr>(&mut self) -> T {
            loop {
                if let Some(token) = self.buf_iter.next() {
                    return token.parse().ok().expect("Failed parse");
                }
                self.buf_str.clear();
                self.reader
                    .read_until(b'\n', &mut self.buf_str)
                    .expect("Failed read");
                self.buf_iter = unsafe {
                    let slice = std::str::from_utf8_unchecked(&self.buf_str);
                    std::mem::transmute(slice.split_ascii_whitespace())
                }
            }
        }

        pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            (0..n).map(|_| self.next()).collect()
        }

        pub fn next_str(&mut self) -> Vec<char> {
            self.next::<String>().chars().collect()
        }
    }
}


use std::io;

fn main () {
        // read
        let mut s = String::new();
        io::stdin().read_line(&mut s);

        let int_vec: Vec<f64> =s.trim()
                .split(" ")
                .map(|x|{
                        x.parse::<f64>().expect("not an integer")
                        })
                .collect();

        let mut a :f64 = int_vec[0];
        let mut b : f64 = int_vec[1];
        let mut m : f64 = int_vec[2];

        let mut lado_a = (a/m).ceil();
        let mut lado_b = (b/m).ceil();

        println!("{}",lado_a*lado_b);

}


macro_rules !input {(source =$s :expr ,$($r :tt ) *) =>{let mut iter =$s .split_whitespace () ;let mut next =||{iter .next () .unwrap () } ;input_inner !{next ,$($r ) *} } ;($($r :tt ) *) =>{let stdin =std ::io ::stdin () ;let mut bytes =std ::io ::Read ::bytes (std ::io ::BufReader ::new (stdin .lock () ) ) ;let mut next =move ||->String {bytes .by_ref () .map (|r |r .unwrap () as char ) .skip_while (|c |c .is_whitespace () ) .take_while (|c |!c .is_whitespace () ) .collect () } ;input_inner !{next ,$($r ) *} } ;}
macro_rules !input_inner {($next :expr ) =>{} ;($next :expr ,) =>{} ;($next :expr ,$var :ident :$t :tt $($r :tt ) *) =>{let $var =read_value !($next ,$t ) ;input_inner !{$next $($r ) *} } ;}
macro_rules !read_value {($next :expr ,($($t :tt ) ,*) ) =>{($(read_value !($next ,$t ) ) ,*) } ;($next :expr ,[$t :tt ;$len :expr ] ) =>{(0 ..$len ) .map (|_ |read_value !($next ,$t ) ) .collect ::<Vec <_ >>() } ;($next :expr ,chars ) =>{read_value !($next ,String ) .chars () .collect ::<Vec <char >>() } ;($next :expr ,usize1 ) =>{read_value !($next ,usize ) -1 } ;($next :expr ,$t :ty ) =>{$next () .parse ::<$t >() .expect ("Parse error" ) } ;}
trait Monoid {
    fn id() -> Self;
    fn f(a: Self, b: Self) -> Self;
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
enum MaxInt {
    Minimal,
    Val(i64),
}
impl std::ops::Mul for MaxInt {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        if self > other {
            self
        } else {
            other
        }
    }
}
impl MaxInt {
    fn unwrap(self) -> i64 {
        if let Self::Val(x) = self {
            x
        } else {
            panic!();
        }
    }
    fn map<F>(self, f: F) -> Self
    where
        F: Fn(i64) -> i64,
    {
        if let Self::Val(x) = self {
            Self::Val(f(x))
        } else {
            Self::Minimal
        }
    }
}
impl Monoid for MaxInt {
    fn id() -> Self {
        MaxInt::Minimal
    }
    fn f(a: Self, b: Self) -> Self {
        a * b
    }
}
use MaxInt::*;

fn main() {
    input! {
        n: usize,
        k: usize,
        s: String,
        t: String,
    }
    let s = s.chars().map(|c| c as u8).collect::<Vec<_>>();
    let t = t.chars().map(|c| c as u8).collect::<Vec<_>>();
    if t[0] == t[1] {
        let mut ans = 0;
        let mut c = 0;
        let mut k = k;
        for i in 0..n {
            if k != 0 && s[i] != t[0] {
                ans += c;
                c += 1;
                k -= 1;
            }
            if s[i] == t[0] {
                ans += c;
                c += 1;
            }
        }
        println!("{}", ans);
        return;
    }
    if k == 0 {
        let mut ans = 0;
        let mut c = 0;
        for i in 0..n {
            if s[i] == t[0] {
                c += 1;
            }
            if s[i] == t[1] {
                ans += c;
            }
        }
        println!("{}", ans);
        return;
    }

    let mut dp = vec![vec![vec![Minimal; n + 1]; k + 2]; n + 1];
    dp[0][0][0] = Val(0);
    for i in 0..n {
        for k in 0..=k {
            for c in 0..=i {
                if s[i] == t[0] {
                    dp[i + 1][k][c + 1] = dp[i + 1][k][c + 1] * dp[i][k][c];
                } else {
                    dp[i + 1][k + 1][c + 1] = dp[i + 1][k + 1][c + 1] * dp[i][k][c];
                }
                if s[i] == t[1] {
                    dp[i + 1][k][c] = dp[i + 1][k][c] * dp[i][k][c].map(|v| v + c as i64);
                } else {
                    dp[i + 1][k + 1][c] = dp[i + 1][k + 1][c] * dp[i][k][c].map(|v| v + c as i64);
                }
                if s[i] != t[0] && s[i] != t[1] {
                    dp[i + 1][k][c] = dp[i + 1][k][c] * dp[i][k][c];
                }
            }
        }
    }
    let mut ans = Minimal;
    for k in 0..=k {
        for c in 0..=n {
            ans = ans * dp[n][k][c];
        }
    }
    println!("{}", ans.unwrap());
}


#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
#[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;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[doc = " main"]
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    input!{
        n:i64,
    }
    let mut tot = 0;
    for i in 2..=n-1 {
        tot += i * (i+1);
    }
    writeln!(out,"{}",tot);
}


// https://codeforces.com/contest/1271/problem/E
//
#![allow(unused_imports)]
use std::io::*;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

#[allow(unused_macros)]
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)*}
    };
}

#[allow(unused_macros)]
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)*}
    };

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

#[allow(unused_macros)]
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, [ next / $t:tt ]) => {
        {
            let len = read_value!($iter, usize);
            (0..len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
        }
    };

    ($iter:expr, switch) => {
        {
            let ty = read_value!($iter, i32);
            if ty == 1 {
                vec![ty, read_value!($iter, i32), read_value!($iter, i32)]
            } else if ty == 2 {
                vec![ty, read_value!($iter, i32)]
            } else {
                vec![ty, read_value!($iter, i32)]
            }
        }
    };

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

#[allow(unused_macros)]
macro_rules! dvec {
    ($t:expr ; $len:expr) => {
        vec![$t; $len]
    };

    ($t:expr ; $len:expr, $($rest:expr),*) => {
        vec![dvec!($t; $($rest),*); $len]
    };
}

#[allow(unused_macros)]
macro_rules! ifv {
    ($t:expr, $a:expr, $b: expr) => {
        if $t { $a } else { $b }
    }
}

#[allow(unused_macros)]
macro_rules! fill {
    ($t:expr, $v:expr) => {
        for i in 0..$t.len() {
            $t[i] = $v;
        }
    };
}

#[allow(unused_macros)]
macro_rules! join {
    ($t:expr, $glue:expr) => {
        $t.into_iter().map(|w| w.to_string()).collect::<Vec<_>>().join($glue)
    };
}

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

fn exp(upto: usize, k: usize) {
    let mut cnt = vec![0; upto];
    for w in 1..upto {
        let mut ww = w;
        loop {
            cnt[ww] += 1;
            if ww == 1 {
                break;
            }
            if ww % 2 == 0 {
                ww /= 2;
            } else {
                ww -= 1;
            }
        }
    }
    let mut up = 0;
    for w in (1..upto).rev() {
        if cnt[w] > up {
            up = cnt[w];
            // debug!(w, up);
        }
    }
    for w in (1..upto).rev() {
        if cnt[w] >= k {
            println!("{}", w);
            break;
        }
    }
}

fn main() {
    input! {
        n: i64, k: i64
    };

    if n <= 100 {
        exp((n+1) as usize, k as usize);
        return;
    }

    let mut ans = -1;
    let mut tbl = vec![(n, 1), (n-1, ifv!(n % 2 == 0, 1, 2)), (n-2, ifv!(n % 2 == 0, 2, 1))];
    loop {
        // debug!(tbl);
        for &(f, l) in &tbl {
            if k <= l {
                ans = f;
                break;
            }
        }
        if tbl[0].0 <= 1 {
            break;
        }
        if ans != -1 {
            break;
        }

        let mut ntbl: Vec<(i64, i64)> = vec![];
        let tn = tbl.len();
        for nex in 0..4 {
            let to = tbl[0].0 / 2 - nex;
            let mut add = 1;

            // find 2*to
            {
                let mut f2 = false;
                for f in 0..tn {
                    if tbl[f].0 == 2*to {
                        add += tbl[f].1;
                        f2 = true;
                        break;
                    }
                }
                if !f2 {
                    for f in 0..nex {
                        if ntbl[f as usize].0 == 2*to {
                            add += ntbl[f as usize].1;
                            f2 = true;
                            break;
                        }
                    }
                }

                if !f2 {
                    for f in (0..tn).rev() {
                        if tbl[f].0 % 2 == 0 {
                            add += tbl[f].1;
                            break;
                        }
                    }
                }
            }

            // find to+1
            if to % 2 == 0 {
                // we already have that one...
                if nex >= 1 {
                    add += ntbl[(nex-1) as usize].1;
                } else {
                    for f in (0..tn).rev() {
                        if tbl[f].0 % 2 == 1 {
                            add += tbl[f].1;
                            break;
                        }
                    }
                }
            }
            ntbl.push((to, add));
        }
        tbl = ntbl;
    }

    // exp((n+1) as usize);
    println!("{}", ans);
}


// ---------- begin ModInt ----------
const MOD: u32 = 998_244_353;
#[derive(Clone, Copy)]
struct ModInt(u32);

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, rhs: ModInt) -> ModInt {
        let mut d = self.0 + rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> ModInt {
        ModInt((self.0 as u64 * rhs.0 as u64 % MOD as u64) as u32)
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> ModInt {
        let mut d = self.0 + MOD - rhs.0;
        if d >= MOD {
            d -= MOD;
        }
        ModInt(d)
    }
}

impl std::ops::Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> ModInt {
        if self.0 == 0 {self} else {ModInt(MOD - self.0)}
    }
}

impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, rhs: ModInt) {
        *self = *self + rhs;
    }
}

impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, rhs: ModInt) {
        *self = *self * rhs;
    }
}

impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, rhs: ModInt) {
        *self = *self - rhs;
    }
}

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

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

#[allow(dead_code)]
impl ModInt {
    pub fn new(v: u32) -> ModInt {
        ModInt(v % MOD)
    }
    pub fn zero() -> ModInt {
        ModInt(0)
    }
    pub fn one() -> ModInt {
        ModInt(1)
    }
    pub fn pow(self, mut n: u32) -> ModInt {
        let mut t = ModInt::one();
        let mut s = self;
        while n > 0 {
            if n & 1 == 1 {
                t = t * s;
            }
            s = s * s;
            n >>= 1;
        }
        t
    }
    pub fn inv(self) -> ModInt {
        self.pow(MOD - 2)
    }
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
#[allow(dead_code)]
struct Precalc {
    n: usize,
    inv: Vec<ModInt>,
    fact: Vec<ModInt>,
    ifact: Vec<ModInt>,
}

#[allow(dead_code)]
impl Precalc {
    pub fn new(n: usize) -> Precalc {
        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) {
            inv[i] = -inv[MOD as usize % i] * ModInt(MOD / i as u32);
            fact[i] = fact[i - 1] * ModInt(i as u32);
            ifact[i] = ifact[i - 1] * inv[i];
        }
        Precalc {
            n: n,
            inv: inv,
            fact: fact,
            ifact: ifact,
        }
    }
    pub fn fact(&self, n: usize) -> ModInt {
        self.fact[n]
    }
    pub fn ifact(&self, n: usize) -> ModInt {
        self.ifact[n]
    }
    pub fn comb(&self, n: usize, k: usize) -> ModInt {
        self.fact[n] * self.ifact[k] * self.ifact[n - k]
    }
    pub fn inv(&self, n: usize) -> ModInt {
        self.inv[n]
    }
}

// ---------- end Precalc ----------
// ---------- begin NTT ----------
fn ntt(f: &mut [ModInt]) {
    let n = f.len();
    assert!(n.count_ones() == 1);
    let len = n.trailing_zeros() as usize;
    for i in 1..(n - 1){
        let mut x = i;
        let mut j = 0;
        for _ in 0..len {
            j = (j << 1) | (x & 1);
            x >>= 1;
        }
        if i < j {
            f.swap(i, j);
        }
    }
    for k in 0..(n.trailing_zeros() as usize) {
        let m = 1 << k;
        let z = ModInt(3).pow((MOD - 1) >> (k + 1) as u32);
        for f in f.chunks_mut(2 * m) {
            let mut q = ModInt::one();
            let (x, y) = f.split_at_mut(m);
            for (x, y) in x.iter_mut().zip(y.iter_mut()) {
                let a = *x;
                let b = q * *y;
                *x = a + b;
                *y = a - b;
                q *= z;
            }
        }
    }
}

fn intt(f: &mut [ModInt]) {
    ntt(f);
    f[1..].reverse();
    let ik = ModInt(f.len() as u32).inv();
    for f in f.iter_mut() {
        *f *= ik;
    }
}

fn multiply(a: &[ModInt], b: &[ModInt]) -> Vec<ModInt> {
    let n = a.len() + b.len() - 1;
    let mut k = 1;
    while k < n {
        k *= 2;
    }
    assert!(k <= (1 << 23));
    let mut f = Vec::with_capacity(k);
    let mut g = Vec::with_capacity(k);
    f.extend_from_slice(a);
    f.resize(k, ModInt::zero());
    ntt(&mut f);
    g.extend_from_slice(b);
    g.resize(k, ModInt::zero());
    ntt(&mut g);
    for (f, g) in f.iter_mut().zip(g.iter()) {
        *f *= *g;
    }
    intt(&mut f);
    f.truncate(n);
    f
}

// ---------- end NTT ----------

fn calc(n: usize, p: ModInt, k: usize) -> Vec<ModInt> {
    if n == 1 {
        let mut ans = vec![ModInt::one()];
        for _ in 1..=k {
            ans.push(p);
        }
        ans
    } else if n % 2 == 1 {
        let mut dp = calc(n - 1, p, k);
        let mut v = calc(1, p, k);
        let pc = Precalc::new(2 * k);
        for i in 0..=k {
            dp[i] *= pc.ifact(i);
            v[i] *= pc.ifact(i);
        }
        let mut ans = multiply(&dp, &v);
        for i in 0..=k {
            ans[i] *= pc.fact(i);
        }
        ans.truncate(k + 1);
        ans
    } else {
        let mut dp = calc(n / 2, p, k);
        let pc = Precalc::new(2 * k);
        for i in 0..=k {
            dp[i] *= pc.ifact(i);
        }
        let mut ans = multiply(&dp, &dp);
        for i in 0..=k {
            ans[i] *= pc.fact(i);
        }
        ans.truncate(k + 1);
        ans
    }
}

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let mut it = s.trim().split_whitespace();
    let n: usize = it.next().unwrap().parse().unwrap();
    let m: u32 = it.next().unwrap().parse().unwrap();
    let k: usize = it.next().unwrap().parse().unwrap();
    let ans = calc(n, ModInt(m).inv(), k);
    println!("{}", ans[k]);
}

fn main() {
    run();
}


const N:usize = 505;

fn main() {

    let mut str = String::new();
	std::io::stdin().read_line(&mut str).expect("");
    let input :Vec<&str> = str.trim().split(" ").collect();
    let n = input[0].parse::<i32>().unwrap();
    let modn = input[1].parse::<i64>().unwrap();
    let mut dp0:Vec<i64> = vec![0;N*N];
    let mut dp1:Vec<i64> = vec![0;N*N];
    //let mut temp_dp0:Vec<i64> = vec![0;N*N];
    //let mut temp_dp1:Vec<i64> = vec![0;N*N];
    let shift = N*N/2;
    dp1[shift]=1;
    for _i in 1..n{
        let mut new_dp0 :Vec<i64> = vec![0;N*N];
        let mut new_dp1 :Vec<i64> = vec![0;N*N];

        //let mut new_dp0 = temp_dp0;
        //let mut new_dp1 = temp_dp1;
        //for j in 0..(N*N){
        //    new_dp0[j]=0;
        //    new_dp1[j]=0;
        ///}
        let i = _i as usize;
        for _j in 0..(N*N-1){
            let j = _j as usize;
            if dp1[j]==0 &&  dp0[j]==0{
                continue;
            }
            new_dp1[j-i] = (new_dp1[j-i]+dp1[j])%modn;
            new_dp1[j+1] = (new_dp1[j+1]-2*dp1[j] + modn + modn)%modn;
            new_dp1[j+i+2]=(new_dp1[j+i+2]+dp1[j])%modn;

            new_dp0[j+1] = (new_dp0[j+1]+dp1[j]*(i as i64))%modn;
            new_dp0[j] = (new_dp0[j]+(modn-dp1[j])*(i as i64+1))%modn;
            new_dp0[j-i] = (new_dp0[j-i]+dp1[j])%modn;

            let t:i64 = (i as i64 +1)*dp0[j]%modn;
            new_dp0[j] = (new_dp0[j]+t)%modn;
            new_dp0[j+1] = (new_dp0[j+1]+(modn-t)*2)%modn;
            new_dp0[j+2] = (new_dp0[j+2]+t)%modn;
        }
        //for j in shift-10..shift+11{
        //    println!("{} {}",j as i32-shift as i32,new_dp[j][0])
        //}
        for j in 0..(N*N-1){
            new_dp0[j+1]=(new_dp0[j+1]+new_dp0[j])%modn;
            new_dp1[j+1]=(new_dp1[j+1]+new_dp1[j])%modn;
        }
        for j in 0..(N*N-1){
            new_dp0[j+1]=(new_dp0[j+1]+new_dp0[j])%modn;
            new_dp1[j+1]=(new_dp1[j+1]+new_dp1[j])%modn;
        }
        //temp_dp0 = dp0;
        //temp_dp1 = dp1;
        dp0 = new_dp0;
        dp1 = new_dp1;
    }
    let mut ans:i64 = 0;
    for j in shift+1..N*N{
        ans = (ans + dp0[j])%modn;
    }
    println!("{}",ans);

}


use std::cmp::max;

fn main() {
    let mut input = io::Input::new();

    let (n, k): (usize, usize) = (input.next(), input.next());

    let mut v = [0i32; 200];
    for i in 0..n {
        v[i] = input.next();
    }

    let mut maximum = std::i32::MIN;
    for b in 0..n {
        let mut c = 0;
        for i in 0..n {
            if (b + i) % k != 0 {
                c += v[i];
            }
        }
        maximum = max(c.abs(), maximum);
    }

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

#[allow(unused)]
pub mod io {

    const BUFFER_SIZE: usize = 8192;

    use std::collections::VecDeque;
    use std::str::FromStr;
    use std::io;
    use std::io::Read;

    type AsciiStr = Vec<u8>;

    pub struct Input {
        token_buffer: VecDeque<String>,
        remaining: String,
    }

    impl Input {

        pub fn new() -> Input {
            Input {
                token_buffer: VecDeque::with_capacity(100),
                remaining: String::new(),
            }
        }

        pub fn next<T: FromStr>(&mut self) -> T
            where T::Err: ::std::fmt::Debug
        {
            self.fill_buffer();
            self.token_buffer.pop_front().unwrap().parse().unwrap()
        }

        pub fn next_ascii_string(&mut self) -> AsciiStr {
            self.fill_buffer();
            Vec::from(self.token_buffer.pop_front().unwrap().as_bytes())
        }

        fn fill_buffer(&mut self) {
            while self.token_buffer.is_empty() {
                let mut minibuffer = [0u8; BUFFER_SIZE];
                let size = io::stdin().read(&mut minibuffer[..]).unwrap();

                self.remaining += &String::from_utf8_lossy(&minibuffer[..size]);

                if self.remaining.trim().len() > 0 {
                    for token in self.remaining.trim().split_whitespace() {
                        self.token_buffer.push_back(String::from(token))
                    }

                    if size > 0 && ! self.remaining.ends_with(|c: char|char::is_ascii_whitespace(&c)) {
                        self.remaining = self.token_buffer.pop_back().unwrap();
                    } else {
                        self.remaining.clear();
                    }

                } else if size == 0 {
                    panic!("EOF");
                }
            }
        }
    }
}


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

    let mut it = input.split_whitespace();

    let n: u64 = it.next().unwrap().parse().unwrap();
    let k: u64 = it.next().unwrap().parse().unwrap();
    let a: u64 = it.next().unwrap().parse().unwrap();
    let b: u64 = it.next().unwrap().parse().unwrap();

    if k == 1 {
        let ans = (n - 1) * a;
        println!("{}", ans);
        return;
    }

    let mut x = n;

    let mut ans = 0;

    loop {
        let rem = x % k;
        if rem > 0 {
            x -= rem;
            ans += rem * a;
        } else {
            let q = x / k;
            let y = std::cmp::min((k - 1) * q * a, b);

            ans += y;
            x = q;
        }
        if x == 1 {
            println!("{}", ans);
            break;
        } else if x == 0 {
            println!("{}", ans - a);
            break;
        }
    }
}


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 mult(m1: &[[u64; 4]; 4], m2: &[[u64; 4]; 4]) -> [[u64; 4]; 4] {
    let mut result = [[0u64; 4]; 4];
    for i in 0..4 {
        for j in 0..4 {
            let mut sum = 0u64;
            for k in 0..4 {
                sum = (sum + m1[i][k] * m2[k][j]) % 1000000007;
            }
            result[i][j] = sum;
        }
    }
    result
}

fn exp(m: &[[u64; 4]; 4], mut e: u64) -> [[u64; 4]; 4] {
    let mut m2 = m.clone();
    let mut result = [[0u64; 4]; 4];
    result[0][0] = 1;
    result[1][1] = 1;
    result[2][2] = 1;
    result[3][3] = 1;
    while e > 0 {
        if e & 1 == 1 {
            result = mult(&result, &m2);
        }
        e >>= 1;
        m2 = mult(&m2, &m2);
    }
    result
}

fn _main() {
    let mut scan = Scan::new();
    let n: u64 = scan.next();
    let mat: [[u64; 4]; 4] = [[0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1], [1, 1, 1, 0]];
    let result = exp(&mat, n);
    println!("{}", result[0][0]);
}

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


#![allow(dead_code, unused_macros, unused_variables, clippy::many_single_char_names)]
use std::io::{stdin, stdout, StdinLock, StdoutLock, BufWriter, prelude::*};

macro_rules! spread {
    ($w: expr, $v: expr) => {
        for x in $v.iter() {
            write!($w, "{} ", x).unwrap();
        }
        writeln!($w).unwrap();
    };
}

struct Reader<'a> {
    stdin: StdinLock<'a>,
    last_pos: usize
}

macro_rules! read {
    ($s: ident) => {
        {
            // $s.stdin.consume($s.last_pos+1);

            let buf = $s.stdin.fill_buf().unwrap();
            let mut i = 0;

            while i < buf.len() {
                if buf[i] > 32 {
                    i += 1;
                } else {
                    break;
                }
            }

            $s.last_pos = i;
            &buf[..i]
        }
    };
}

macro_rules! read_int {
    ($s: ident, $t: ty) => {
        {
            let mut v: $t = 0;
            let num: &[u8] = read!($s);
            let l = $s.last_pos;

            assert!(num.len() == l); // hopefully remove bound checks

            if num[0] == b'-' {
                for d in &num[1..l] { // use release for wrapping op
                    v = v*10 - (*d as $t) + (b'0' as $t);
                }
            } else {
                for d in &num[..l] {
                    v = v*10 + (*d as $t) - (b'0' as $t);
                }
            }
            v
        }
    }
}

fn main() {
    let stdin = stdin();
    let stdout = stdout();
    solve(&mut Reader {stdin: stdin.lock(), last_pos: 0}, &mut BufWriter::new(stdout.lock()));
}

fn solve(r: &mut Reader, w: &mut BufWriter<StdoutLock>) {
    for c in read!(r) {
        let c = *c;
        let c = if (c as u8) < 97 {(c as u8) + 32} else {c};

        match c {
            b'a' | b'e' | b'i' | b'o' | b'u' | b'y' => {},
            _ => write!(w, ".{}", c as char).unwrap()
        }
    }
}


//spnauti-rust
#[allow(unused_macros)]
macro_rules! a {
    ($c: tt, $x: expr, $y: expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
use std::str::*;
use std::fmt::Debug;
struct WordReader<'a> { it : SplitAsciiWhitespace<'a>, }
#[allow(dead_code)]
impl<'a> WordReader<'a> {
    fn new<T: std::io::Read>(b: &mut String, mut r: T) -> WordReader {
        b.clear();
        r.read_to_string(b).unwrap();
        WordReader { it: b.split_ascii_whitespace() }
    }
    fn from_stdin(b: &mut String) -> WordReader {
        WordReader::new(b, std::io::stdin())
    }
    fn sl(&mut self) ->  &str { self.it.next().unwrap() }
    fn bs(&mut self) -> &[u8] { self.sl().as_bytes()    }
    fn s(&mut self) -> String { String::from(self.sl()) }
    fn i(&mut self) ->    i32 { self.p()                }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}

fn main() {
    let mut buffer = String::new();
    let mut input = WordReader::from_stdin(&mut buffer);

    use std::collections::HashMap;
    const K: &[u8] = b"qwertyuiopasdfghjkl;zxcvbnm,./";
    let ml = K.iter().zip(K.iter().skip(1)).collect::<HashMap<_,_>>();
    let mr = K.iter().skip(1).zip(K.iter()).collect::<HashMap<_,_>>();
    let c = input.bs()[0];
    let s = input.bs();
    let m = if c == b'L' { ml } else { mr };
    for x in s {
        print!("{}", *(m[x]) as char);
    }
}


use std::io;

fn read_u8() -> u8 {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s.trim().parse().unwrap()
}

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

fn main() {
    let n = read_u8();
    let n_sqrt = (n as f64).sqrt() as u8;
    let mut s = read_string();

    let mut divs: Vec<usize> = vec!();
    for i in 1..=n_sqrt {
        if n%i == 0 {
            divs.push(i as usize);
            if i*i != n {
                divs.push((n/i) as usize);
            }
        }
    }
    divs.sort();

    for i in divs.iter() {
        let t = s.split_off(*i);
        s = s.chars().rev().collect();
        s.push_str(&t);
    }

    println!("{}", s);

    return;
}


//spnauti-rust
use std::io::*;
use std::str::*;
use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::*;
#[allow(unused_imports)] use std::collections::*;

#[allow(unused_macros)]
macro_rules! a {
    ($c: tt, $x: expr, $y: expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
struct WordReader<'a> { it : SplitAsciiWhitespace<'a>, }
#[allow(dead_code)]
impl<'a> WordReader<'a> {
    fn new<T: Read>(b: &mut String, mut r: T) -> WordReader {
        b.clear();
        r.read_to_string(b).ok();
        WordReader { it: b.split_ascii_whitespace() }
    }
    fn from_stdin(b: &mut String) -> WordReader {
        WordReader::new(b, stdin())
    }
    fn sl(&mut self) ->  &str { self.it.next().unwrap() }
    fn bs(&mut self) -> &[u8] { self.sl().as_bytes()    }
    fn s(&mut self) -> String { String::from(self.sl()) }
    fn i(&mut self) ->    i32 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn vi(&mut self, n: usize) -> Vec<i32> {
        self.vp::<i32>(n)
    }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}

#[allow(dead_code)]
fn build_counting_hashmap<K: Eq + std::hash::Hash, T>(i: T) -> HashMap<K,usize>
    where T: Iterator<Item = K> {
    let mut m = HashMap::new();
    for k in i {
        let n = 1 + if let Some(&n) = m.get(&k) { n } else { 0 };
        m.insert(k, n);
    }
    m
}

const M: i64 = 1_000_000_007;

// fn mul(a: i64, b: i64) -> i64 { a * b % M }
fn add(a: i64, b: i64) -> i64 {
    let mut x = (a + b) % M;
    if x < 0 { x += M; }
    x
}

fn main() {
    let mut bin = String::new();
    let mut input = WordReader::from_stdin(&mut bin);

    let n = input.u();
    let tt = input.i();
    let mut t = vec![0; n];
    let mut g = vec![0; n];
    let mut z = vec![0; 4];
    for i in 0..n {
        t[i] = input.i();
        g[i] = input.i();
        z[g[i] as usize] += 1;
    }

    let f = |a,b| if a == b { 1 } else { 0 };

    let dp1 = {
        let mut dp = HashMap::<(i32,i32,i32,i32),i64>::new();
        dp.insert((0,0,0,0), 1);
        for i in 0..n {
            let mut d = HashMap::<(i32,i32,i32,i32),i64>::new();
            let x = t[i];
            let g = g[i];
            for (&(t,a,b,c), &y) in dp.iter() {
                let key = (t + x, a + f(g, 1), b + f(g, 2), c + f(g, 3));
                let res = *d.get(&key).unwrap_or(&0);
                d.insert(key, add(res, y));
            }
            for (key, y) in d.into_iter() {
                let res = *dp.get(&key).unwrap_or(&0);
                dp.insert(key, add(res, y));
            }
        }
        dp
    };
    //  for ((t,a,b,c),x) in dp1.iter() {
        //  println!("dp1    {} {} {} {} : {}", t,a,b,c,x);
    //  }

    let dp2 = {
        let mut dp2 = HashMap::<(i32,i32,i32),i64>::new();
        let mut dp = HashMap::<(i32,i32,i32,i32,i32),i64>::new();
        for g in 1..4 {
            dp.insert((0,0,0,0,g), 1);
        }
        for _i in 0..n {
            let mut d = HashMap::<(i32,i32,i32,i32,i32),i64>::new();
            for ((h,a,b,c,l), y) in dp.into_iter() {
                let mut p = [0,a,b,c];
                for g in 1..4 {
                    if (h == 0 && g != l) || (h > 0 && g == l) {
                        continue;
                    }
                    p[g as usize] += 1;
                    if (1..4).all(|i| p[i] <= z[i]) {
                        let key = (h + 1, p[1], p[2], p[3], g);
                        let res = add(y * p[g as usize] as i64, *d.get(&key).unwrap_or(&0));
                        d.insert(key, res);
                    }
                    p[g as usize] -= 1;
                }
            }

            for (&(_,a,b,c,_),&x) in d.iter() {
                let key = (a,b,c);
                let res = *dp2.get(&key).unwrap_or(&0);
                dp2.insert(key, add(res, x));
            }
            dp = d;
            // println!("\n-----------------------: {}", _i);
            // for ((h,a,b,c,g),x) in dp.iter() {
            // println!("{} {} {} {} {}: {}", h,a,b,c,g,x);
            // }
        }
        dp2
    };
    //  for ((a,b,c),x) in dp2.iter() {
        //  println!("dp2    {} {} {} : {}", a,b,c,x);
    //  }

    let mut sol: i64 = 0;
    for a in 0..z[1]+1 {
        let a = a as i32;
        for b in 0..z[2]+1 {
            let b = b as i32;
            for c in 0..z[3]+1 {
                let c = c as i32;
                let x = dp1.get(&(tt,a,b,c)).unwrap_or(&0);
                let y = dp2.get(&(a,b,c)).unwrap_or(&0);
                sol = add(sol, x * y);
            }
        }
    }
    println!("{}", sol);
}


use std::io;

fn main() {
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    let read_in = buf.split_whitespace().map(|c| c.trim().parse::<usize>().unwrap()).collect::<Vec<_>>();
    let n = read_in[0];
//    let m = read_in[1];

    buf.clear();
    io::stdin().read_line(&mut buf).unwrap();
    let mut nums = buf.split_whitespace().map(|c| c.trim().parse::<usize>().unwrap()).collect::<Vec<_>>();
    nums.sort();

    let ret = nums.windows(n as usize).fold(None, |acc: Option<usize>, v| {
        let m = v[n - 1] - v[0];
        let r = match acc {
            None => m,
            Some(acc_n)if m > acc_n => acc_n,
            _ => m,
        };
        Some(r)
    });
    println!("{}", ret.unwrap());
}


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

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

    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 mut line = String::new();
            std::io::stdin().read_line(&mut line).expect("Fail to read");
            self.buffer = line.split_whitespace().map(String::from).collect();
        }
    }

}

fn _main() {
    let mut scan = Scan::new();
    let n: isize = scan.next();
    let m: isize = scan.next();
    let mut twomoves: isize = n / 2;
    let mut onemoves: isize = n % 2;
    for _ in 0..m {
        if (twomoves + onemoves ) % m == 0 {
            println!("{}", twomoves+onemoves);
            return;
        }
        if twomoves > 0 {
            twomoves -= 1;
            onemoves += 2;
        }
    }
    println!("-1");
}

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


//spnauti-rust
#[allow(unused_macros)]
macro_rules! a {
    ($c: tt, $x: expr, $y: expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
use std::io::*;
use std::str::*;
use std::fmt::Debug;
struct WordReader<'a> { it : SplitAsciiWhitespace<'a>, }
#[allow(dead_code)]
impl<'a> WordReader<'a> {
    fn new<T: Read>(b: &mut String, mut r: T) -> WordReader {
        b.clear();
        r.read_to_string(b).unwrap();
        WordReader { it: b.split_ascii_whitespace() }
    }
    fn from_stdin(b: &mut String) -> WordReader {
        WordReader::new(b, stdin())
    }
    fn sl(&mut self) ->  &str { self.it.next().unwrap() }
    fn bs(&mut self) -> &[u8] { self.sl().as_bytes()    }
    fn s(&mut self) -> String { String::from(self.sl()) }
    fn i(&mut self) ->    i32 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn vi(&mut self, n: usize) -> Vec<i32> {
        self.vp::<i32>(n)
    }
    fn p<T: FromStr>(&mut self) -> T where T::Err: Debug {
        self.sl().parse::<T>().unwrap()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}

fn main() {
    let mut bin = String::new();
    let mut input = WordReader::from_stdin(&mut bin);

    let sum = (0..2).fold(0, |s,_| s + input.i().abs());
    let s = input.i();
    if s >= sum && (s - sum) % 2 == 0 {
        println!("Yes");
    } else {
        println!("No");
    }
}


// 991E
use std::io;

fn main() {
    let mut a = String::new();
    io::stdin().read_line(&mut a).unwrap();
    let a = a.trim();

    let mut counts = [0u64; 10];

    for c in a.chars() {
        counts[c.to_digit(10).unwrap() as usize] += 1;
    }

    let mut fa = [0u64; 30];

    let with_zero = count(&mut counts, 0, &mut fa);
    let mut correct = with_zero;
    if counts[0] > 0 {
        counts[0] -= 1;
        correct -= count(&mut counts, 0, &mut fa);
        if counts[0] > 0 {
            counts[0] = 0;
            correct -= count(&mut counts, 0, &mut fa);
        }
    }
    println!("{}", correct);
}

fn factorial(n: u64, fa: &mut [u64]) -> u64 {
    if n == 0 {
        fa[n as usize] = 1;
    } else if fa[n as usize] == 0 {
        fa[n as usize] = factorial(n - 1, fa) * n;
    }
    return fa[n as usize];
}

fn count(counts: &mut [u64], change_here: usize, fa: &mut [u64]) -> u64 {
    if change_here == 10 {
        // All numbers are fixed now
        let numerator = factorial(counts.iter().sum(), fa);
        let mut denominator = 1;
        for c in counts {
            denominator *= factorial(*c, fa);
        }
        return numerator / denominator;
    }

    if counts[change_here] == 0 {
        return count(counts, change_here + 1, fa);
    }

    let mut add = 0;
    for i in 1..(counts[change_here] + 1) {
        counts[change_here] = i;
        add += count(counts, change_here + 1, fa);
    }
    return add;
}


use std::io::{self, Stdin};
use std::str::{self, FromStr};
use std::error::Error;
use std::thread;
use std::cmp::*;
fn exec() {
    let mut sc = Scanner::new();
    let _: usize = sc.ne();
    let k: usize = sc.ne();
    let a = sc.ne::<String>().into_bytes();
    let start = a.iter().position(|&x| x == b'G').unwrap();
    let goal = a.iter().position(|&x| x == b'T').unwrap();
    let s = min(start, goal);
    let g = max(start, goal);
    let mut ok = true;
    if (g - s) % k != 0 {
        println!("NO");
        std::process::exit(0);
    }
    let mut cur = s;
    while cur != g {
        if a[cur] == b'#' {
            ok = false;
        }
        cur += k;
    }
    println!("{}", if ok { "YES" } else { "NO" });
}

fn main() {
    const DEFAULT_STACK: usize = 16 * 1024 * 1024;
    let builder = thread::Builder::new();
    let th = builder.stack_size(DEFAULT_STACK);
    let handle = th.spawn(|| { exec(); }).unwrap();
    let _ = handle.join();
}

#[allow(dead_code)]
struct Scanner {
    stdin: Stdin,
    id: usize,
    buf: Vec<u8>,
}

#[allow(dead_code)]
impl Scanner {
    fn new() -> Scanner {
        Scanner {
            stdin: io::stdin(),
            id: 0,
            buf: Vec::new(),
        }
    }
    fn next_line(&mut self) -> Option<String> {
        let mut res = String::new();
        match self.stdin.read_line(&mut res) {
            Ok(0) => return None,
            Ok(_) => Some(res),
            Err(why) => panic!("error in read_line: {}", why.description()),
        }
    }
    fn next<T: FromStr>(&mut self) -> Option<T> {
        while self.buf.len() == 0 {
            self.buf = match self.next_line() {
                Some(r) => {
                    self.id = 0;
                    r.trim().as_bytes().to_owned()
                }
                None => return None,
            };
        }
        let l = self.id;
        assert!(self.buf[l] != b' ');
        let n = self.buf.len();
        let mut r = l;
        while r < n && self.buf[r] != b' ' {
            r += 1;
        }
        let res = match str::from_utf8(&self.buf[l..r]).ok().unwrap().parse::<T>() {
            Ok(s) => Some(s),
            Err(_) => panic!("parse error"),
        };
        while r < n && self.buf[r] == b' ' {
            r += 1;
        }
        if r == n {
            self.buf.clear();
        } else {
            self.id = r;
        }
        res
    }
    fn ne<T: FromStr>(&mut self) -> T {
        self.next::<T>().unwrap()
    }
}


use std::io::{Read,stdin};

const M: i128 = 1_000_000_007;

fn main() {
    let mut buf = String::new();
    stdin().read_to_string(&mut buf).unwrap();
    let mut tok = buf.split_whitespace();
    let mut get = || tok.next().unwrap();
    macro_rules! get {
        ($t:ty) => (get().parse::<$t>().unwrap());
        () => (get!(i128));
    }

    let x = get!();
    let n = get!();

    let mut ps = vec![];
    let mut y = x;
    for i in 2 ..= x {
        if i * i > y {
            break;
        }
        if y % i != 0 {
            continue;
        }
        ps.push(i);
        while y % i == 0 {
            y /= i;
        }
    }
    if y > 1 {
        ps.push(y);
    }
    let mut ans = 1;
    for &p in ps.iter() {
        let mut es = vec![];
        let mut e = p;
        while e <= n {
            es.push(e);
            e *= p;
        }
        let mut t = 0;
        while let Some(e) = es.pop() {
            let c = n / e - t;
            ans = ans * pow(e, c) % M;
            t = n / e;
        }
    }
    println!("{}", ans);
}

fn pow(a: i128, b: i128) -> i128 {
    if b == 0 {
        1
    } else if b % 2 == 0 {
        pow(a * a % M, b / 2)
    } else {
        a * pow(a, b - 1) % M
    }
}


macro_rules! parse_line {
    ($t: ty) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let a_str = a_str.trim();
        a_str.parse::<$t>().expect("parse error")
    });
    ($($t: ty),+) => ({
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        let mut a_iter = a_str.split_whitespace();
        (
            $(
            a_iter.next().unwrap().parse::<$t>().expect("parse error"),
            )+
        )
    })
}

#[allow(unused_macros)]
macro_rules! parse_line_to_vec {
    ($t: ty) => {{
        let mut a_str = String::new();
        std::io::stdin().read_line(&mut a_str).expect("read error");
        (a_str
            .split_whitespace()
            .map(|x| x.parse::<$t>().unwrap())
            .collect::<Vec<$t>>())
    }};
}

use std::io::Write;

fn solve(writer: &mut std::io::BufWriter<std::io::Stdout>) {
    let ss: Vec<u8> = parse_line!(String).bytes().collect();
    let b = ss.iter().filter(|c| **c == b'B').count() as u64;
    let s = ss.iter().filter(|c| **c == b'S').count() as u64;
    let c = ss.iter().filter(|c| **c == b'C').count() as u64;
    let (nb, ns, nc) = parse_line!(u64, u64, u64);
    let (pb, ps, pc) = parse_line!(u64, u64, u64);
    let r = parse_line!(u64);
    let mut l = 0;
    let mut u = 10000000000000;
    while u - l > 1 {
        let m = (l + u) / 2;
        let need =
            if b * m <= nb {0} else {pb * (b * m - nb)} +
            if s * m <= ns {0} else {ps * (s * m - ns)} +
            if c * m <= nc {0} else {pc * (c * m - nc)};
        if need <= r {
            l = m;
        }else{
            u = m;
        }
    }
    writeln!(writer, "{}", l).unwrap();
}

fn main() {
    let mut writer = std::io::BufWriter::new(std::io::stdout());
    let tests = 1; // parse_line!(usize);
    for _ in 0..tests {
        solve(&mut writer);
    }
}


use std::io::{self, Read};

fn main() -> io::Result<()> {
    let mut buf = String::new();
    io::stdin().read_to_string(&mut buf)?;
    let v: Vec<u32> = buf
        .split_ascii_whitespace()
        .map(|x| x.parse().unwrap())
        .collect();
    let (k, mut l) = (v[0], v[1]);

    let mut ans = -1;
    while l % k == 0 {
        l /= k;
        ans += 1;
    }

    if l == 1 {
        println!("YES");
        println!("{}", ans);
    } else {
        println!("NO");
    }

    Ok(())
}


use std::io;

fn main() {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).expect("failed to read input");
    let n: u32 = buffer.trim().parse().expect("invalid input");

    println!("{}", 2 * n * (n - 1) + 1);
}


use std::io::{stdin, BufRead, BufReader};
use std::vec::Vec;
use std::process;

const MAX_DIFF: i32 = 90;

fn digit_sum(n: i32) -> i32 {
    let mut result = 0;
    let mut t = n;
    while t > 0 {
        result = result + (t % 10);
        t = t / 10;
    }
    result
}

fn solve(n: i32) -> Vec<i32> {
    let mut result: Vec<i32> = Vec::new();
    for x in 1..MAX_DIFF {
        let t = n - x;
        if digit_sum(t) == x {
            result.push(t);
        }
    }
    result
}

#[allow(non_snake_case)]
#[allow(unused_variables)]
fn main() {
    let mut reader = BufReader::new(stdin());
    let mut s = String::new();
    reader.read_line(&mut s).unwrap();
    let N = s.trim_right().parse::<i32>().unwrap();
    let mut solved = solve(N);
    let mut result = solved.as_mut_slice();
    result.sort();
    println!("{}", result.len());
    if result.len() == 0 {
        process::exit(0);
    }
    s.clear();
    for i in 0..result.len() {
        s.push_str(result[i].to_string().as_str());
        if i != result.len() - 1 {
            s.push(' ');
        }
    }
    println!("{}", s);
}