#![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, 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; while a != 0 { swap(&mut a, &mut b); a %= b; }
                    b
                }
                #[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, mut b: Self) -> Self {
                    let mut a = self; while a != 0 { swap(&mut a, &mut b); a %= b; }
                    b.abs()
                }
                #[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;
    }

    #[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(mul_mod_u32(self.val, rhs.into().val, Self::modulus()))
        }
    }
    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 }
            }
            pub type $mint = ModIntBase<$name>;
        }
    }

    macro_rules! dynamic_modulus {
        ($mint: ident, $name: ident, $modulus: ident) => {
            static $modulus: crate::Unsync<Cell<u32>> = crate::Unsync(Cell::new(0));
            #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
            pub enum $name {}
            impl Modulus for $name {
                fn get_modulus() -> u32 { $modulus.0.get() }
            }
            impl $name {
                pub fn set_modulus(val: u32) { $modulus.0.set(val) }
            }
            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;

fn mod_factorials(maxn: usize) -> Vec<ModInt> {
    let mut res = vec![ModInt::default(); maxn+1];
    res[0] = 1.into();
    for i in 1..=maxn {
        res[i] = res[i-1] * i
    }
    return res;
}

struct ModCombinatorics {
    factorials: Vec<ModInt>,
    inv_factorials: Vec<ModInt>
}
#[allow(non_snake_case)]
impl ModCombinatorics {
    fn new(maxn: usize) -> Self {
        let factorials = mod_factorials(maxn);
        let mut inv = vec![ModInt::default(); maxn+1];
        inv[maxn] = factorials[maxn].inv();
        for i in (1..=maxn).rev() {
            inv[i-1] = inv[i] * i;
        }
        Self { factorials, inv_factorials: inv }
    }
    #[inline]
    fn factorial(&self, n: usize) -> ModInt { self.factorials[n] }
    #[inline]
    fn inv_factorial(&self, n: usize) -> ModInt { self.inv_factorials[n] }
    fn P(&self, n: usize, k: usize) -> ModInt {
        if k > n { ModInt::raw(0) } else { self.factorial(n) * self.inv_factorial(n-k) }
    }
    fn C(&self, n: usize, k: usize) -> ModInt {
        if k > n { ModInt::raw(0) } else { self.factorial(n) * self.inv_factorial(k) * self.inv_factorial(n-k) }
    }

    // multi-choose, be sure to adjust maxn accordingly
    fn M(&self, n: usize, k: usize) -> ModInt {
        if k == 0 { 1.into() } else { self.C(n + k - 1, k) }
    }
}

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; }
        }
    }

    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);
        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);
        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)]
    }
}

struct FactorMap {
    map: Vec<u32>
}
impl FactorMap {
    pub fn new(limit: usize) -> FactorMap {
        let limit = limit + 1;
        let mut map = vec![0; limit >> 1];
        for p in (3..limit).step_by(2) {
            if map[p >> 1] != 0 { continue; }
            let sq = p * p;
            if sq >= limit { break; }
            for i in (sq..limit).step_by(p*2) {
                if map[i >> 1] == 0 { map[i >> 1] = p as u32; }
            }
        }

        FactorMap { map }
    }

    pub fn least_prime_factor(&self, n: usize) -> usize {
        if n & 1 == 0 { return 2; }
        let p = self.map[n >> 1] as usize;
        if p == 0 { n } else { p }
    }

    pub fn factorize(&self, n: usize) -> FactorIterator {
        FactorIterator { fm: self, n }
    }

    pub fn is_prime(&self, n: usize) -> bool { n > 1 && self.least_prime_factor(n) == n }

    /// lists divisors, unsorted
    pub fn divisors(&self, mut n: usize) -> Vec<usize> {
        let mut res = vec![1];

        while n > 1 {
            let p = self.least_prime_factor(n);
            let mut x = 0;
            loop {
                n /= p;
                x += 1;
                if p != self.least_prime_factor(n) { break; }
            }
            for i in 0..res.len() {
                let mut a = res[i];
                for _ in 0..x {
                    a *= p;
                    res.push(a);
                }
            }
        }

        res
    }

    pub fn new_with_mobius(limit: usize) -> (FactorMap, Vec<i8>) {
        let fm = Self::new(limit);
        let mut mu = vec![1i8; limit + 1];
        mu[0] = 0;

        for i in 2..=limit {
            let p = fm.least_prime_factor(i);
            mu[i] = if p == fm.least_prime_factor(i/p) { 0 } else { -mu[i/p] };
        }

        (fm, mu)
    }
}
struct FactorIterator<'a> {
    fm: &'a FactorMap,
    n: usize
}
impl Iterator for FactorIterator<'_> {
    type Item = usize;

    fn next(&mut self) -> Option<Self::Item> {
        if self.n <= 1 { return None; }
        let p = self.fm.least_prime_factor(self.n);
        self.n /= p;
        Some(p)
    }

    fn size_hint(&self) -> (usize, Option<usize>) { (0, Some(32)) }
}

#[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 mut ans = mi(0);
        if min(n, k) == 1 { ans = mi(1); }
        else {
            let mc = ModCombinatorics::new(min(n, k));
            let ff = ModFft::new(min(n, k) * 2);
            let mu = FactorMap::new_with_mobius(n).1;

            let mut m = 0usize;
            let mut A = mi(0);
            let P = veci!(min(n, k)+1, j: if j & 1 == 1 { -mc.inv_factorial(j) } else { mc.inv_factorial(j) });

            for i in 1..=n {
                if mu[i] == 0 { continue; }
                let mn = n.div_ceil(i);
                if m != mn {
                    m = mn;
                    let l = min(m, k);
                    let Q = veci!(l+1, j: mi(j).pow(m as _) * mc.inv_factorial(j));
                    let R = ff.mul(&P[..=l], &Q);
                    A = R[2..=l].iter().sum();
                }
                if mu[i] == 1 { ans += A; } else { ans -= A; }
            }
        }

        println!(ans);
    }

    out_flush();
}


use std::io;
fn main(){
    let mut line=String::new();
    io::stdin().read_line(&mut line).expect("Die");
    let arr:Vec<i32> = line.split(" ").map(|x| x.trim().parse().expect("Int")).collect();
    let (mut i,mut j):(i32,i32)=(arr[1],arr[3]);
    let mut ans=false;
    loop{
        i+=1;
        if i>arr[0]{
            i=1;
        }

        j-=1;
        if j<=0{
            j=arr[0];
        }
        if i==j{
            ans=true;
            break;
        }
        else if i==arr[2] || j==arr[4]{
            break;
        }
    }

    if ans{
        println!("YES")
    }
    else{
        println!("NO")
    }
}


use std::cmp::min;

macro_rules! read_line {
    ($v:ident) => {
        let mut temp = String::new();
        std::io::stdin().read_line(&mut temp).unwrap();
        let $v = temp;
    };
    (var, $t:ty, $($v:ident), *) => {
        read_line!(input_line);
        let mut iter = parse_token!($t, input_line);
        $(
            let $v = iter.next().unwrap();
        )*
    };
    (vec, $t:ty, $v:ident) => {
        read_line!(input_line);
        let iter = parse_token!($t, input_line);
        let $v: Vec<$t> = iter.collect();
    };
    ($($v:ident; $t:ty), *) => {
        read_line!(input_line);
        let mut iter = input_line.split_whitespace();
        $(
            let $v: $t = iter.next().unwrap().parse().unwrap();
        )*
    };
}

macro_rules! parse_token {
    ($t:ty, $e:expr) => {
        $e.split_whitespace().map(|x| x.parse::<$t>().unwrap());
    };
}

fn main() {
    read_line!(k2;u32, k3;u32, k5;u32, k6;u32);
    let max_256 = min(min(k2, k5), k6);
    let k2_left = k2 - max_256;
    let max_32 = min(k2_left, k3);
    println!("{}", max_32 * 32 + max_256 * 256);
}


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

    let mut it = input.split_whitespace();

    let p: u64 = it.next().unwrap().parse().unwrap();
    let y: u64 = it.next().unwrap().parse().unwrap();

    let ans = (p + 1..y + 1).rev().find(|&i| {
        let k = std::cmp::min(p, (y as f64).sqrt().floor() as u64);
        (2..k + 1).all(|j| i % j != 0)
    });

    match ans {
        Some(ans) => println!("{}", ans),
        None => println!("-1"),
    }
}


#[allow(unused_imports)]
use std::io::{stdin, Read, StdinLock};
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::str::FromStr;
#[allow(unused_imports)]
use std::collections::{HashSet, HashMap, BinaryHeap};
#[allow(unused_imports)]
use std::vec::Vec;

#[allow(dead_code)]
const INF: i32 = 1000_000_000;
#[allow(dead_code)]
const INFLL: i64 = 1000_000_000_000_000_000;
#[allow(dead_code)]
const EPS: f64 = 1.0e-10;
#[allow(dead_code)]
const MOD: i32 = 1000_000_007;

struct Scanner<'a> {
    cin: StdinLock<'a>,
}

impl<'a> Scanner<'a> {
    #[allow(dead_code)]
    fn new(cin: StdinLock<'a>) -> Scanner<'a> {
        Scanner {cin: cin}
    }

    #[allow(dead_code)]
    fn read1<T: FromStr>(&mut self) -> Option<T> {
        let token = self.cin.by_ref().bytes().map(|c| c.unwrap() as char)
                    .skip_while(|c| c.is_whitespace())
                    .take_while(|c| !c.is_whitespace())
                    .collect::<String>();
        token.parse::<T>().ok()
    }

    #[allow(dead_code)]
    fn read<T: FromStr>(&mut self) -> T {
        self.read1().unwrap()
    }
}

fn main() {
    let cin = stdin();
    let cin = cin.lock();
    let mut sc = Scanner::new(cin);
    let mut s1: Vec<char> = Vec::new();
    for _i in 0..2 {
        let s: String = sc.read();
        let mut s: Vec<char> = s.chars().collect();
        s1.append(&mut s);
    }
    let s2: String = sc.read();
    let mut s2: Vec<char> = s2.chars().collect();
    s1.sort(); s2.sort();
    if s1.len() != s2.len() {
        println!("NO");
    } else {
        let mut ok = true;
        for i in 0..s1.len() {
            ok &= s1[i] == s2[i];
        }
        if ok {
            println!("YES");
        } else {
            println!("NO");
        }
    }
}


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

use std::io::prelude::*;
use std::io::BufReader;
use std::cmp::{max, min};

fn get_line() -> String {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input
}

fn get_vec<T>() -> Vec<T>
where T: FromStr,
      <T as FromStr>::Err: std::fmt::Debug,
{
    get_line().split_whitespace().map(|k| k.parse().unwrap()).collect()
}

const N: i64 = 998_244_353;

fn extended_euclid(a: i64, b: i64) -> (i64, i64, i64) {
    if b == 0 {
        (a, 1, 0)
    } else {
        let (d0, x0, y0) = extended_euclid(b, a % b);
        (d0, y0, x0 - a / b * y0)
    }
}

fn main() {
    let (a, b, c) = {
        let input = get_line();
        let mut it = input.split_whitespace().map(|k| k.parse::<i64>().unwrap());
        (
            it.next().unwrap(),
            it.next().unwrap(),
            it.next().unwrap(),
            )
    };

    let mut s = [a, b, c];
    s.sort();
    let (a, b, c) = (s[0], s[1], s[2]);

    // Nombres d'arêtes possibles :
    // a * b + b * c + c * a
    // Nombre de combinaisons possibles :
    // 2^nap

    let modulo = |a, b| {
        if a % b < 0 {
            a % b + b
        } else {
            a % b
        }
    };

    let inv = |x| {
        modulo(extended_euclid(x, N).1, N)
    };

    let fact: Vec<i64> = (0..5001).scan(1, |state, x| {
        if x != 0 {
            *state = x * *state % N;
        }
        Some(*state)
    }).collect();

    let bc = |k, n| {
        fact[n as usize] * inv(fact[(n - k) as usize]) % N * inv(fact[k as usize]) % N
    };

    let np = |k, n| {
        fact[n as usize] * inv(fact[(n - k) as usize]) % N
    };

    let foo = |a, b| {
        (0..a + 1).map(|i| bc(i, a) * np(i, b) % N).fold(0, |acc, x| (acc + x) % N)
    };

    let ans = foo(a, b) * foo(a, c) % N * foo(b, c) % N;
    println!("{}", ans);
}


use std::io::Read;

fn input(read_file: bool) -> String {
    if read_file {
        let mut file = std::fs::File::open("sample.txt").unwrap();
        let mut buf = String::new();
        file.read_to_string(&mut buf).unwrap();
        buf
    } else {
        let mut buf = String::new();
        std::io::stdin().read_to_string(&mut buf).unwrap();
        buf.trim_end().to_owned()
    }
}

fn solve(ws: &mut std::str::SplitWhitespace) {
    let r: f64 = ws.next().unwrap().parse().unwrap();
    let x: f64 = ws.next().unwrap().parse().unwrap();
    let y: f64 = ws.next().unwrap().parse().unwrap();
    let xd: f64 = ws.next().unwrap().parse().unwrap();
    let yd: f64 = ws.next().unwrap().parse().unwrap();

    let dist = ((xd - x).powi(2) + (yd - y).powi(2)).sqrt();
    let r2 = 2.0 * r;

    println!("{}", (dist / r2).ceil() as u32);
}

fn main() {
    const READ_FROM_FILE: bool = false;

    let s = input(READ_FROM_FILE);
    let mut ws = s.split_whitespace();

    solve(&mut ws);
}


//#[derive(Debug)]
use std::io::stdin;
//use std::char::from_digit;
//use std::collections::HashMap;

#[derive(Default)]
struct Scanner {
    buffer: Vec<String>
}
impl Scanner {
    fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

fn main() {
    //let mut ans= Vec::new();
    let mut scan = Scanner::default();
    //let mut mas  = Vec::new();
    let mut ans:i32 = 1;

    let mut n= scan.next::<i32>();
    //let dig: Vec<usize> = (1..9).map(|_| scan.next()).collect();
    while n>=10
    {
        ans+=10-n%10;
        n/=10;n+=1;
        while n%10==0 {n/=10;}
    }

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


#![allow(unused_imports)]
#![allow(non_snake_case)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn count(s: &Vec<char>) -> i64 {
    let n = s.len();
    let mut lb_count = vec![0; n];
    lb_count[0] = if s[0] == '(' { 1 } else { 0 };
    for i in 1..n {
        lb_count[i] = lb_count[i - 1];
        if s[i] == '(' {
            lb_count[i] += 1;
        }
    }
    let lb_count = lb_count;
    let mut rb_count = vec![0; n];
    rb_count[0] = if s[0] == ')' { 1 } else { 0 };
    for i in 1..n {
        rb_count[i] = rb_count[i - 1];
        if s[i] == ')' {
            rb_count[i] += 1;
        }
    }

    // scan
    let mut min_depth = n as i64;
    let mut cur_depth = 0;
    for i in 0..n {
        if s[i] == '(' {
            cur_depth += 1;
        } else {
            cur_depth -= 1;
        }
        if cur_depth < min_depth {
            min_depth = cur_depth;
        }
    }

    let mut ans = 0;
    let mut cur_depth = 0;
    for i in 0..n {
        if s[i] == '(' {
            cur_depth += 1;
        } else {
            cur_depth -= 1;
        }
        if cur_depth == min_depth {
            ans += 1;
        }
    }
    ans
}

fn main() {
    let n = read::<usize>();
    let s = read::<String>().chars().collect::<Vec<_>>();

    let mut lb_count = vec![0; n];
    lb_count[0] = if s[0] == '(' { 1 } else { 0 };
    for i in 1..n {
        lb_count[i] = lb_count[i - 1];
        if s[i] == '(' {
            lb_count[i] += 1;
        }
    }
    let lb_count = lb_count;
    let mut rb_count = vec![0; n];
    rb_count[0] = if s[0] == ')' { 1 } else { 0 };
    for i in 1..n {
        rb_count[i] = rb_count[i - 1];
        if s[i] == ')' {
            rb_count[i] += 1;
        }
    }
    if lb_count[n - 1] != rb_count[n - 1] {
        println!("0");
        println!("1 1");
        return;
    }

    let mut ans = count(&s);
    let mut ans_pair = (1, 1);
    for i in 0..n {
        for j in i + 1..n {
            let mut s_clone = s.clone();
            let temp = s_clone[i];
            s_clone[i] = s_clone[j];
            s_clone[j] = temp;
            let temp = count(&s_clone);
            if temp > ans {
                ans = temp;
                ans_pair = (i + 1, j + 1);
            }
        }
    }
    println!("{}", ans);
    println!("{0} {1}", ans_pair.0, ans_pair.1);
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}


use std::io;

fn main()
{
   let mut n =String::new();
   let mut opt = String::new();
   io::stdin().read_line(&mut n);
   io::stdin().read_line(&mut opt);

    let n:usize = n.trim().parse().expect("");
    let mut ans = 0;
   for i in 0..n
   {
       if opt.chars().nth(i) == Some('-')
       {
           ans-=1;
           if ans<0
           {
                ans=0;
           }
       }
       else
       {
           ans+=1;
       }
   }

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


#[allow(unused_imports)]
use std::cmp::{max,min};

type GenError = Box<dyn std::error::Error>;
type GenResult<T> = Result<T, GenError>;

struct Reader {

}

impl Reader{
    #[allow(unused)]
    fn read_string() -> GenResult<String> {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string)?;
        Ok(string.trim().to_string())
    }

    #[allow(unused)]
    fn read_tokens() -> GenResult<Vec::<String>> {
        let mut string: String = String::new();
        std::io::stdin().read_line(&mut string)?;
        let mut v = Vec::new();
        for value in string.split_whitespace() {
            v.push(value.to_string());
        }
        Ok(v)
    }
}

fn main() {

    let tokens = Reader::read_tokens().unwrap();
    let n: i32 = tokens[0].parse().unwrap();
    let m: i32 = tokens[1].parse().unwrap();
    let k: i32 = tokens[2].parse().unwrap();

    let mut ans = 1000000;
    let mut index = 1;
    for value in Reader::read_tokens().unwrap() {
        let value : i32 = value.parse().unwrap();
        if value > 0 && value <= k {
            if 10 * (index - m).abs() < ans {
                ans = 10 * (index - m).abs();
            }
        }
        index += 1;
    }
    println!("{}", ans);
}


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

fn main() {
    let mut buffer = String::new();
    let stdin = io::stdin();
    let mut handle = stdin.lock();
    handle.read_to_string(&mut buffer).unwrap();

    let arr : Vec<_> = buffer.split_whitespace().collect();

    let n = arr[0].parse::<usize>().unwrap();
    let m = arr[1].parse::<usize>().unwrap();

    let mut orig = vec![ vec![0; m]; n ];

    for (k1,i) in arr[2..].iter().enumerate() {
        for (k2,j) in i.chars().enumerate() {
            if j == '#' {
                orig[k1][k2] = 1;
            }
        }
    }

    let mut v = vec![ vec![0; m]; n ];
    for i in 1..n-1 {
        for j in 1..m-1 {
            let neighbours = [ (-1,0), (0,-1), (1,0), (0,1), (-1,-1), (1,-1), (-1,1), (1,1) ];
            let mut count = 0;
            for (x,y) in neighbours.iter() {
                let (x2,y2) = ((i as isize+x) as usize ,(j as isize +y) as usize);
                if orig[x2][y2] == 1 {
                    count += 1;
                }
            }
            if count == 8 {
                for (x,y) in neighbours.iter() {
                    let (x2,y2) = ((i as isize+x) as usize ,(j as isize +y) as usize);
                    v[x2][y2] = 1;
                }
            }
        }
    }

    // println!("{:?}",v);

    let mut feasible = true;
    'outer: for i in 0..n {
        for j in 0..m {
            if v[i][j] != orig[i][j] {
                feasible = false;
                break 'outer;
            }
        }
    }

    if feasible {
        println!("YES");
    } else {
        println!("NO");
    }
}


use std::io;

fn solve() -> Vec<String> {
    let mut input = "".split_ascii_whitespace();
    let mut read = || loop {
        if let Some(word) = input.next() {
            break word;
        }
        input = {
            let mut input = "".to_owned();
            io::stdin().read_line(&mut input).unwrap();
            if input.is_empty() {
                panic!("reached EOF");
            }
            Box::leak(input.into_boxed_str()).split_ascii_whitespace()
        };
    };
    macro_rules! read(($ty:ty) => (read().parse::<$ty>().unwrap()));

    let mut rr = vec!["".to_string(); 0];

    let t = 1;
    for _ in 0..t {
        let n = read!(usize);
        let ca = read!(String).chars().collect::<Vec<char>>();

        let mut a = vec![' '; n];
        let mut b = vec![' '; n];
        for i in 0..n {
            a[i] = ca[i];
            b[i] = ca[i + n];
        }

        a.sort();
        b.sort();
        let mut t = 0;
        for i in 0..n {
            if a[i] < b[i] {
                t |= 1;
            } else if a[i] > b[i] {
                t |= 2;
            } else {
                t |= 4;
            }
        }

        if t < 3 {
            rr.push("YES".to_string());
        } else {
            rr.push("NO".to_string());
        }
    }

    rr
}

#[allow(dead_code)]
fn main() {
    let output = solve();
    println!("{}", output.join("\n"));
}


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

    let n: u64 = input.trim().parse().unwrap();

    let ans = n / 2 + 1;

    println!("{}", ans)
}


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

fn main() {
    let reader = io::stdin();
    let numbers: Vec<i64> =
        reader.lock()                           // (0)
              .lines().next().unwrap().unwrap() // (1)
              .split(' ').map(|s| s.trim())     // (2)
              .filter(|s| !s.is_empty())        // (3)
              .map(|s| s.parse().unwrap())      // (4)
              .collect();                       // (5)

    let l = numbers[0];
    let r = numbers[1];

    let mut ans = 0;

    let mut num2: i64 = 1;
    for p2 in 0..32 {
        let mut num3: i64 = num2;
        for p3 in 0..20 {
        	if num3 >= l && num3 <= r {
        		ans = ans + 1;
        	}
        	num3 = num3 * 3;
        }
        num2 = num2 * 2;
    }

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


fn main() {
    let input = input_vec_chars();
    let d: Vec<char> = input
        .into_iter()
        .filter(|c| *c == 'Q' || *c == 'A').collect();

    let mut count = 0;

    for (i, elm) in d.iter().enumerate() {
        if *elm == 'Q' {
            for j in i+1..d.len() {
                if d[j] == 'A' {
                    for k in j+1..d.len() {
                        if d[k] == 'Q' {
                            count += 1;
                        }
                    }
                }
            }
        }
    }
    println!("{:?}", count);
}

fn input_str() -> String {
    let mut buff = String::new();
    std::io::stdin().read_line(&mut buff).expect("Err");
    buff
}

fn input_u64() -> u64 {
    input_str().trim().parse().unwrap()
}

fn input_vec<T>(sep: &str) -> Vec<T>
where
    T: std::str::FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Debug,
{
    input_str().trim().split(sep).map(|c| c.parse::<T>().expect("Err pars")).collect()
}

fn input_vec_chars() -> Vec<char> {
    input_str().trim().chars().collect()
}


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

type Point = (i32, i32);
type Seg = (Point, Point);

fn cm(base: &Point, a: &Point, b: &Point) -> i32 {
    let debug = false;
    if debug { println!("base {:?}, a {:?}, b {:?}", base, a, b) }
    return (a.0 - base.0)*(b.1 - base.1) - (a.1 - base.1)*(b.0 - base.0);
}

fn inx(a: i32, b: i32, x: i32) -> bool {
    return (b >= a && x >= a && x <= b) || (b <= a && x <= a && x >= b);
}

fn ins(pa: &Point, pb: &Point, px: &Point) -> bool {
    return inx(pa.0, pb.0, px.0) && inx(pa.1, pb.1, px.1);
}

fn intersect(a: &Seg, b: &Seg) -> bool {
    let b0 = cm(&a.0, &a.1, &b.0);
    if b0 == 0 && ins(&a.0, &a.1, &b.0) { return true; }
    let b1 = cm(&a.0, &a.1, &b.1);
    if b1 == 0 && ins(&a.0, &a.1, &b.1) { return true; }
    let a0 = cm(&b.0, &b.1, &a.0);
    if a0 == 0 && ins(&b.0, &b.1, &a.0) { return true; }
    let a1 = cm(&b.0, &b.1, &a.1);
    if a1 == 0 && ins(&b.0, &b.1, &a.1) { return true; }
    return ((a0 > 0 && a1 < 0) || (a0 < 0 && a1 > 0))
        && ((b0 > 0 && b1 < 0) || (b0 < 0 && b1 > 0));
}

fn main() {
    let debug = false;
    let stdin: io::Stdin = io::stdin();
    let mut lines: io::Lines<io::StdinLock> = stdin.lock().lines();

    let next_line = lines.next()
        .unwrap() // Option<Result> { Some(Result), None }
        .unwrap(); // Result<String, io::Error> { Ok(String), Err(io::Error) }

    let square_a: Vec<_> = next_line
        .trim()
        .split(' ')
        .map(|n| {
            n.parse::<i32>().unwrap()
        })
        .collect();

    let next_line = lines.next()
        .unwrap() // Option<Result> { Some(Result), None }
        .unwrap(); // Result<String, io::Error> { Ok(String), Err(io::Error) }

    let square_b: Vec<_> = next_line
        .trim()
        .split(' ')
        .map(|n| {
            n.parse::<i32>().unwrap()
        })
        .collect();

    // any a inside b
    if debug { println!("\n\n a inside b ?? \n\n") }
    for a_i in 0..4 {
        let a = (square_a[2*a_i], square_a[2*a_i+1]);
        let mut left = false;
        let mut right = false;
        if debug { println!("POINT a choosen") }
        for i in 0..4 {
            let base = (square_b[2*i], square_b[2*i+1]);
            let j = (i+1) % 4;
            let b = (square_b[2*j], square_b[2*j+1]);
            if debug { println!("-------------------") }
            let cmv = cm(&base, &b, &a);
            if debug { println!("cmv {}", cmv) }
            if cmv > 0 { left = true; }
            if cmv < 0 { right = true; }
        }
        if !left || !right {
            println!("YES");
            return;
        }
    }

    // any b inside a
    if debug { println!("\n\n b inside a ?? \n\n") }
    for b_i in 0..4 {
        let b = (square_b[2*b_i], square_b[2*b_i+1]);
        let mut left = false;
        let mut right = false;
        if debug { println!("POINT b choosen") }
        for i in 0..4 {
            let base = (square_a[2*i], square_a[2*i+1]);
            let j = (i+1) % 4;
            let a = (square_a[2*j], square_a[2*j+1]);
            if debug { println!("-------------------") }
            let cmv = cm(&base, &a, &b);
            if debug { println!("cmv {}", cmv) }
            if cmv > 0 { left = true; }
            if cmv < 0 { right = true; }
        }
        if !left || !right {
            println!("YES");
            return;
        }
    }

    // check intersect
    for a_i in 0..4 {
        let a_a = (square_a[2*a_i], square_a[2*a_i+1]);
        let a_j = (a_i + 1) % 4;
        let a_b = (square_a[2*a_j], square_a[2*a_j+1]);
        let seg_a = (a_a, a_b);

        for i in 0..4 {
            let b_a = (square_b[2*i], square_b[2*i+1]);
            let j = (i+1) % 4;
            let b_b = (square_b[2*j], square_b[2*j+1]);
            let seg_b = (b_a, b_b);
            if intersect(&seg_a, &seg_b) {
                println!("YES");
                return;
            }
        }
    }

    println!("NO");
}


#[warn(unused_variables)]

fn main() {
    let n = input_::<u32>();
    println!("{}", if n % 2 == 0 {2u64.pow(n/2u32)} else {0})
}

fn input_str() -> String {
    let mut buff = String::new();
    std::io::stdin().read_line(&mut buff).expect("Err");
    buff
}

fn input_<T>() -> T
where
    T: std::str::FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Debug,
{
    input_str().trim().parse::<T>().expect("Err pars")
}

fn input_vec<T>(sep: &str) -> Vec<T>
where
    T: std::str::FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Debug,
{
    input_str().trim().split(sep).map(|c| c.parse::<T>().expect("Err pars")).collect()
}

fn input_vec_chars() -> Vec<char> {
    input_str().trim().chars().collect()
}


use std::io::{BufReader, BufWriter, Read, Write, stdin, stdout};

pub struct Scanner<U: Sized + Read> {
    pub buffer: Vec<String>,
    pub reader: U,
}
impl<U: Sized + Read> Scanner<U> {
    pub fn next<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            self.reader.read_to_string(&mut input).expect("Failed read");
            self.buffer = input.lines().rev().map(String::from).collect();
        }
    }

    pub fn new(reader: U) -> Self {
        return Scanner {
            buffer: vec![],
            reader,
        };
    }
}
pub fn solution_of_p263a(input: &mut Read, out: &mut Write) {
    let mut scanner = Scanner::new(input);
    let mut mat: Vec<Vec<usize>> = vec![];
    for _i in 0..5 {
        let arr: Vec<usize> = scanner.next::<String>().split(" ").map(|e| {
            return e.parse::<usize>().unwrap();
        }).collect();
        mat.push(arr);
    }

    // find the cordinate of the 1 in the matrix
    let mut x = 0;
    let mut y = 0;
    for i in 0..5 {
        let row: &Vec<usize> = &mat[i];
        for j in 0..5 {
            let elem = row[j];
            if elem == 1 {
                x = i;
                y = j;
            }
        }
    }
    let mut res = 0;
    if x > 2 {
        res += x - 2;
    } else {
        res += 2-x;
    }
    if y > 2 {
        res += y - 2;
    } else {
        res += 2-y;
    }
    write!(out, "{}\n", res).ok();
}

fn main() {
    solution_of_p263a(&mut stdin(), &mut stdout());
}


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

fn solve<'a, I: Iterator<Item = &'a str>>(mut lines: I) -> Option<Vec<bool>> {
	let count: usize = lines.next()?
		.parse().ok()?;

	(0..count).map(|_| {
		let mut key: usize = lines.next()?
			.parse().ok()?;
		let doors: [_; 3] = lines.next()?
			.split(' ')
			.map(str::parse)
			.collect::<Result<Vec<usize>, _>>().ok()?
			.try_into().ok()?;

		let mut opened: usize = 0;

		while opened < 3 {
			key = if key > 0 && key <= doors.len() {
				doors[key - 1]
			} else {
				break;
			};

			opened += 1;
		}

		Some(opened == 3)
	})
		.collect()
}

fn main() -> io::Result<()> {
	let mut stdout = io::BufWriter::new(io::stdout());
	let mut stdin = io::BufReader::new(io::stdin());

	let mut input = String::new();
	stdin.read_to_string(&mut input)?;
	let lines = input.lines();

	let result = solve(lines).unwrap();

	for case in result {
		stdout.write_all(if case { b"YES\n" } else { b"NO\n" })?;
	}

	Ok(())
}


use std::io::{stdin, stdout, Write, BufReader, BufRead, Read};

fn gcd(mut a: u64, mut b: u64) -> u64 {
    while b != 0 {
        a %= b;
        let c = a;
        a = b;
        b = c;
    }
    return a;
}

fn solve(input: &mut BufRead, output: &mut Write) {
    let mut input = BufReader::new(input);

    let mut first = String::with_capacity(201);
    let mut second = String::with_capacity(201);

    input.read_line(&mut first).unwrap();
    input.read_line(&mut second).unwrap();

    let s = first.trim().as_bytes();
    let t = second.trim().as_bytes();

    let first = s.iter().position(|&it| it == t[0]).unwrap();
    let second = s.iter().rev().position(|&it| it == t[t.len() - 1]).unwrap();

    let mut answ = first.max(second);

    let mut pos = vec![first; t.len()];
    let mut pos_rev = vec![second; t.len()];

    let mut prev = first;
    for i in 0..t.len() {
        let mut pos1 = 0;
        for j in prev..s.len() {
            if s[j] == t[i] {
                pos1 = j;
                break;
            }
        }
        prev = pos1;
        pos[i] = prev;
        prev += 1;
    }

    let mut rev = s.len() - 1 -second;
    for i in (0..t.len()).rev() {
        let mut pos1 = 0;
        for j in (0..=rev).rev() {
            if s[j] == t[i] {
                pos1 = j;
                break;
            }
        }
        rev = pos1;
        pos_rev[i] = rev;
        if rev > 0 {
            rev -= 1;
        }
    }

    for i in 0..t.len() - 1 {
        answ = answ.max(pos_rev[i + 1] - 1 - pos[i])
    }

    answ = answ.max(s.len() - pos[pos.len() - 1] - 1);
    answ = answ.max(pos_rev[0]);

    writeln!(output, "{}", answ).unwrap();
}

fn main() {
    let stdin = stdin();
    let stdout = stdout();
    solve(&mut stdin.lock(), &mut stdout.lock());
}

#[cfg(test)]
mod tests {
    use std::fs::File;
    use solve;
    use std::io::BufReader;

    #[test]
    fn basic_test() {
        let mut f = BufReader::new("bbaba
bb
".as_bytes());
        let mut buf: Vec<u8> = Vec::new();

        solve(&mut f, &mut buf);

        let res = String::from_utf8(buf).unwrap();
        assert_eq!(res, "3\n");
    }

    #[test]
    fn basic_test2() {
        let mut f = BufReader::new("baaba
ab
".as_bytes());
        let mut buf: Vec<u8> = Vec::new();

        solve(&mut f, &mut buf);

        let res = String::from_utf8(buf).unwrap();
        assert_eq!(res, "2\n");
    }

    #[test]
    fn basic_test3() {
        let mut f = BufReader::new("abcde
abcde
".as_bytes());
        let mut buf: Vec<u8> = Vec::new();

        solve(&mut f, &mut buf);

        let res = String::from_utf8(buf).unwrap();
        assert_eq!(res, "0\n");
    }

    #[test]
    fn basic_test4() {
        let mut f = BufReader::new("asdfasdf
fasd
".as_bytes());
        let mut buf: Vec<u8> = Vec::new();

        solve(&mut f, &mut buf);

        let res = String::from_utf8(buf).unwrap();
        assert_eq!(res, "3\n");
    }
}


//spnauti-rusT
use std::io::*;
use std::str::{self,*};
use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::{self,*};
#[allow(unused_imports)] use std::iter::{self,*};
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_macros)]
macro_rules! m {
    ($c:tt, $x:expr, $y:expr) => {{
        let b = $y; let a = &mut $x;
        if b $c *a { *a = b; true } else { false }
    }};
}
#[allow(unused_macros)]
macro_rules! l {
    ($($v:ident),* = $i:ident.$f:ident $a:tt) => {
        $( let $v = $i.$f$a; )*
    };
    ($($v:ident),*:$t:ty = $i:ident.$f:ident $a:tt) => {
        $( let $v:$t = $i.$f$a; )*
    };
}
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 f(&mut self) ->    f64 { self.p()                }
    fn u(&mut self) ->  usize { self.p()                }
    fn sk(&mut self, n: usize) { self.it.nth(n - 1); }
    fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> {
        self.ip(n).into_iter()
    }
    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 ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
        self.vp(n).into_iter()
    }
    fn vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
        (0..n).map(|_| self.p()).collect()
    }
}
//------------------- End rusT

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

    let n: i64 = input.p();
    let mut a = 1;
    let mut b = 2;
    let mut sol = 0;
    while b <= n {
        let c = a + b;
        a = b;
        b = c;
        sol += 1;
    }
    println!("{}", sol);
}


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

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

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

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

    pub fn tokens<T: str::FromStr>(&mut self) -> Vec<T> {
        assert!(self.buffer.is_empty());
        let mut input = String::new();
        self.reader.read_line(&mut input).expect("Failed read");
        input
            .split_whitespace()
            .map(|x| x.parse().ok().expect("Failed parse"))
            .collect()
    }
}

const INF: i32 = 1000000000;

fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
    let n: usize = scan.token();
    let jump_length: usize = scan.token();
    let s: Vec<char> = scan.token::<String>().chars().collect();
    let mut dp = vec![INF; n];
    dp[0] = 0;
    for i in 1..n {
        if s[i] == '1' {
            for j in 1..=jump_length {
                if i >= j {
                    dp[i] = dp[i].min(dp[i - j] + 1);
                }
            }
        }
    }
    let ans = if dp[n - 1] >= INF { - 1 } else { dp[n - 1] };
    writeln!(out, "{}", ans).ok();
}

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


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

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

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

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

	(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7])
}

fn main() {
	let (n, k, l, c, d, p, nl, np) = get_nums();

	println!("{}", min((k*l)/nl, c*d, p/np)/n);

	fn min(x: i32, y: i32, z: i32) -> i32 {
		if x < y {
			if x < z {
				x
			} else {
				z
			}
		} else if y < z {
			y
		} else {
			z
		}
	}
}


use std::collections::{HashMap, HashSet};
use std::cmp::max;

fn read_string() -> String {
    let mut string: String = String::new();

    std::io::stdin().read_line(&mut string)
        .ok()
        .expect("Error read line!");
    return string;
}

fn koutsu_count(koutsu : &HashMap<&str, usize> ) -> usize
{
    koutsu.values().max().unwrap().to_owned()
}

fn shuntsu_count(shuntsu : &HashMap<&str, HashSet<usize>> ) -> usize
{
    shuntsu.values().map(|x| suit_set_count(&x))
        .max().to_owned().unwrap()

}

fn suit_set_count(set : &HashSet<usize>) -> usize
{
    if set.len() <= 1  { return  set.len() }

    let mut list :Vec<_> = set.iter().collect();
    list.sort();
    let mut currrent_count = 1;
    let mut max_count = 1;
    let mut prev = list[0];
    for item in list
    {
        match item - prev
        {
            i if i > 2  =>
            {
                max_count = max(currrent_count, max_count);
                currrent_count = 1;
            }
            1 =>
            {
                currrent_count += 1;
                max_count = max(currrent_count, max_count);
            }
            2 =>
            {
                max_count = max(2, max_count);
                currrent_count = 1;
            }
            _ => { }

        }
        prev = item;
    }
    max_count
}

fn main() {

    let line : String= read_string().trim().into();
    let mut koutsu : HashMap<&str, usize> = HashMap::new();
    let mut shuntsu : HashMap<&str, HashSet<usize>> = HashMap::new();
    for elem in line.split(" ")
    {
        koutsu.entry(elem).and_modify(|e| *e+=1).or_insert(1);
        let value = &elem[0..1].parse().unwrap();
        let suit = &elem[1..2];
        shuntsu.entry(suit).or_default().insert(*value);

    }
    println!("{}", 3 - max(koutsu_count(&koutsu) ,shuntsu_count(&shuntsu)))

}


use std::io;

fn read_line() -> io::Result<String> {
    let mut input_str = String::new();

    try!(io::stdin().read_line(&mut input_str));

    Ok(input_str)
}

fn a_to_b(a: u32, b: u32) -> Vec<u32> {
    let mut result = Vec::new();
    let mut current_state = b;

    loop {
        match current_state {
            x if (x < a) || (x > a && x % 2 != 0 && x % 10 != 1) => {
                result.clear();
                break;
            }
            x => {
                result.push(x);
                match x {
                    x if x == a => break,
                    x if x % 2 == 0 => current_state /= 2,
                    _ => current_state /= 10,
                }
            }
        }
    }

    result.reverse();
    result
}

fn main() {
    let input_line = read_line().expect("Failed to read line.");
    let mut input_line_iter = input_line.split_whitespace();

    let given_number = input_line_iter.next()
        .expect("First number is not given.")
        .parse::<u32>()
        .expect("First number is invalid.");
    let result_number = input_line_iter.next()
        .expect("Second number is not given.")
        .parse::<u32>()
        .expect("Second number is invalid");

    let answer_sequence = a_to_b(given_number, result_number);

    match answer_sequence.len() {
        0 => println!("NO"),
        len => {
            println!("YES\n{}", len);
            for number in answer_sequence {
                print!("{} ", number);
            }
        }
    }
}


#![allow(unused_imports, unused_macros)]

use kyoproio::*;
use std::{
    collections::*,
    io::{self, prelude::*},
    iter,
    mem::{replace, swap},
};

fn main() -> io::Result<()> {
    std::thread::Builder::new()
        .stack_size(64 * 1024 * 1024)
        .spawn(|| {
            let stdin = io::stdin();
            let stdout = io::stdout();
            run(KInput::new(stdin.lock()), io::BufWriter::new(stdout.lock()))
        })?
        .join()
        .unwrap();
    Ok(())
}

fn run<I: Input, O: Write>(mut kin: I, mut out: O) {
    macro_rules! output { ($($args:expr),+) => { write!(&mut out, $($args),+).unwrap(); }; }
    macro_rules! outputln {
        ($($args:expr),+) => { output!($($args),+); outputln!(); };
        () => { output!("\n"); if cfg!(debug_assertions) { out.flush().unwrap(); } }
    }

    let k: i64 = kin.input();
    let mut a = vec![1; 10];
    for i in 0.. {
        let p: i64 = a.iter().product();
        if p >= k {
            break;
        }
        a[i % 10] += 1;
    }
    let s = b"codeforces";
    for i in 0..10 {
        for _ in 0..a[i] {
            output!("{}", s[i] as char);
        }
    }
    outputln!();
}

// -----------------------------------------------------------------------------
pub mod kyoproio {
    use std::io::prelude::*;
    pub trait Input {
        fn str(&mut self) -> &str;
        fn input<T: InputParse>(&mut self) -> T {
            T::input(self)
        }
        fn iter<T: InputParse>(&mut self) -> Iter<T, Self> {
            Iter(self, std::marker::PhantomData)
        }
        fn seq<T: InputParse, B: std::iter::FromIterator<T>>(&mut self, n: usize) -> B {
            self.iter().take(n).collect()
        }
    }
    pub struct KInput<R> {
        src: R,
        buf: String,
        pos: usize,
    }
    impl<R: BufRead> KInput<R> {
        pub fn new(src: R) -> Self {
            Self {
                src,
                buf: String::with_capacity(1024),
                pos: 0,
            }
        }
        pub fn src(&mut self) -> &mut R {
            &mut self.src
        }
    }
    impl<R: BufRead> Input for KInput<R> {
        fn str(&mut self) -> &str {
            loop {
                if self.pos >= self.buf.len() {
                    self.pos = 0;
                    self.buf.clear();
                    if self.src.read_line(&mut self.buf).expect("io error") == 0 {
                        return &self.buf;
                    }
                }
                let range = self.pos
                    ..self.buf[self.pos..]
                        .find(|c: char| c.is_ascii_whitespace())
                        .map(|i| i + self.pos)
                        .unwrap_or_else(|| self.buf.len());
                self.pos = range.end + 1;
                if range.end > range.start {
                    return &self.buf[range];
                }
            }
        }
    }
    pub struct Iter<'a, T, I: ?Sized>(&'a mut I, std::marker::PhantomData<*const T>);
    impl<'a, T: InputParse, I: Input + ?Sized> Iterator for Iter<'a, T, I> {
        type Item = T;
        fn next(&mut self) -> Option<T> {
            Some(self.0.input())
        }
    }
    pub trait InputParse: Sized {
        fn input<I: Input + ?Sized>(src: &mut I) -> Self;
    }
    impl InputParse for Vec<u8> {
        fn input<I: Input + ?Sized>(src: &mut I) -> Self {
            src.str().as_bytes().to_owned()
        }
    }
    macro_rules! from_str_impl {
        { $($T:ty)* } => {
            $(impl InputParse for $T {
                fn input<I: Input + ?Sized>(src: &mut I) -> Self {
                    src.str().parse::<$T>().expect("parse error")
                }
            })*
        }
    }
    from_str_impl! {
        String char bool f32 f64 isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128
    }
    macro_rules! tuple_impl {
        ($H:ident $($T:ident)*) => {
            impl<$H: InputParse, $($T: InputParse),*> InputParse for ($H, $($T),*) {
                fn input<I: Input + ?Sized>(src: &mut I) -> Self {
                    ($H::input(src), $($T::input(src)),*)
                }
            }
            tuple_impl!($($T)*);
        };
        () => {}
    }
    tuple_impl!(A B C D E F G);
    #[macro_export]
    macro_rules! kdbg {
        ($($v:expr),*) => {
            if cfg!(debug_assertions) { dbg!($($v),*) } else { ($($v),*) }
        }
    }
}


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

static BIG: i64 = 1e9 as i64 + 7;
fn _main() {
    let mut scan = Scan::new();
    let mut x: i64 = scan.next();
    let mut y: i64 = scan.next();
    let mut n: i64 = scan.next();
    let mut i = 2i64;
    n = n % 6;
    // I think it would be better to precompute an
    // array with the 6 different possible values
    while i < n + 6 {
        let tmp = y;
        y = (y - x + BIG) % BIG;
        x = tmp;
        i += 1;
    }
    println!("{}", (y + BIG) % BIG);
}

fn main() {
    std::thread::Builder::new()
        .stack_size(1 << 23)
        .spawn(_main)
        .unwrap()
        .join()
        .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::io::{stdin, stdout, BufWriter, Write};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[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() {
    input!{
        w0: (i64,i64,i64,i64),
        b0: (i64,i64,i64,i64),
        b1: (i64,i64,i64,i64),
    }

    let mut xs = vec![];
    xs.push(w0.0);
    xs.push(w0.2);
    xs.push(b0.0);
    xs.push(b0.2);
    xs.push(b1.0);
    xs.push(b1.2);
    xs.sort();
    let mut x_compress = HashMap::new();
    let mut x_decompress = HashMap::new();
    let mut cur_x=0;
    for x in xs {
        if !x_compress.contains_key(&x) {
            x_compress.entry(x).or_insert(cur_x);
            x_decompress.entry(cur_x).or_insert(x);
            cur_x+=1;
        }
    }

    let mut ys = vec![];
    ys.push(w0.1);
    ys.push(w0.3);
    ys.push(b0.1);
    ys.push(b0.3);
    ys.push(b1.1);
    ys.push(b1.3);
    ys.sort();
    let mut y_compress = HashMap::new();
    let mut y_decompress = HashMap::new();
    let mut cur_y=0;
    for y in ys {
        if !y_compress.contains_key(&y) {
            y_compress.entry(y).or_insert(cur_y);
            y_decompress.entry(cur_y).or_insert(y);
            cur_y+=1;
        }
    }

    let mut table = vec![vec![false; cur_y-1]; cur_x-1];
    let x_comp = |x: i64| {
        x_compress.get(&x).unwrap().clone() as usize
    };
    let y_comp = |y: i64| {
        y_compress.get(&y).unwrap().clone() as usize
    };
    for x in x_comp(b0.0)..x_comp(b0.2) {
        for y in y_comp(b0.1)..y_comp(b0.3) {
            table[x][y]=true;
        }
    }
    for x in x_comp(b1.0)..x_comp(b1.2) {
        for y in y_comp(b1.1)..y_comp(b1.3) {
            table[x][y]=true;
        }
    }
    let mut ok = false;
    for x in x_comp(w0.0)..x_comp(w0.2) {
        for y in y_comp(w0.1)..y_comp(w0.3) {
            if !table[x][y] {
                ok=true;
                break;
            }
        }
    }

    if ok {
        println!("YES");
    } else {
        println!("NO");
    }
}


use std::io::{self, Stdin};
use std::str::{self, FromStr};
use std::error::Error;
use std::thread;

fn exec() {
    let mut sc = Scanner::new();
    let s: Vec<u8> = sc.ne::<String>().into_bytes();
    let mut ok = true;
    let mut next = b'a';
    for &c in &s {
        if c == next {
            next += 1;
        } else if c > next {
            ok = false;
        }
    }
    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::{str::FromStr, fmt::Debug};
fn read_line() -> String {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).expect("");
    return line;
}
fn read<T: std::str::FromStr>() -> T where <T as FromStr>::Err: Debug{
    return read_line().trim().parse::<T>().unwrap();
}
fn reads<T: std::str::FromStr>() -> Vec<T> where <T as FromStr>::Err: Debug{
    return read_line().trim().split(' ').map(|x| x.parse::<T>().unwrap()).collect();
}
fn main() {
    let modint = 998244353;
    let nm = reads::<i64>();
    let n = nm[0];
    let m = nm[1];
    let mut a = Vec::<i64>::new();
    a.resize(n as usize + 1, 0);
    let mut is_prime = Vec::<bool>::new();
    is_prime.resize(n as usize + 1, true);
    a[1] = m;
    let mut lcm = 1;
    let mut x = 0;
    let mut y = 0;
    let mut p = 1;
    for i in 2..n + 1 {
        if is_prime[i as usize] {
            let mut j = i + i;
            while j <= n {
                is_prime[j as usize] = false;
                j += i;
            }
        }
    }
    for i in 1..n + 1 {
        p = m % modint * p % modint;
        x = (x + p) % modint;
        if is_prime[i as usize] {
            lcm = std::cmp::min(lcm * i, m + 1);
        }
        a[i as usize] = m / lcm;
    }
    for i in (1..n + 1).rev() {
        y = a[i as usize] % modint * (y + 1) % modint;
    }
    println!("{}", (x + modint - y) % modint);
}


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::{Not, Sub}, process::exit, rc::Rc, str::{FromStr, from_utf8, from_utf8_unchecked}, time::{Duration, Instant}};

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| { writeln!(x).ok() }); };
    ($exp: expr) => { out(|x| { writeln!(x, "{}", $exp).ok(); }); };
    ($fmt: expr, $($arg : tt )*) => { out(|x| { writeln!(x, $fmt, $($arg)*).ok(); }); }
}
macro_rules! print {
    ($exp: expr) => { out(|x| { write!(x, "{}", $exp).ok(); }); };
    ($fmt: expr, $($arg : tt )*) => { out(|x| { write!(x, $fmt, $($arg)*).ok(); }); }
}

fn out_flush() { out(|x| x.flush().ok()); }

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: ToString, I: Iterator<Item = T>> JoinToStr for I {
    fn join_to_str(mut self, sep: &str) -> String {
        let mut res = String::new();
        if let Some(first) = self.next() {
            res.push_str(&first.to_string());
            while let Some(item) = self.next() {
                res.push_str(sep);
                res.push_str(&item.to_string())
            }
        }
        res
    }

    fn concat_to_str(self) -> String {
        let mut res = String::new();
        for item in self { res.push_str(&item.to_string()); }
        res
    }
}

macro_rules! veci {
    ($n:expr , $i:ident : $gen:expr) => {{
        let n = $n;
        let mut list = Vec::with_capacity(n);
        for $i in 0..n {
            list.push($gen);
        }
        list
    }};
    ($n:expr , $gen:expr) => { veci!($n, __: $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;
}

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; while a != 0 { swap(&mut a, &mut b); a %= b; }
                    b
                }
                #[inline] fn highest_one(self) -> Self {
                    if self == 0 { 0 } else { const ONE: $ux = 1; ONE.rotate_right(1) >> self.leading_zeros() }
                }
                #[inline] fn lowest_one(self) -> Self { self & self.wrapping_neg() }
            }

            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, mut b: Self) -> Self {
                    let mut a = self; while a != 0 { swap(&mut a, &mut b); a %= b; }
                    b.abs()
                }
                #[inline] fn highest_one(self) -> Self { (self as $ux).highest_one() as _ }
                #[inline] fn lowest_one(self) -> Self { self & self.wrapping_neg() }
            }
        )*
    }
}
impl_common_num_ext!(i8 = u8, i16 = u16, i32 = u32, i64 = u64, i128 = u128, isize = usize);

trait ChMaxMin<T> {
    fn set_max(&mut self, v: T) -> bool;
    fn set_min(&mut self, v: T) -> bool;
}
impl<T: PartialOrd> ChMaxMin<T> for T {
    fn set_max(&mut self, v: T) -> bool { if v > *self { *self = v; true } else { false } }
    fn set_min(&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 { r.wrapping_add(m) }
    }
    #[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;
        }
        return 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;
    }

    #[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
        }
    }

    #[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(mul_mod_u32(self.val, rhs.into().val, Self::modulus()))
        }
    }
    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 }
            }
            pub type $mint = ModIntBase<$name>;
        }
    }

    macro_rules! dynamic_modulus {
        ($mint: ident, $name: ident, $modulus: ident) => {
            static $modulus: crate::Unsync<Cell<u32>> = crate::Unsync(Cell::new(0));
            #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
            pub enum $name {}
            impl Modulus for $name {
                fn get_modulus() -> u32 { $modulus.0.get() }
            }
            impl $name {
                pub fn set_modulus(val: u32) { $modulus.0.set(val) }
            }
            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;

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

    for _case_num in 1..=num_cases {
        let n = read!(usize);
        DynamicModulus::set_modulus(read());

        let mut dp = vec![mir(0); n+1];
        dp[1] = mir(1);
        dp[2] = mir(2);
        for i in 2..n {
            let d = dp[i];
            dp[i+1] += d + d + mir(1);
            let d = d - dp[i-1];
            for j in (i*2..=n).step_by(i) {
                dp[j] += d;
            }
        }

        let ans = dp[n];
        println!(ans);
    }

    out_flush();
}


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 a: usize = scan.next();
    let b: usize = scan.next();
    if a == b {
        println!("0 6 0");
    } else if a < b {
        let middle = a.max(b) - a.min(b) - 1;
        println!(
            "{} {} {}",
            a + middle / 2,
            middle % 2,
            6 - b + 1 + middle / 2
        );
    } else {
        let middle = a.max(b) - a.min(b) - 1;
        println!(
            "{} {} {}",
            6 - a + 1 + middle / 2,
            middle % 2,
            b + middle / 2
        );
    }
}

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


use std::io;
use std::io::Read;

fn main() {
    let mut buffer = String::new();
    io::stdin().read_to_string(&mut buffer).unwrap();
    let mut cin = buffer.split_whitespace().map(|x| x.parse::<u64>().unwrap());
    let n = cin.next().unwrap() as usize;
    let mut a = cin.enumerate().collect::<Vec<_>>();
    a.sort_by_key(|x| x.1);
    for i in 0..n / 2 {
        println!("{} {}", a[i].0 + 1, a[n - i - 1].0 + 1);
    }
}