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

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

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

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

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

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

fn main() {
    let (n, k) = get!(u64, u64);

    let mut ans = 1;

    if k > 1 {
        for i in 2..k + 1 {
            let u = (n - i + 1..n + 1).fold(1, |a, b| a * b);
            let d = (1..i + 1).fold(1, |a, b| a * b);

            let c = u / d;

            ans += c * [1, 2, 9][(i - 2) as usize];
        }
    }

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


macro_rules! readln {
    () => {{
        use std::io;

        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();
        buf.trim().to_string()
    }};
    ( $t:ty ) => {{
        let input = readln!();
        input.parse::<$t>().unwrap()
    }};
    ( $( $t:ty ),+ ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        (
            $(
                input.next().unwrap().parse::<$t>().unwrap(),
            )+
        )
    }}
}

macro_rules! readvec {
    ( $t:ty ) => {{
        let input = readln!();
        let mut input = input.split_whitespace();
        let mut result = Vec::new();
        for elem in input {
            result.push(elem.parse::<$t>().unwrap());
        }
        result
    }}
}

fn main() {
    let (a,b) = readln!(i32,i32);
    let mut live = a;
    let mut dead = 0;
    let mut res = 0;
    while live>0 {
        res += live;
        dead += live;
        live = 0;
        live += (dead/b);
        dead %= b;
    }
    println!("{}",res);
}


fn readln() -> Vec<i32> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.split_whitespace()
        .map(|x| x.parse().unwrap())
        .collect()
}

fn main() {
    let input = readln();

    let mut count_new_candles = input[0];
    let mut count_old_candles = 0;
    let b = input[1];

    let mut total_time = 0;
    while count_new_candles > 0 {
        total_time += 1;
        count_new_candles -= 1;
        count_old_candles += 1;
        if count_old_candles == b {
            count_new_candles += 1;
            count_old_candles = 0;
        }
    }

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


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

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn num_days(n : u64, m : u64) -> u64 {
    let mut s = n;
    let mut x = n;
    loop {
        if x < m {
            break;
        } else {
            let x_div_m = x / m;
            let x_mod_m = x % m;
            s = s + x_div_m;
            x = x_div_m + x_mod_m;
        }
    }
    s
}

fn main() {
    let stdin = io::stdin();
    let mut n_m : Vec<u64> = vec![];
    read_ts(&stdin, &mut n_m);
    let n = n_m[0];
    let m = n_m[1];
    println!("{}", num_days(n, m));
}


use std::io;

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

fn read_line_vec() -> Vec<i64> {
    return read_line().split(' ')
        .map(|s| s.parse().unwrap())
        .collect();
}

fn read_line_pair() -> (i64, i64) {
    let vec = read_line_vec();
    return (vec[0], vec[1]);
}

fn main() {
    let (mut a, b) = read_line_pair();
    let mut remain = 0;

    let mut sum = 0;
    while a > 0 {
        sum += a;
        remain += a;
        a = remain / b;
        remain = remain % b;
    }

    println!("{}", sum);

}


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 = scan.next::<usize>();
    let b = scan.next::<usize>();
    let mut result = a;
    let mut current = a;
    while current>=b {
        result += current / b;
        current = current / b + current % b;
    }
    println!("{}", result);
}


use std::io;

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

    let mut iter = input.split_whitespace();

    let a: u16 = iter.next().unwrap().trim().parse().unwrap();
    let b: u16 = iter.next().unwrap().trim().parse().unwrap();

    let mut hour_count: i32 = 0;

    if a >= b {
        let mut candle_count = a as i16;

        while candle_count > 0 {
            if (candle_count - (b as i16)) >= 0 {
                candle_count -= b as i16;
                hour_count += b as i32;
                candle_count += 1;
            } else {
                hour_count += candle_count as i32;
                candle_count = 0;
            }
        }
    } else {
        hour_count += a as i32;
    }

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


// {{{ by shik

use std::io;

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

#[allow(unused_macros)]
macro_rules! R {
    ( $ty:ty, ... ) => {
        gets().split_whitespace().map(|x| x.parse::<$ty>().unwrap()).collect::<Vec<_>>()
    };
    ( $($ty:ty),* ) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        ( $(it.next().unwrap().parse::<$ty>().unwrap(),)* )
    }}
}

#[allow(unused_macros)]
macro_rules! W {
    ( $x:expr ) => {{
        println!("{}", $x);
    }};
    ( $x:expr, $($xs:expr),* ) => {{
        print!("{} ", $x);
        W!($($xs),*);
    }}
}

#[allow(unused_macros)]
macro_rules! join {
    ($x:expr, $($xs:expr),*; $sep:expr) => { concat!($x, $($sep, $xs),*) }
}

#[allow(unused_macros)]
macro_rules! dump {
    ($($x:expr),*) => {
        eprintln!(join!($(concat!(stringify!($x), " = {:?}")),*; ", "), $($x),*);
    }
}

// }}}

fn main() {
    let (a, b) = R!(usize, usize);
    let mut ans: usize = 0;
    let mut cur: usize = a;
    let mut curu: usize = 0;
    while cur > 0 {
        ans += cur;
        curu += cur;
        cur = curu / b;
        curu %= b;
    }
    println!("{}", ans);
}


type Pair = (i32, i32);
fn input_pair() -> Pair {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    let buf: Vec<i32> = buf.trim().split_whitespace().map(|elem| elem.parse().unwrap()).collect();
    (buf[0], buf[1])
}

fn solve(n: i32, m: i32, r: i32) -> i32 {
    match n {
        0 => 0,
        n => n + solve((n+r) / m, m, (n+r) % m)
    }
}

fn main() {
    let (n, m) = input_pair();
    println!("{}", solve(n, m, 0));
}


// ---------- begin input macro ----------
// reference: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

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

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    ($iter:expr, bytes) => {
        read_value!($iter, String).bytes().collect::<Vec<u8>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
// ---------- end input macro ----------

fn run() {
    input! {
        s: bytes,
    }
    if &s == &[b'_'] {
        println!("1");
        return;
    }
    let mut x = 1;
    if s.contains(&b'X') {
        x = 10;
    }
    let mut ans = 0u64;
    for v in 0..x {
        let mut s = s.clone();
        s.iter_mut().for_each(|s| {
            if *s == b'X' {
                *s = b'0' + v as u8;
            }
        });
        if s[0] == b'0' && s.len() > 1 {
            continue;
        }
        let mut dp = [0; 25];
        dp[0] = 1;
        for (i, s) in s.iter().enumerate() {
            if *s == b'_' {
                let mut s = 0;
                if i == 0 {
                    s = 1;
                }
                let mut next = [0; 25];
                for d in s..10 {
                    for (i, dp) in dp.iter().enumerate() {
                        next[(i * 10 + d) % 25] += *dp;
                    }
                }
                dp = next;
            } else {
                assert!(b'0' <= *s && *s <= b'9');
                let k = (*s - b'0') as usize;
                let mut next = [0; 25];
                for d in k..(k + 1) {
                    for (i, dp) in dp.iter().enumerate() {
                        next[(i * 10 + d) % 25] += *dp;
                    }
                }
                dp = next;
            }
        }
        ans += dp[0];
    }
    println!("{}", ans);
}

fn main() {
    run();
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::Read;

#[allow(dead_code)]
fn getline() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok().unwrap();
    ret
}

fn get_word() -> String {
    let stdin = std::io::stdin();
    let mut stdin=stdin.lock();
    let mut u8b: [u8; 1] = [0];
    loop {
        let mut buf: Vec<u8> = Vec::with_capacity(16);
        loop {
            let res = stdin.read(&mut u8b);
            if res.unwrap_or(0) == 0 || u8b[0] <= b' ' {
                break;
            } else {
                buf.push(u8b[0]);
            }
        }
        if buf.len() >= 1 {
            let ret = String::from_utf8(buf).unwrap();
            return ret;
        }
    }
}

#[allow(dead_code)]
fn get<T: std::str::FromStr>() -> T { get_word().parse().ok().unwrap() }

fn main() {
    let s: Vec<char> = get_word().chars().collect();
    let mut ans = 0;
    for i in 0..4_000_000 {
        let t: Vec<_> = format!("{}", 25 * i).chars().collect();
        if s.len() == t.len() {
            let mut x = 0;
            let mut ok = true;
            for i in 0..s.len() {
                if s[i] != t[i] && s[i] != '_' && s[i] != 'X' {
                    ok = false;
                    break;
                }
                if s[i] == 'X' {
                    let idx = t[i] as u8 - b'0';
                    x |= 1 << idx;
                }
            }
            if ok && (x & -x) == x {
                ans += 1;
            }
        }
    }
    println!("{}", ans);
}


use std::cmp::*;
use std::collections::*;

struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> IO<R, W> {
        IO(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write_all(s.to_string().as_bytes()).unwrap();
    }
    pub fn writeln<S: ToString>(&mut self, s: S) {
        self.write(format!("{}\n", s.to_string()));
    }
    pub fn writevec<T: ToString>(&mut self, v: &[T]) {
        let s = v
            .iter()
            .map(|x| x.to_string())
            .collect::<Vec<_>>()
            .join(" ");
        self.writeln(format!("{} ", &s));
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn usize(&mut self) -> usize {
        self.read::<usize>()
    }
    pub fn i32(&mut self) -> i32 {
        self.read::<i32>()
    }
    pub fn i64(&mut self) -> i64 {
        self.read::<i64>()
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn vecn<T: std::str::FromStr>(&mut self) -> Vec<T> {
        let n: usize = self.read();
        self.vec(n)
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}

fn pow(mut a: i64, mut b: i64) -> i64 {
    let mut r = 1;
    loop {
        if b & 1 == 1 {
            r *= a;
        }
        b >>= 1;
        if b == 0 {
            break;
        }
        a *= a;
    }
    r
}

fn solve_one(s: Vec<char>) -> i64 {
    if ["__".to_owned(), "_X".to_owned()].contains(&s.iter().collect::<String>()) {
        return 3;
    }
    if s.len() == 1 {
        return if "0_X".contains(s[0]) { 1 } else { 0 };
    }
    if s[0] == '0' {
        return 0;
    }

    let l = s[s.len() - 1];
    let k = s[s.len() - 2];

    let mut combs = HashMap::new();

    if !"05_X".contains(l) {
        return 0;
    }
    if l == '0' || l == '_' {
        if !"05_X".contains(k) {
            if l != '_' {
                return 0;
            }
        } else if k == 'X' {
            *combs.entry(Some(5)).or_insert(0) += 1;
            if s[0] != 'X' {
                *combs.entry(Some(0)).or_insert(0) += 1;
            }
        } else {
            *combs.entry(None).or_insert(0) += if k == '_' { 2 } else { 1 };
        }
    }
    if l == '5' || l == '_' {
        if !"27_X".contains(k) {
            if l != '_' {
                return 0;
            }
        } else if k == 'X' {
            *combs.entry(Some(2)).or_insert(0) += 1;
            *combs.entry(Some(7)).or_insert(0) += 1;
        } else {
            *combs.entry(None).or_insert(0) += if k == '_' { 2 } else { 1 };
        }
    }
    if l == 'X' {
        if k == '0' || k == '5' {
            if s[0] != 'X' {
                *combs.entry(Some(0)).or_insert(0) += 1;
            }
        } else if k == '2' || k == '7' {
            *combs.entry(Some(5)).or_insert(0) += 1;
        } else if k == '_' {
            if s[0] != 'X' {
                *combs.entry(Some(0)).or_insert(0) += if s.len() == 2 { 1 } else { 2 };
            }
            *combs.entry(Some(5)).or_insert(0) += 2;
        } else if k == 'X' {
            if s[0] != 'X' {
                *combs.entry(Some(0)).or_insert(0) += 1;
            }
        } else {
            return 0;
        }
    }

    let b = s[..s.len() - 2].to_vec();
    let u = b.iter().filter(|&&c| c == '_').count();
    let x = b.iter().filter(|&&c| c == 'X').count();

    let mut count = 0;

    for (xv, cnt) in combs {
        let a = match xv {
            Some(p) => u,
            None => u + if x > 0 { 1 } else { 0 },
        } as i64;

        let mut ch = pow(10, a);
        if s[0] == '_' && s.len() > 2 || xv.is_none() && s[0] == 'X' {
            ch = ch / 10 * 9;
        }

        count += ch * cnt;
    }

    count
}

// Wtf is this.......

pub fn main() {
    let mut sc = IO::new(std::io::stdin(), std::io::stdout());
    let ans = solve_one(sc.chars());
    sc.writeln(ans);
}


use std::cmp::*;
use std::collections::*;

struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> IO<R, W> {
        IO(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write_all(s.to_string().as_bytes()).unwrap();
    }
    pub fn writeln<S: ToString>(&mut self, s: S) {
        self.write(format!("{}\n", s.to_string()));
    }
    pub fn writevec<T: ToString>(&mut self, v: &[T]) {
        let s = v
            .iter()
            .map(|x| x.to_string())
            .collect::<Vec<_>>()
            .join(" ");
        self.writeln(format!("{} ", &s));
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn usize(&mut self) -> usize {
        self.read::<usize>()
    }
    pub fn i32(&mut self) -> i32 {
        self.read::<i32>()
    }
    pub fn i64(&mut self) -> i64 {
        self.read::<i64>()
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn vecn<T: std::str::FromStr>(&mut self) -> Vec<T> {
        let n: usize = self.read();
        self.vec(n)
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}

fn pow(mut a: i64, mut b: i64) -> i64 {
    let mut r = 1;
    loop {
        if b & 1 == 1 {
            r *= a;
        }
        b >>= 1;
        if b == 0 {
            break;
        }
        a *= a;
    }
    r
}

fn solve_one(s: Vec<char>) -> i64 {
    if ["__".to_owned(), "_X".to_owned()].contains(&s.iter().collect::<String>()) {
        return 3;
    }
    if s.len() == 1 {
        return if "0_X".contains(s[0]) { 1 } else { 0 };
    }
    if s[0] == '0' {
        return 0;
    }

    let l = s[s.len() - 1];
    let k = s[s.len() - 2];

    // println!("l: {}, k: {}", l, k);

    let mut combs = HashMap::new();

    if !"05_X".contains(l) {
        return 0;
    }
    if l == '0' || l == '_' {
        if !"05_X".contains(k) {
            if l != '_' {
                return 0;
            }
        } else if k == 'X' {
            *combs.entry(Some(5)).or_insert(0) += 1;
            if s[0] != 'X' {
                *combs.entry(Some(0)).or_insert(0) += 1;
            }
        } else {
            *combs.entry(None).or_insert(0) += if k == '_' { 2 } else { 1 };
        }
    }
    if l == '5' || l == '_' {
        if !"27_X".contains(k) {
            if l != '_' {
                return 0;
            }
        } else if k == 'X' {
            *combs.entry(Some(2)).or_insert(0) += 1;
            *combs.entry(Some(7)).or_insert(0) += 1;
        } else {
            *combs.entry(None).or_insert(0) += if k == '_' { 2 } else { 1 };
        }
    }
    if l == 'X' {
        if k == '0' || k == '5' {
            if s[0] != 'X' {
                *combs.entry(Some(0)).or_insert(0) += 1;
            }
        } else if k == '2' || k == '7' {
            *combs.entry(Some(5)).or_insert(0) += 1;
        } else if k == '_' {
            if s[0] != 'X' {
                *combs.entry(Some(0)).or_insert(0) += if s.len() == 2 { 1 } else { 2 };
            }
            *combs.entry(Some(5)).or_insert(0) += 2;
        } else if k == 'X' {
            if s[0] != 'X' {
                *combs.entry(Some(0)).or_insert(0) += 1;
            }
        } else {
            return 0;
        }
    }

    let b = s[..s.len() - 2].to_vec();
    let u = b.iter().filter(|&&c| c == '_').count();
    let x = b.iter().filter(|&&c| c == 'X').count();

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

    // let c = pow(10, (u + if) as i64);

    let mut count = 0;

    for (xv, cnt) in combs {
        let a = match xv {
            Some(p) => u,
            None => u + if x > 0 { 1 } else { 0 },
        } as i64;

        let mut ch = pow(10, a);
        if s[0] == '_' && s.len() > 2 || xv == None && s[0] == 'X' {
            ch = ch / 10 * 9;
        }

        count += ch * cnt;
    }

    count
}

pub fn main() {
    let mut sc = IO::new(std::io::stdin(), std::io::stdout());
    let ans = solve_one(sc.chars());
    sc.writeln(ans);
}


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

fn load() -> Vec<i64> {
    let mut line = String::new();
    io::stdin().read_line(&mut line).expect("Failed to read line");
    let vec: Vec<&str> = line.split(" ").collect();
    let mut data : Vec<i64> = Vec::new();
    for i in vec {
        let el : i64 = i.trim().parse().unwrap();
        data.push(el);
    }
    data
}
fn maxv(v : &Vec<i64>) -> i64{
    let mut s=v[0];
    for i in v {s=max(s,*i);}
    return s;
}
fn minv(v : &Vec<i64>) -> i64{
    let mut s=v[0];
    for i in v {s=min(s,*i);}
    return s;
}

fn main() {
    let a = load();
    let n=a[0];
    let k=a[1];
    let t=240-k;
    let mut sum = 0;
    let mut last = 0;
    for i in 1..n+1 {
        sum+=i*5;
        if sum > t {break;}
        last = i;
    }
    println!("{}", last);
}
// min, max
// HashSet, insert, contains
// Vec, len, sort
// primitive retype: i as f64


use std::io;

fn main() -> std::io::Result<()> {
    let stdin = io::stdin();
    let mut input = String::new();
    stdin.read_line(&mut input)?;
    let problems_travel: Vec<i16> = input.trim().split(" ").map(|x| x.parse::<i16>().unwrap()).collect();
    let mut minutes_left: i16 = 240 - problems_travel[1];
    for p in 1..=problems_travel[0] {
        if minutes_left - p * 5 < 0 {
            print!("{}", p-1);
            break;
        } else if p == problems_travel[0] {print!("{}",p);}
        else {
            minutes_left -= p * 5;
        }
    }

    Ok(())
}


#[allow(dead_code)]
use std::cmp::min;
use std::collections::HashMap;
use std::io;
use std::str::FromStr;
use std::io::Read;

struct Input {
  tokens: <std::vec::Vec<std::string::String> as IntoIterator>::IntoIter,
  read_all: bool,
}

impl Input {
  pub fn new(read_all: bool) -> Input {
    if read_all {
      let mut all = String::new();
      io::stdin().read_to_string(&mut all).unwrap();
      let tokens: Vec<String> = all.split_whitespace().map(|s| s.to_string()).collect();
      Input {
        tokens: tokens.into_iter(),
        read_all: true,
      }
    } else {
      Input {
        tokens: vec!().into_iter(),
        read_all: false,
      }
    }
  }

  fn refresh_next_line(&mut self) {
    if self.read_all {
      panic!();
    }
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    let tokens: Vec<String> = buf.split_whitespace().map(|s| s.to_string()).collect();
    self.tokens = tokens.into_iter();
  }

  fn next_impl(&mut self) -> String {
    loop {
      if let Some(next) = self.tokens.next() {
        return next.to_string();
      }
      self.refresh_next_line();
    }
  }

  pub fn next<T: FromStr>(&mut self) -> T where <T as std::str::FromStr>::Err: std::fmt::Debug {
    let next_str = self.next_impl();
    next_str.parse().unwrap()
  }

  pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> where <T as std::str::FromStr>::Err: std::fmt::Debug {
    (0..len).map(|_i| self.next()).collect()
  }

  pub fn next_vec_read_len<T: FromStr>(&mut self) -> Vec<T> where <T as std::str::FromStr>::Err: std::fmt::Debug {
    let len = self.next();
    self.next_vec(len)
  }
}

fn main() {
  let mut input = Input::new(false);
  let n: i64 = input.next();
  let k: i64 = input.next();
  let mut time = 240 - k;
  let mut i = 1;
  while time >= i * 5 && i <= n {
    time -= i * 5;
    i += 1
  }
  println!("{}", i - 1);

}


// {{{ by shik

use std::io;

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

#[allow(unused_macros)]
macro_rules! R {
    ( $ty:ty, ... ) => {
        gets().split_whitespace().map(|x| x.parse::<$ty>().unwrap()).collect::<Vec<_>>()
    };
    ( $($ty:ty),* ) => {{
        let line = gets();
        let mut it = line.split_whitespace();
        ( $(it.next().unwrap().parse::<$ty>().unwrap(),)* )
    }}
}

#[allow(unused_macros)]
macro_rules! W {
    ( $x:expr ) => {{
        println!("{}", $x);
    }};
    ( $x:expr, $($xs:expr),* ) => {{
        print!("{} ", $x);
        W!($($xs),*);
    }}
}

#[allow(unused_macros)]
macro_rules! join {
    ($x:expr, $($xs:expr),*; $sep:expr) => { concat!($x, $($sep, $xs),*) }
}

#[allow(unused_macros)]
macro_rules! dump {
    ($($x:expr),*) => {
        eprintln!(join!($(concat!(stringify!($x), " = {:?}")),*; ", "), $($x),*);
    }
}

// }}}

fn main() {
    let (n, k) = R!(usize, usize);
    let mut kk = k;
    let mut ans = 0;
    for i in 1..(n+1) {
        if i*5 + kk > 240 {
            break;
        } else {
            ans = i;
            kk += i*5;
        }
    }
    println!("{}", ans);
}


use std::io::*;

fn reads<T: std::str::FromStr>(i: &mut StdinLock) -> Vec<T> {
    let mut s = String::new();
    i.by_ref().read_line(&mut s).ok();
    s.trim()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

enum Status {
    NotFound,
    Found(u32),
}

fn main() {
    // initialize stdin
    let sin = std::io::stdin();
    let mut sin = sin.lock();
    let sin = &mut sin;

    let params: Vec<u32> = reads(sin);

    let n = params[0];
    let k = params[1];

    let time_limit = 240 - k;
    let mut time_spend = 0;

    let mut status = Status::NotFound;

    for i in 1..n + 1 {
        time_spend += 5 * i;
        if time_limit < time_spend {
            status = Status::Found(i - 1);
            break;
        }
    }

    let ans = match status {
        Status::Found(x) => x,
        Status::NotFound => n,
    };

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


#[allow(unused_imports)]
use std::io::{self, stdout, BufWriter, stdin, Write};
#[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 scan = Scanner::default();
    let out = &mut BufWriter::new(stdout());
    let n:i32 = scan.next();
    let mut k:i32 = 240 - scan.next::<i32>();
    let mut count = 0;
    for i in 1..n+1{
        if k - (5*i) < 0{break;} else {k -= 5*i; count += 1;}
    }
    writeln!(out, "{}", count).ok();
}


type Pair = (u8, u8);
fn input_pair() -> Pair {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    let buf: Vec<u8> = buf.trim().split_whitespace().map(|elem| elem.parse().unwrap()).collect();
    (buf[0], buf[1])
}

fn main() {
    let (n, k) = input_pair();

    let mut time_left = 240 - k;
    let mut result = 0;

    for i in 1..=n {
        if 5 * i <= time_left {
            time_left -= 5*i;
            result += 1;
        } else {
            break;
        }
    }

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


// https://codeforces.com/problemset/problem/750/A
use std::io;

fn cumulative(n: i64) -> i64 {
    let mut sum = 0;
    for i in 1..n+1 {
        sum += i*5;
    }
    sum
}

fn main() {
    let mut line = String::new();

    io::stdin()
        .read_line(&mut line)
        .unwrap();

    let words: Vec<i64> =
        line
        .split_whitespace()
        .map(|x| x.parse().unwrap())
        .collect();

    let n = words[0];
    let k = words[1];

    let mut left = 0;
    let mut right = n;

    while left <= right {
        let middle = (right+left)/2;
        if (cumulative(middle)+k) <= 240 {
            left = middle+1;
        } else {
            right = middle-1;
        }
    }
    println!("{}", right);
}


use std::io::stdin;
use std::collections::VecDeque;

macro_rules! input{
    ( $s: expr, $t:ty ) => {
        {
            $s.clear();
            let mut _stdin = stdin();
            _stdin.read_line(&mut $s).unwrap();
            $s.trim().parse::<$t>().unwrap()
        }
    };
    ( $s: expr, $($t:ty),* ) => {
        {
            $s.clear();
            let mut _stdin = stdin();
            _stdin.read_line(&mut $s).unwrap();
            let mut iterator = $s.trim().split_whitespace();
            let result = ($(iterator.next().unwrap().parse::<$t>().unwrap(),)*);
            assert!(iterator.next().is_none());
            result
        }
    };
}

const LIM: usize = 20001;

fn main() {
    let mut s = String::new();
    let (n, m) = input!(s, usize, usize);

    let mut memo = vec![-1; LIM];
    let mut queue = VecDeque::new();
    memo[n] = 0;
    queue.push_back(n);
    while let Some(i) = queue.pop_front() {
        if memo[m] != -1 {
            println!("{}", memo[m]);
            return;
        }
        if 2 * i < LIM && memo[2 * i] == -1 {
            queue.push_back(2 * i);
            memo[2 * i] = memo[i] + 1;
        }
        if i > 0 && memo[i - 1] == -1 {
            queue.push_back(i - 1);
            memo[i - 1] = memo[i] + 1;
        }
    }
}


// use std::io::{self, Read};
use std::collections::VecDeque;

fn main() {
    let cin = std::io::stdin();
    let mut s = String::new();
    cin.read_line(&mut s).unwrap();
    let values = s
        .split_whitespace()
        .map(|x| x.parse::<usize>())
        .collect::<Result<Vec<usize>, _>>()
        .unwrap();

    let n = values[0];
    let m = values[1];

    let mut visited: [i32; 100000] = [0; 100000];
    let mut queue = VecDeque::new();
    queue.push_back((n, 0));
    while !queue.is_empty() {
        if let Some((curr_val, curr_cost)) = queue.pop_front() {
            if visited[curr_val] == 1 {
                continue;
            }

            if curr_val == m {
                println!("{}", curr_cost);
                return;
            }

            visited[curr_val] = 1;

            if curr_val - 1 > 0 {
                queue.push_back((curr_val - 1, curr_cost + 1));
            }

            if curr_val < 2 * m {
                queue.push_back((curr_val * 2, curr_cost + 1));
            }
        }
    }
}


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 dfs_moves(acc: usize, current: usize, goal: usize, dist: &mut [usize;20000]) {
    if dist[current]<=acc { return; }
    dist[current] = acc;
    if current >= goal {
        dist[goal] = dist[goal].min(acc+current-goal);
        return;
    }
    dfs_moves(acc + 1, current*2, goal, dist);
    if current > 1 {
        dfs_moves(acc + 1, current-1, goal, dist);
    }
}

fn _main() {
    let mut scan = Scan::new();
    let n: usize = scan.next();
    let m: usize = scan.next();
    if m<= n {
        println!("{}", n - m);
        return;
    }
    let mut dist = [std::usize::MAX; 20000];
    dfs_moves(0, n, m, &mut dist);
    println!("{}", dist[m]);
}

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


use std::io::stdin;
use std::cmp::min;
use std::collections::HashMap;
use std::collections::hash_map::Entry;

fn explore(visited: &mut HashMap<i32, i32>, start: i32, finish: i32, dist: i32) -> i32 {
	match visited.entry(start) {
		Entry::Occupied(mut o) => {
			if o.get() > &dist {
				o.insert(dist);
			} else {
				return std::i32::MAX;
			}
		},

		Entry::Vacant(v) => {
			v.insert(dist);
		}
	}

	if start >= finish {
		dist + start - finish
	} else if start == 1 {
		explore(visited, 2, finish, dist + 1)
	} else {
		min(
			explore(visited, start - 1, finish, dist + 1),
			explore(visited, start * 2, finish, dist + 1)
		)
	}
}

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

	let mut it = input.split_whitespace();
	let n: i32 = it.next().unwrap().parse().unwrap();
	let m: i32 = it.next().unwrap().parse().unwrap();

	let mut map: HashMap<i32, i32> = HashMap::new();

	let res = explore(&mut map, n, m, 0);
	println!("{}", res);
}


const ARRAY_SIZE: usize = 20000;

fn update_array(f: &mut [Option<usize>; ARRAY_SIZE], x: usize, m: usize, x_stack: &mut Vec<usize>) {
    if x == 0 {
        return;
    }

    if x >= ARRAY_SIZE {
        return;
    }

    let old_value: Option<usize> = f[x];
    let mut new_value: Option<usize> = old_value;
    if x == m {
        new_value = Some(0);
    } else {
        if x > 1 {
            let value_sub1: Option<usize> = f[x + 1];
            if let Some(value_sub1_real) = value_sub1 {
                if let Some(new_value_real) = new_value {
                    if (value_sub1_real + 1) < new_value_real {
                        new_value = Some(value_sub1_real + 1);
                    }
                } else {
                    new_value = Some(value_sub1_real + 1);
                }
            }
        }

        if (x % 2) == 0 {
            let value_mul2: Option<usize> = f[x / 2];
            if let Some(value_mul2_real) = value_mul2 {
                if let Some(new_value_real) = new_value {
                    if (value_mul2_real + 1) < new_value_real {
                        new_value = Some(value_mul2_real + 1);
                    }
                } else {
                    new_value = Some(value_mul2_real + 1);
                }
            }
        }
    }

    f[x] = new_value;

    if new_value != old_value {
        x_stack.push(x - 1);
        x_stack.push(x * 2);
    }
}

fn get_min_path_length(m: usize, n: usize) -> usize {
    if m > n {
        return m - n;
    }

    let mut f: [Option<usize>; ARRAY_SIZE] = [None; ARRAY_SIZE];

    let mut x_stack: Vec<usize> = vec![m];

    while let Some(x) = x_stack.pop() {
        update_array(&mut f, x, m, &mut x_stack);
    }

    return f[n].unwrap();
}

#[cfg(test)]
mod tests {
    use super::get_min_path_length;

    #[test]
    fn test1() {
        assert_eq!(get_min_path_length(4, 6), 2);
    }
    #[test]
    fn test2() {
        assert_eq!(get_min_path_length(10, 1), 9);
    }
    #[test]
    fn test3() {
        assert_eq!(get_min_path_length(100, 196), 3);
    }
}

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

fn main() {
    let stdin = stdin();
    let mut stdin_lock = stdin.lock();

    let mut values_string: String = String::new();
    stdin_lock.read_line(&mut values_string).unwrap();
    let values_vec: Vec<usize> = values_string
        .trim()
        .split_whitespace()
        .map(|s| s.parse().unwrap())
        .collect();

    let m: usize = values_vec[0];
    let n: usize = values_vec[1];

    let result: usize = get_min_path_length(m, n);

    let stdout = stdout();
    let mut stdout_lock = stdout.lock();

    writeln!(stdout_lock, "{}", result).unwrap();
}


#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![allow(unused_mut)]
#![allow(unused_variables)]
#![allow(dead_code)]

#[allow(unused_macros)]
macro_rules! invec {
    ( $ t : ty ) => {{
        let mut s = String::new();
        match std::io::stdin().read_line(&mut s) {
            Ok(0) => Vec::<$t>::new(),
            Ok(n) => s
                .trim()
                .split_whitespace()
                .map(|s| s.parse::<$t>().unwrap())
                .collect::<Vec<$t>>(),
            Err(_) => Vec::<$t>::new(),
        }
    }};
}

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

#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

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

#[allow(unused_macros)]
macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($next:expr, [$t:tt]) => {
        {
            let len = read_value!($next, usize);
            (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
        }
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_macros)]
#[cfg(debug_assertions)]
macro_rules! mydbg {
    //($arg:expr) => (dbg!($arg))
    //($arg:expr) => (println!("{:?}",$arg));
      ($($a:expr),*) => {
          eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
      }
}
#[cfg(not(debug_assertions))]
macro_rules! mydbg {
    ($($arg:expr),*) => {};
}

macro_rules! echo {
    ($($a:expr),*) => {
          $(println!("{}",$a))*
      }
}

use std::cmp::*;
use std::collections::*;
use std::ops::{Add, Div, Mul, Sub};

#[allow(dead_code)]
static INF_I64: i64 = i64::max_value() / 2;
#[allow(dead_code)]
static INF_I32: i32 = i32::max_value() / 2;
#[allow(dead_code)]
static INF_USIZE: usize = usize::max_value() / 2;
#[allow(dead_code)]
static M_O_D: usize = 1000000007;
#[allow(dead_code)]
static PAI: f64 = 3.1415926535897932;

trait IteratorExt: Iterator {
    fn toVec(self) -> Vec<Self::Item>;
}

impl<T: Iterator> IteratorExt for T {
    fn toVec(self) -> Vec<Self::Item> {
        self.collect()
    }
}

trait CharExt {
    fn toNum(&self) -> usize;
    fn toAlphabetIndex(&self) -> usize;
    fn toNumIndex(&self) -> usize;
}
impl CharExt for char {
    fn toNum(&self) -> usize {
        return *self as usize;
    }
    fn toAlphabetIndex(&self) -> usize {
        return self.toNum() - 'a' as usize;
    }
    fn toNumIndex(&self) -> usize {
        return self.toNum() - '0' as usize;
    }
}

trait VectorExt {
    fn joinToString(&self, s: &str) -> String;
}
impl<T: ToString> VectorExt for Vec<T> {
    fn joinToString(&self, s: &str) -> String {
        return self
            .iter()
            .map(|x| x.to_string())
            .collect::<Vec<_>>()
            .join(s);
    }
}

trait StringExt {
    fn get_reverse(&self) -> String;
}
impl StringExt for String {
    fn get_reverse(&self) -> String {
        self.chars().rev().collect::<String>()
    }
}

trait UsizeExt {
    fn pow(&self, n: usize) -> usize;
}
impl UsizeExt for usize {
    fn pow(&self, n: usize) -> usize {
        return ((*self as u64).pow(n as u32)) as usize;
    }
}

fn main() {
    let (n, m) = get!(usize, usize);
    let mut kouho = VecDeque::new();
    kouho.push_back((n, 0));
    let mut used = vec![true; 10004 * 2];
    while !kouho.is_empty() {
        let (a, depth) = kouho.pop_front().unwrap();
        //mydbg!(a);
        if a == m {
            echo!(depth);
            return;
        }
        if a - 1 != 0 && used[a - 1] {
            kouho.push_back((a - 1, depth + 1));
            used[a - 1] = false;
        }
        if a * 2 < m * 2 + 1 && used[a * 2] {
            kouho.push_back((a * 2, depth + 1));
            used[a * 2] = false;
        }
    }
}


fn readln() -> Vec<i32> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();

    line.split_whitespace()
        .map(|s| s.parse().unwrap())
        .collect()
}

const MAX_N: i32 = 20000;
const INF: i32 = 10000;

fn main() {
    let input = readln();
    let n = input[0];
    let m = input[1];

    let mut count_clicks: [i32; (MAX_N + 1) as usize] = [INF; (MAX_N + 1) as usize];
    let mut queue: Vec<i32> = vec![n];
    count_clicks[n as usize] = 0;

    let mut i: usize = 0;
    while i < queue.len() {
        let number = queue[i] as i32;
        let index = number as usize;

        if number  - 1 >= 0 && count_clicks[index - 1] > count_clicks[index] + 1 {
            count_clicks[index - 1] = count_clicks[index] + 1;
            queue.push(number - 1);
        }

        if number * 2 <= MAX_N && count_clicks[index * 2] > count_clicks[index] + 1 {
            count_clicks[index * 2] = count_clicks[index] + 1;
            queue.push(number * 2);
        }

        i += 1;
    }

    println!("{}", count_clicks[m as usize]);
}


#![allow(non_snake_case, unused_imports)]

// Input macros
macro_rules! input { (source = $s:expr, $($r:tt)*) => { let mut iter = $s.split_whitespace(); let mut next = || { iter.next().unwrap() }; input_inner!{next, $($r)*} }; ($($r:tt)*) => { let stdin = std::io::stdin(); let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); let mut next = move || -> String{ bytes.by_ref().map(|r|r.unwrap() as char).skip_while(|c|c.is_whitespace()).take_while(|c|!c.is_whitespace()).collect() }; input_inner!{next, $($r)*} }; }
macro_rules! input_inner { ($next:expr) => {}; ($next:expr, ) => {}; ($next:expr, $var:ident : $t:tt $($r:tt)*) => { let $var = read_value!($next, $t); input_inner!{$next $($r)*} }; ($next:expr, mut $var:ident : $t:tt $($r:tt)*) => { let mut $var = read_value!($next, $t); input_inner!{$next $($r)*} }; }
macro_rules! read_value { ($next:expr, ( $($t:tt),* )) => { ( $(read_value!($next, $t)),* ) }; ($next:expr, [ $t:tt ; $len:expr ]) => { (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>() }; ($next:expr, [ $t:tt ]) => { { let len = read_value!($next, usize); (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>() } }; ($next:expr, chars) => { read_value!($next, String).chars().collect::<Vec<char>>() }; ($next:expr, bytes) => { read_value!($next, String).into_bytes() }; ($next:expr, usize1) => { read_value!($next, usize) - 1 }; ($next:expr, $t:ty) => { $next().parse::<$t>().expect("Parse error") }; }

// Module
use std::cmp::{min,max};
use std::collections::{HashSet,HashMap,VecDeque,BinaryHeap};

// Functions

// Main
fn main(){
    input!{
        N: usize,
        mut M: usize
    }
    let mut ans = 0;
    while M>N{
        if M%2==0{
            M = M/2;
            ans += 1;
        }else{
            M += 1;
            ans += 1;
        }
    }
    ans += N-M;
    println!("{}", ans);
}


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

fn compare(x: i32, y: i32) -> i32 {
    if x == y {
        return 0;
    }
    if (x == 2 && y == 4) || (x == 4 && y == 2) {
        return 0;
    }

    if x <= 3 && y <= 3 {
        return if x < y { -1 } else { 1 };
    }
    if x >= 3 && y >= 3 {
        return if x < y { 1 } else { -1 };
    }

    if x == 1 {
        return -1;
    }
    if y == 1 {
        return 1;
    }

    if x <= 3 { 1 } else { -1 }
}

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

    let tokens: Vec<&str> = input.split_whitespace().collect();
    let x = tokens[0].parse::<i32>().unwrap();
    let y = tokens[1].parse::<i32>().unwrap();

    match compare(x, y) {
        -1 => println!("<"),
         0 => println!("="),
         1 => println!(">"),
         _ => println!("This shouldn't happen...")
    };
}


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

    let mut it = input.split_whitespace();

    let x: u32 = it.next().unwrap().parse().unwrap();
    let y: u32 = it.next().unwrap().parse().unwrap();

    // x^y <?> y^x
    // exp(y * ln(x)) <?> exp(x * ln(y))
    // y * ln(x) <?> x * ln(y)
    // ln(x) / x <?> ln(y) / y

    fn f_cmp(a: u32, b: u32) -> ::std::cmp::Ordering {
        use std::cmp::{self, Ordering};

        if a == b {
            Ordering::Equal
        } else if a == 1 {
            Ordering::Less
        } else if b == 1 {
            Ordering::Greater
        } else if a == 3 {
            Ordering::Greater
        } else if b == 3 {
            Ordering::Less
        } else if a == 2 || a == 4 {
            if b == 2 || b == 4 {
                Ordering::Equal
            } else {
                Ordering::Greater
            }
        } else if b == 2 || b == 4 {
            Ordering::Less
        } else {
            b.cmp(&a)
        }
    }

    let ans = f_cmp(x, y);
    use std::cmp::Ordering;
    let txt = match ans {
        Ordering::Less => '<',
        Ordering::Equal => '=',
        Ordering::Greater => '>',
    };

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


use std::cmp;
use std::io;

fn main() {
    let mut mut_line = String::new();
    io::stdin().read_line(&mut mut_line).unwrap();
    let mut iter = mut_line.trim().split(" ").map(|x| x.parse().unwrap());
    let (x, y): (u64, u64) = (iter.next().unwrap(), iter.next().unwrap());
    if x == y {
        println!("=");
        return;
    }
    let mini = cmp::min(x, y);
    let other = x + y - mini;
    let mut result = if mini >= 3 {
        cmp::Ordering::Greater
    } else if mini == 1 {
        cmp::Ordering::Less
    } else {
        // mini == 2
        if other == 3{
            cmp::Ordering::Less
        } else if other == 4 {
            cmp::Ordering::Equal
        }
        else{
            cmp::Ordering::Greater
        }
    };
    if mini == y {
        result = cmp::Ordering::reverse(result);
    }
    match result{
        cmp::Ordering::Less => println!("<"),
        cmp::Ordering::Equal => println!("="),
        cmp::Ordering::Greater => println!(">")
    }
}


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

    let mut it = input.split_whitespace();

    let x: u32 = it.next().unwrap().parse().unwrap();
    let y: u32 = it.next().unwrap().parse().unwrap();

    // x^y <?> y^x
    // exp(y * ln(x)) <?> exp(x * ln(y))
    // y * ln(x) <?> x * ln(y)
    // ln(x) / x <?> ln(y) / y

    struct F {
        x: u32,
    }

    use std::cmp::{Ordering, self};

    impl PartialEq for F {
        fn eq(&self, other: &F) -> bool {
            match (self.x, other.x) {
                (2, 4) | (4, 2) => true,
                (a, b) => a.eq(&b),
            }
        }
    }

    impl Eq for F {}

    impl PartialOrd for F {
        fn partial_cmp(&self, other: &F) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl Ord for F {
        fn cmp(&self, other: &F) -> Ordering {
            match (self.x, other.x) {
                (a, b) if F { x: a } == F { x: b } => Ordering::Equal,
                (3, _) => Ordering::Greater,
                (_, 3) => Ordering::Less,
                (2, _) => Ordering::Greater,
                (_, 2) => Ordering::Less,
                (1, _) => Ordering::Less,
                (_, 1) => Ordering::Greater,
                (a, b) => b.cmp(&a),
            }
        }
    }

    let x = F { x: x };
    let y = F { x: y };
    let ans = x.cmp(&y);
    let txt = match ans {
        Ordering::Less => '<',
        Ordering::Equal => '=',
        Ordering::Greater => '>',
    };

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


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

    let mut it = input.split_whitespace();

    let x: f64 = it.next().unwrap().parse().unwrap();
    let y: f64 = it.next().unwrap().parse().unwrap();

    // x^y <?> y^x
    // exp(y * ln(x)) <?> exp(x * ln(y))
    // y * ln(x) <?> x * ln(y)
    // ln(x) / x <?> ln(y) / y

    let epsilon = 1e-4;

    let diff = x * y.ln() - y * x.ln();

    let ans = if diff.abs() < epsilon {
        '='
    } else if diff > 0.0 {
        '<'
    } else {
        '>'
    };

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


use std::{cell::Cell, cmp::{Reverse, max, min}, collections::{BTreeMap, HashMap, HashSet}, error::Error, fmt::Display, io::{BufWriter, Read, Write}, iter::Peekable, mem::swap, ops::{Not, Range, RangeInclusive, Sub}, process::exit, rc::Rc, str::{FromStr, from_utf8, from_utf8_unchecked}};

const IO_BUF_SIZE: usize = 1 << 16;
struct Scanner<'a, R: Read> {
    src: &'a mut R,
    _buf: Vec<u8>,
    _pt: usize, // pointer
    _rd: usize, // bytes read
}

#[allow(dead_code)]
impl<'a, R: Read> Scanner<'a, R> {
    fn new(src: &'a mut R) -> Scanner<'a, 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 char(&mut self) -> char { self.byte() as char }
    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 token(&mut self) -> String { unsafe { String::from_utf8_unchecked(self.token_bytes()) } }

    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
    }
    fn line(&mut self) -> String { unsafe { String::from_utf8_unchecked(self.line_bytes()) } }

    fn read<T: FromStr>(&mut self) -> T {
        let token = self.token_bytes();
        unsafe { from_utf8_unchecked(&token).parse::<T>().ok().unwrap()  }
    }
    fn vec<T: FromStr>(&mut self, n: usize) -> Vec<T> { (0..n).map(|_| self.read()).collect() }
    fn vec2<T: FromStr>(&mut self, n: usize, m: usize) -> Vec<Vec<T>> { (0..n).map(|_| self.vec(m)).collect() }
}

trait ToCharVec { fn to_char_vec(&self) -> Vec<char>; }
impl ToCharVec for &str { fn to_char_vec(&self) -> Vec<char> { self.chars().collect() } }
impl ToCharVec for String { fn to_char_vec(&self) -> Vec<char> { self.chars().collect() } }
trait JoinToStr {
    fn join_to_str(&mut self, sep: &str) -> String;
    fn concat_to_str(&mut 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();
        match self.next() {
            None => res,
            Some(first) => {
                res.push_str(&first.to_string());
                loop {
                    match self.next() {
                        None => break,
                        Some(item) => {
                            res.push_str(sep);
                            res.push_str(&item.to_string())
                        }
                    }
                }
                res
            }
        }
    }

    fn concat_to_str(&mut 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 }
}

// * end commons * //

mod modint {

    use std::{convert::Infallible, iter::Sum, mem::swap, ops::AddAssign};

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

        fn pow_mod(self, exponent: u64, modulus: u32) -> u32 {
            pow_mod_raw(self.rem_euclid_u32(modulus), exponent, modulus)
        }
        fn mul_mod<Rhs: RemEuclidU32>(self, rhs: Rhs, modulus: u32) -> u32 {
            mul_mod_u32(self.rem_euclid_u32(modulus), rhs.rem_euclid_u32(modulus), modulus)
        }

        fn mod_pow_vec(self, n: usize, modulus: u32) -> Vec<u32> {
            let a = self.rem_euclid_u32(modulus);
            let mut res = vec![0u32; n+1];
            if modulus == 1 { return res; }
            res[0] = 1;
            for i in 1..=n {
                res[i] = mul_mod_u32(a, res[i-1], modulus);
            }
            res
        }
    }

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

    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, undefined otherwise
    pub fn add_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        if b >= m - a { a.wrapping_add(b).wrapping_sub(m) } else { a + b }
    }
    pub fn sub_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        if a < b { a.wrapping_add(m).wrapping_sub(b) } else { a - b }
    }
    pub 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
    pub 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;
            std::mem::swap(&mut s, &mut t);
            std::mem::swap(&mut m0, &mut m1);
        }

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

    #[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
    #[repr(transparent)]
    pub struct ModInt { pub val: u32 }

    impl ModInt {
        #[inline]
        pub fn modulus() -> u32 { crate::get_modulus() }
        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 } }
        pub fn inv(self) -> Self {
            let (x, gcd) = inv_gcd(self.val.into(), Self::modulus().into());
            if gcd != 1 { panic!("the multiplicative inverse {}^-1 mod {} does not exist", self.val, Self::modulus()) }
            Self::raw(x as u32)
        }
        pub fn pow(self, k: u64) -> Self {
            Self::raw(pow_mod_raw(self.val, k, Self::modulus()))
        }
        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 { ModInt::new(val) }

    impl<V: RemEuclidU32> From<V> for ModInt {
        #[inline]
        fn from(from: V) -> Self { Self::new(from) }
    }
    impl std::str::FromStr for ModInt {
        type Err = std::convert::Infallible;
        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 std::fmt::Display for ModInt {
        #[inline]
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            std::fmt::Display::fmt(&self.val, f)
        }
    }
    impl std::fmt::Debug for ModInt {
        #[inline]
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            std::fmt::Debug::fmt(&self.val, f)
        }
    }
    impl std::ops::Neg for ModInt {
        type Output = ModInt;
        fn neg(self) -> Self::Output {
            Self::raw(if self.val == 0 { 0 } else { Self::modulus() - self.val })
        }
    }

    impl std::ops::Add for ModInt {
        type Output = ModInt;
        fn add(self, rhs: Self) -> Self::Output {
            Self::raw(add_mod_raw(self.val, rhs.val, Self::modulus()))
        }
    }
    impl std::ops::Sub for ModInt {
        type Output = ModInt;
        fn sub(self, rhs: Self) -> Self::Output {
            Self::raw(sub_mod_raw(self.val, rhs.val, Self::modulus()))
        }
    }
    impl std::ops::Mul for ModInt {
        type Output = ModInt;
        fn mul(self, rhs: Self) -> Self::Output {
            Self::raw(mul_mod_u32(self.val, rhs.val, Self::modulus()))
        }
    }
    impl std::ops::Div for ModInt {
        type Output = ModInt;
        #[inline]
        fn div(self, rhs: Self) -> Self::Output { self * rhs.inv() }
    }

    impl <I: RemEuclidU32> std::ops::Add<I> for ModInt {
        type Output = ModInt;
        #[inline]
        fn add(self, rhs: I) -> Self::Output { self + Self::new(rhs) }
    }
    impl <I: RemEuclidU32> std::ops::Sub<I> for ModInt {
        type Output = ModInt;
        #[inline]
        fn sub(self, rhs: I) -> Self::Output { self - Self::new(rhs) }
    }
    impl <I: RemEuclidU32> std::ops::Mul<I> for ModInt {
        type Output = ModInt;
        #[inline]
        fn mul(self, rhs: I) -> Self::Output { self * Self::new(rhs) }
    }
    impl <I: RemEuclidU32> std::ops::Div<I> for ModInt {
        type Output = ModInt;
        #[inline]
        fn div(self, rhs: I) -> Self::Output { self / Self::new(rhs) }
    }

    impl std::ops::AddAssign for ModInt {
        #[inline]
        fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; }
    }
    impl std::ops::SubAssign for ModInt {
        #[inline]
        fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; }
    }
    impl std::ops::MulAssign for ModInt {
        #[inline]
        fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; }
    }
    impl std::ops::DivAssign for ModInt {
        #[inline]
        fn div_assign(&mut self, rhs: Self) { *self = *self / rhs; }
    }
    impl <I: RemEuclidU32> std::ops::AddAssign<I> for ModInt {
        #[inline]
        fn add_assign(&mut self, rhs: I) { *self = *self + rhs; }
    }
    impl <I: RemEuclidU32> std::ops::SubAssign<I> for ModInt {
        #[inline]
        fn sub_assign(&mut self, rhs: I) { *self = *self - rhs; }
    }
    impl <I: RemEuclidU32> std::ops::MulAssign<I> for ModInt {
        #[inline]
        fn mul_assign(&mut self, rhs: I) { *self = *self * rhs; }
    }
    impl <I: RemEuclidU32> std::ops::DivAssign<I> for ModInt {
        #[inline]
        fn div_assign(&mut self, rhs: I) { *self = *self / rhs; }
    }

    impl std::iter::Sum for ModInt {
        fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(Self::raw(0), std::ops::Add::add)
        }
    }
    impl std::iter::Product for ModInt {
        fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(1.into(), std::ops::Mul::mul)
        }
    }
}

//const MODULUS: u32 = 998_244_353;
//const MODULUS: u32 = 1_000_000_007;
thread_local! {
    static MODULUS: Cell<u32> = Cell::new(998_244_353);
}
fn get_modulus() -> u32 { MODULUS.with(|x| x.get()) }
fn set_modulus(value: u32) { MODULUS.with(|x| x.set(value)) }
use crate::modint::*;

#[allow(non_snake_case, unused_macros)]
fn main() -> Result<(), Box<dyn Error>> {
    let mut INPUT = std::io::stdin();
    let OUTPUT = std::io::stdout();

    let mut inp = Scanner::new(&mut INPUT);
    let mut out = BufWriter::with_capacity(IO_BUF_SIZE, OUTPUT);

    macro_rules! inp {
        () => { inp.read(); };
        ($t: ty) => { inp.read::<$t>(); };
        ($t: ty, $($tt: ty),*) => { (inp.read::<$t>(), $(inp.read::<$tt>(),)*); };
        [$t: ty; $n: expr] => { inp.vec::<$t>($n); };
    }
    macro_rules! println {
        () => { writeln!(out).unwrap(); };
        ($exp: expr) => { writeln!(out, "{}", $exp).unwrap(); };
        ($fmt: expr, $($arg : tt )*) => { writeln!(out, $fmt, $($arg)*).unwrap(); }
    }
    macro_rules! print {
        ($exp: expr) => { write!(out, "{}", $exp).unwrap(); };
        ($fmt: expr, $($arg : tt )*) => { write!(out, $fmt, $($arg)*).unwrap(); }
    }

    { // solution start
        let num_cases = 1;//inp!(usize);

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

            let mut dp = vec![mi(0); n+1];
            dp[1] = mi(1);
            dp[2] = mi(2);
            for i in 2..n {
                let d = dp[i];
                dp[i+1] += d + d + 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);
        }
    } // solution end

    out.flush()?;
    Ok(())
}


use std::{cell::{Cell, RefCell}, cmp::{Reverse, max, min}, collections::{BTreeMap, BinaryHeap, HashMap, HashSet}, error::Error, fmt::Display, hash::{Hash, Hasher}, io::{BufWriter, Read, Stdin, Stdout, Write}, iter::Peekable, mem::swap, ops::{Not, Sub}, process::exit, rc::Rc, str::{FromStr, from_utf8, from_utf8_unchecked}};

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

struct Unsync<T>(T);
unsafe impl<T> Sync for Unsync<T> {}

type BadLazy<T> = Unsync<RefCell<Option<T>>>;
impl<T> BadLazy<T> {
    const fn new() -> Self { Self(RefCell::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 {
    f(INPUT.0.borrow_mut().get_or_insert_with(_init_input))
}
fn out<F: FnOnce(&mut Output) -> R, R>(f: F) -> R {
    f(OUTPUT.0.borrow_mut().get_or_insert_with(_init_output))
}

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

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

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().unwrap() }
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(&mut self, sep: &str) -> String;
    fn concat_to_str(&mut 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();
        match self.next() {
            None => res,
            Some(first) => {
                res.push_str(&first.to_string());
                loop {
                    match self.next() {
                        None => break,
                        Some(item) => {
                            res.push_str(sep);
                            res.push_str(&item.to_string())
                        }
                    }
                }
                res
            }
        }
    }

    fn concat_to_str(&mut 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 }
}

// * end commons * //

mod modint {

    use std::{convert::Infallible, iter::Sum, mem::swap, ops::AddAssign};

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

        fn pow_mod(self, exponent: u64, modulus: u32) -> u32 {
            pow_mod_raw(self.rem_euclid_u32(modulus), exponent, modulus)
        }
        fn mul_mod<Rhs: RemEuclidU32>(self, rhs: Rhs, modulus: u32) -> u32 {
            mul_mod_u32(self.rem_euclid_u32(modulus), rhs.rem_euclid_u32(modulus), modulus)
        }

        fn mod_pow_vec(self, n: usize, modulus: u32) -> Vec<u32> {
            let a = self.rem_euclid_u32(modulus);
            let mut res = vec![0u32; n+1];
            if modulus == 1 { return res; }
            res[0] = 1;
            for i in 1..=n {
                res[i] = mul_mod_u32(a, res[i-1], modulus);
            }
            res
        }
    }

    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, undefined otherwise
    #[inline]
    pub fn add_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        sub_mod_raw(a, m-b, m)
    }
    #[inline]
    pub 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 }
    }
    pub 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
    pub 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;
            std::mem::swap(&mut s, &mut t);
            std::mem::swap(&mut m0, &mut m1);
        }

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

    #[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
    #[repr(transparent)]
    pub struct ModInt { pub val: u32 }

    impl ModInt {
        #[inline(always)]
        pub fn modulus() -> u32 { crate::get_modulus() }
        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 } }
        pub fn inv(self) -> Self {
            let (x, gcd) = inv_gcd(self.val.into(), Self::modulus().into());
            if gcd != 1 { panic!("the multiplicative inverse {}^-1 mod {} does not exist", self.val, Self::modulus()) }
            Self::raw(x as u32)
        }
        pub fn pow(self, k: u64) -> Self {
            Self::raw(pow_mod_raw(self.val, k, Self::modulus()))
        }
        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 { ModInt::new(val) }

    impl<V: RemEuclidU32> From<V> for ModInt {
        #[inline]
        fn from(from: V) -> Self { Self::new(from) }
    }
    impl std::str::FromStr for ModInt {
        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 std::fmt::Display for ModInt {
        #[inline]
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            std::fmt::Display::fmt(&self.val, f)
        }
    }
    impl std::fmt::Debug for ModInt {
        #[inline]
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            std::fmt::Debug::fmt(&self.val, f)
        }
    }
    impl std::ops::Neg for ModInt {
        type Output = ModInt;

        #[inline]
        fn neg(self) -> Self::Output {
            Self::raw(0) - self
            //Self::raw(norm(self.val.wrapping_neg(), Self::modulus()))
        }
    }

    impl std::ops::Add for ModInt {
        type Output = ModInt;
        #[inline]
        fn add(self, rhs: Self) -> Self::Output {
            Self::raw(add_mod_raw(self.val, rhs.val, Self::modulus()))
        }
    }
    impl std::ops::Sub for ModInt {
        type Output = ModInt;
        #[inline]
        fn sub(self, rhs: Self) -> Self::Output {
            Self::raw(sub_mod_raw(self.val, rhs.val, Self::modulus()))
        }
    }
    impl std::ops::Mul for ModInt {
        type Output = ModInt;
        #[inline]
        fn mul(self, rhs: Self) -> Self::Output {
            Self::raw(mul_mod_u32(self.val, rhs.val, Self::modulus()))
        }
    }
    impl std::ops::Div for ModInt {
        type Output = ModInt;
        #[inline]
        fn div(self, rhs: Self) -> Self::Output { self * rhs.inv() }
    }

    impl <I: RemEuclidU32> std::ops::Add<I> for ModInt {
        type Output = ModInt;
        #[inline]
        fn add(self, rhs: I) -> Self::Output { self + Self::new(rhs) }
    }
    impl <I: RemEuclidU32> std::ops::Sub<I> for ModInt {
        type Output = ModInt;
        #[inline]
        fn sub(self, rhs: I) -> Self::Output { self - Self::new(rhs) }
    }
    impl <I: RemEuclidU32> std::ops::Mul<I> for ModInt {
        type Output = ModInt;
        #[inline]
        fn mul(self, rhs: I) -> Self::Output { self * Self::new(rhs) }
    }
    impl <I: RemEuclidU32> std::ops::Div<I> for ModInt {
        type Output = ModInt;
        #[inline]
        fn div(self, rhs: I) -> Self::Output { self / Self::new(rhs) }
    }

    impl std::ops::AddAssign for ModInt {
        #[inline]
        fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; }
    }
    impl std::ops::SubAssign for ModInt {
        #[inline]
        fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; }
    }
    impl std::ops::MulAssign for ModInt {
        #[inline]
        fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; }
    }
    impl std::ops::DivAssign for ModInt {
        #[inline]
        fn div_assign(&mut self, rhs: Self) { *self = *self / rhs; }
    }
    impl <I: RemEuclidU32> std::ops::AddAssign<I> for ModInt {
        #[inline]
        fn add_assign(&mut self, rhs: I) { *self = *self + rhs; }
    }
    impl <I: RemEuclidU32> std::ops::SubAssign<I> for ModInt {
        #[inline]
        fn sub_assign(&mut self, rhs: I) { *self = *self - rhs; }
    }
    impl <I: RemEuclidU32> std::ops::MulAssign<I> for ModInt {
        #[inline]
        fn mul_assign(&mut self, rhs: I) { *self = *self * rhs; }
    }
    impl <I: RemEuclidU32> std::ops::DivAssign<I> for ModInt {
        #[inline]
        fn div_assign(&mut self, rhs: I) { *self = *self / rhs; }
    }

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

// const MODULUS: u32 = 998_244_353;
// //const MODULUS: u32 = 1_000_000_007;
// #[inline(always)]
// fn get_modulus() -> u32 { MODULUS }

static MODULUS: Unsync<Cell<u32>> = Unsync(Cell::new(0));
#[inline] fn get_modulus() -> u32 { MODULUS.0.get() }
#[inline] fn set_modulus(value: u32) { MODULUS.0.set(value) }

use crate::modint::*;

#[allow(non_snake_case, unused_macros)]
fn main() -> Result<(), Box<dyn Error>> {
    let num_cases = 1;//read!(i32);

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

        let mut dp = vec![mi(0); n+1];
        dp[1] = mi(1);
        dp[2] = mi(2);
        for i in 2..n {
            let d = dp[i];
            dp[i+1] += d + d + 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();
    Ok(())
}