#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(dead_code)]
#![allow(unused_labels)]

use std::char::*;
use std::cmp::*;
use std::collections::*;
use std::io::*;
use std::str::FromStr;

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

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

use std::f64;

fn min<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { a }
    else { b }
}

fn max<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { b }
    else { a }
}

const MAX:usize = 30;
const INF:i64 = std::i64::MAX;
const MOD:i64 = 1e9 as i64 + 7;

struct Graph {
    e: Vec<Vec<usize>>,
    v: Vec<usize>,
    u: Vec<usize>,
    f: Vec<bool>,
    c: i64,
    vc: Vec<i64>,
}

impl Graph {
    fn new(n:usize) -> Self {
        Graph {
            e: vec![vec![];n],
            v: vec![],
            u: vec![n;n],
            f: vec![false;n],
            c: 0,
            vc: vec![0;n],
        }
    }

    fn dfs(&mut self, crt: usize) {
        if self.f[crt] { return; }
        self.c += 1;
        self.f[crt] = true;
        self.v.push(crt);
        self.vc[crt] = self.c;
        self.u[crt] = self.v.len()-1;
        for i in 0..self.e[crt].len() {
            self.dfs(self.e[crt][i]);
        }
        //debug!(crt, self.c, self.vc[crt]);
        self.vc[crt] = self.c - self.vc[crt];
    }
}

fn binary_search(s: &Vec<i64>, v:i64) -> usize {
    let mut left = 0;
    let mut right = s.len();

    while right-left > 1 {
        let mid = (right+left)/2;
        //debug!(left,mid,right,s[mid]);
        if s[mid] < v { left = mid; }
        else { right = mid; }
    }
    left
}

fn main() {
    //let t:usize = read();

    //'outer: for _ in 0..t {
        let n:usize = read();
        let m:usize = read();
        let mut p:Vec<(usize,usize,i64,usize)> = (0..m).map(|i| (read::<usize>()-1,read::<usize>()-1,read(),i)).collect();

        p.sort_by(|a,b| a.0.cmp(&b.0));
        //debug!(p);

        let mut e = vec![m;n];
        let mut c = vec![0;m];
        for i in 0..m {
            e[p[i].1] = i;
            c[p[i].3] = p[i].2;
        }

        let mut idx = 0;
        let mut v = vec![];
        for i in 0..n {
            if e[i] != m {
                if c[e[i]] != 0 {
                    println!("-1");
                    return;
                }
                v.push(m+1);
            }
            else if idx == m {
                v.push(0);
            }
            else if i >= p[idx].0 {
                v.push(p[idx].3+1);
                c[p[idx].3] -= 1;
                if c[p[idx].3] == 0 {
                    idx += 1;
                }
            }
            else {
                v.push(0);
            }
        }
        //debug!(v);
        for e in v {print!("{} ", e);} println!();

    //}
}

/*

*/


//! http://codeforces.com/problemset/problem/815/E

use std::cmp::Ordering;

#[derive(PartialEq)]
struct Segment {
  start: usize,
  len: usize
}

impl Segment {
  fn min_dist(&self) -> usize {
    (self.len + 1) / 2
  }

  fn split(self) -> Box<Iterator<Item=Self>> {
    let mut segments = Vec::new();
    let segment1;
    let segment2;
    if self.len % 2 == 0 {
      segment1 = Segment { start: self.start, len: self.len / 2 - 1 };
      segment2 = Segment { start: self.start + self.len / 2, len: self.len / 2 };
    } else {
      segment1 = Segment { start: self.start, len: self.len / 2 };
      segment2 = Segment { start: self.start + self.len / 2 + 1, len: self.len / 2 };
    }
    if segment1.len > 0 { segments.push(segment1); }
    if segment2.len > 0 { segments.push(segment2); }
    Box::new(segments.into_iter())
  }

  fn house(&self) -> usize {
    if self.len % 2 == 0 {
      self.start + self.len / 2 - 1
    } else {
      self.start + self.len / 2
    }
  }
}

impl PartialOrd for Segment {
  fn partial_cmp(&self, them: &Self) -> Option<Ordering> {
    let (o_len, t_len) = (self.min_dist(), them.min_dist());
    Some(match o_len.cmp(&t_len) {
      Ordering::Less => Ordering::Greater,
      Ordering::Greater => Ordering::Less,
      Ordering::Equal => self.start.cmp(&them.start)
    })
  }
}

fn main() {
  use std::io;
  let mut buf = String::new();
  io::stdin().read_line(&mut buf).unwrap();
  let mut ns = buf.split(" ")
    .map(|str| str.trim().parse::<usize>().unwrap());
  let n = ns.next().unwrap();
  let k = ns.next().unwrap();
  let mut last = 1;
  let mut segments = BinHeap::new();
  for i in 1..k {
    if i == 1 { last = n; segments.insert(Segment { start: 2, len: n - 2 }); }
    else {
      let segment = segments.pop_min()
        .unwrap();
      last = segment.house();
      for s in segment.split() {
        segments.insert(s);
      }
    }
  }
  println!("{}", last);
}

// -----------------------------------------------------------------------------

pub struct BinHeap<T> {
  pub elements: Vec<T>
}

pub fn left_child(i: usize) -> usize { (i * 2) + 1 }
pub fn right_child(i: usize) -> usize { (i * 2) + 2 }
pub fn parent(i: usize) -> usize { i.saturating_sub(1) / 2 }

pub type HeapElementId = usize;

impl<T> BinHeap<T> {
  pub fn new() -> Self {
    BinHeap { elements: Vec::new() }
  }
  pub fn with_capacity(capacity: usize) -> Self {
    BinHeap { elements: Vec::with_capacity(capacity) }
  }
}

impl<T: PartialOrd> BinHeap<T> {
  pub fn min(&self) -> Option<&T> {
    self.elements.first()
  }

  pub fn pop_min(&mut self) -> Option<T> {
    let elements = &mut self.elements;
    if elements.is_empty() { return None; }
    let i = elements.len() - 1;
    elements.swap(0, i);
    let min = elements.pop().unwrap();
    if !elements.is_empty() {
      let mut i = 0;
      let n = elements.len();
      while i < n {
        let (l, r) = (left_child(i), right_child(i));
        let mut swap = i;
        swap = if l < n && elements[l] < elements[swap] { l } else { swap };
        swap = if r < n && elements[r] < elements[swap] { r } else { swap };
        if swap == i { break; }
        elements.swap(i, swap);
        i = swap;
      }
    }
    Some(min)
  }

  pub fn insert(&mut self, element: T) -> HeapElementId {
    let i = self.elements.len();
    self.elements.push(element);
    self.bubble(i)
  }

  pub fn reduce_key(&mut self, key: T, element_id: HeapElementId) -> HeapElementId {
    if key < self.elements[element_id] { self.elements[element_id] = key; }
    self.bubble(element_id)
  }

  fn bubble(&mut self, element_id: HeapElementId) -> HeapElementId {
    let elements = &mut self.elements;
    let mut i = element_id;
    loop {
      let parent = parent(i);
      if i == 0 || elements[parent] < elements[i] { break; }
      elements.swap(i, parent);
      i = parent;
    }
    return i;
  }
}


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

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

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

// ここまで

fn calc(n: u64, k: usize, p: &[u64], map: &mut std::collections::BTreeMap<(u64, usize), u64>) -> u64 {
    if k == 0 {
        return n;
    }
    let a = p[k - 1];
    if a >= n {
        return 0;
    }
    if let Some(&v) = map.get(&(n, k)) {
        return v;
    }
    let val = calc(n, k - 1, p, map) - calc(n / a, k - 1, p, map);
    map.insert((n, k), val);
    val
}

fn run() {
    input! {
        n: u64,
    }
    let m = 1_000_000;
    let mut is_prime = vec![true; m + 1];
    for i in 2.. {
        if i * i > m {
            break;
        }
        if is_prime[i] {
            let mut j = i * i;
            while j <= m {
                is_prime[j] = false;
                j += i;
            }
        }
    }
    let mut p = vec![];
    for (i, b) in is_prime.iter().enumerate().skip(2) {
        if *b {
            p.push(i as u64);
        }
    }
    let mut ans = 0u64;
    for p in p.iter() {
        if p.pow(3) > n {
            break;
        }
        ans += 1;
    }
    let mut map = std::collections::BTreeMap::new();
    for (i, a) in p.iter().enumerate() {
        if *a * p[i + 1] > n {
            break;
        }
        let n = n / a;
        let k = match p.binary_search_by(|p| (*p * *p).cmp(&n)) {
            Ok(k) => k + 1,
            Err(k) => k,
        };
        ans += calc(n, k, &p, &mut map) - 1 + k as u64 - (i + 1) as u64;
    }
    println!("{}", ans);
}

fn main() {
    run();
}


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

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

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

// ここまで

fn calc(n: u64, k: usize, p: &[u64], map: &mut std::collections::BTreeMap<(u64, usize), u64>) -> u64 {
    if k == 0 {
        return n;
    }
    let a = p[k - 1];
    if a >= n {
        return 1;
    }
    if let Some(&v) = map.get(&(n, k)) {
        return v;
    }
    let val = calc(n, k - 1, p, map) - calc(n / a, k - 1, p, map);
    map.insert((n, k), val);
    val
}

fn run() {
    input! {
        n: u64,
    }
    let m = 1_000_000;
    let mut is_prime = vec![true; m + 1];
    for i in 2.. {
        if i * i > m {
            break;
        }
        if is_prime[i] {
            let mut j = i * i;
            while j <= m {
                is_prime[j] = false;
                j += i;
            }
        }
    }
    let mut p = vec![];
    for (i, b) in is_prime.iter().enumerate().skip(2) {
        if *b {
            p.push(i as u64);
        }
    }
    let mut ans = 0u64;
    for p in p.iter() {
        if p.pow(3) > n {
            break;
        }
        ans += 1;
    }
    let mut map = std::collections::BTreeMap::new();
    for (i, a) in p.iter().enumerate() {
        if *a * p[i + 1] > n {
            break;
        }
        let n = n / a;
        let k = match p.binary_search_by(|&p| (p * p).cmp(&n)) {
            Ok(k) => k + 1,
            Err(k) => k,
        };
        ans += calc(n, k, &p, &mut map) - 1 + k as u64 - (i + 1) as u64;
    }
    println!("{}", ans);
}

fn main() {
    run();
}


struct FenwickTree {
    val: Vec<i64>,
}

impl FenwickTree {
    fn new(n: usize) -> Self {
        FenwickTree {
            val: vec![0; n + 1],
        }
    }
    fn add(&mut self, mut x: usize, v: i64) {
        while let Some(p) = self.val.get_mut(x) {
            *p += v;
            x += x & (!x + 1);
        }
    }
    fn sum(&mut self, mut x: usize) -> i64 {
        assert!(x < self.val.len());
        let mut ans = 0;
        while x > 0 {
            ans += self.val[x];
            x -= x & (!x + 1);
        }
        ans
    }
}

fn sieve(n: usize) -> Vec<i64> {
    let mut is_prime = vec![true; n + 1];
    for i in 2.. {
        if i * i > n {
            break;
        }
        if is_prime[i] {
            let mut j = i * i;
            while j <= n {
                is_prime[j] = false;
                j += i;
            }
        }
    }
    let len = is_prime.iter().skip(2).filter(|p| **p).count();
    let mut prime = Vec::with_capacity(len);
    for (i, is_prime) in is_prime.into_iter().enumerate().skip(2) {
        if is_prime {
            prime.push(i as i64);
        }
    }
    prime
}

// N 以下の素数の個数を数える
fn prime_count(n: i64) -> i64 {
    let mut m = 1;
    while (m + 1) * (m + 1) <= n {
        m += 1;
    }
    let p = sieve(m as usize);
    let bound = (n as f64).cbrt().powi(2) as i64 + 2;
    let mut query = vec![];
    let mut stack = vec![(n, p.len())];
    while let Some((n, k)) = stack.pop() {
        if k == 0 {
            continue;
        }
        let q = p[k - 1];
        if q * q > n {
            let x = match p[..k].binary_search_by(|&p| (p * p).cmp(&n)) {
                Ok(k) => k + 1,
                Err(k) => k,
            };
            stack.push((n, x));
        } else if n <= bound {
            query.push((k, n));
        } else {
            stack.push((n, k - 1));
            stack.push((n / q, k - 1));
        }
    }
    query.sort();
    query.dedup();
    let m = bound as usize;
    let mut bit = FenwickTree::new(m);
    for i in 1..=m {
        bit.add(i, 1);
    }
    let mut is_prime = vec![true; m + 1];
    let mut memo = vec![0; query.len()];
    let mut pos = 0;
    for (i, p) in p.iter().enumerate() {
        let p = *p as usize;
        let mut j = p;
        while j <= m {
            if is_prime[j] {
                bit.add(j, -1);
            }
            is_prime[j] = false;
            j += p;
        }
        while let Some(&(k, n)) = query.get(pos) {
            if k > i + 1 {
                break;
            } else {
                memo[pos] = bit.sum(n as usize);
                pos += 1;
            }
        }
        if pos >= query.len() {
            break;
        }
    }
    let mut ans = 0;
    let mut stack = vec![(n, p.len(), 1)];
    while let Some((n, k, sign)) = stack.pop() {
        if k == 0 {
            ans += sign * n;
            continue;
        }
        let q = p[k - 1];
        if q * q > n {
            let x = match p[..k].binary_search_by(|p| (p * p).cmp(&n)) {
                Ok(k) => k + 1,
                Err(k) => k,
            };
            ans += -sign * (k - x) as i64;
            stack.push((n, x, sign));
        } else if n <= bound {
            ans += sign * memo[query.binary_search(&(k, n)).unwrap()];
        } else {
            stack.push((n, k - 1, sign));
            stack.push((n / q, k - 1, -sign));
        }
    }
    ans - 1 + p.len() as i64
}

fn run() {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let n: i64 = s.trim().parse().unwrap();
    let p = sieve((n as f64).sqrt() as usize + 2);
    let mut ans = 0i64;
    for p in p.iter() {
        if p.pow(3) <= n {
            ans += 1;
        } else {
            break;
        }
    }
    for (i, p) in p.iter().enumerate() {
        if p.pow(2) <= n {
            ans +=prime_count(n / *p) - (i + 1) as i64;
        }
    }
    println!("{}", ans);
}

fn main() {
    run();
}


fn main() {
    let small_prime_limit = 200_000_000;
    let mut is_prime = vec![true; small_prime_limit/2];
    is_prime[0] = false;

    for i in 1..(((small_prime_limit+1) as f64).sqrt() as usize / 2) {
        if is_prime[i] {
            for j in ((3*i+1)..(small_prime_limit/2)).step_by(2*i+1) {
                is_prime[j] = false;
            }
        }
    }

    let mut small_primes = vec![2];
    for (idx, is_p) in is_prime.iter().enumerate() {
        if *is_p {
            small_primes.push(2*idx + 1);
        }
    }

    println!("{}", small_primes.len());
}


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

fn parse_problem<B: BufRead>(mut input: B) -> io::Result<Vec<(i64, i64)>> {
    let mut buffer = String::new();
    input.read_line(&mut buffer)?;
    buffer.truncate(buffer.trim_end().len());
    let mut positions = Vec::new();
    let mut curr = (0, 0);
    for c in buffer.chars() {
        let next = match c {
            'L' => Ok((curr.0 - 1, curr.1)),
            'U' => Ok((curr.0, curr.1 + 1)),
            'R' => Ok((curr.0 + 1, curr.1)),
            'D' => Ok((curr.0, curr.1 - 1)),
            _ => Err(io::Error::new(io::ErrorKind::InvalidInput, "bad input")),
        }?;
        positions.push(curr);
        curr = next;
    }
    positions.push(curr);
    Ok(positions)
}

fn main() -> io::Result<()> {
    let positions = parse_problem(io::stdin().lock())?;
    let mut seen_positions = HashSet::new();
    for pos in positions {
        if !seen_positions.insert(pos) {
            println!("BUG");
            return Ok(())
        }
    }
    println!("OK");
    Ok(())
}


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

enum Protocol { HTTP, FTP }

fn fix_protocol(s: &String) -> (String, Protocol) {
    let mut res: String = String::new();
    if s.chars().nth(0) == Some('f') {
        (s.chars().skip(3).collect(), Protocol::FTP)
    } else {
        (s.chars().skip(4).collect(), Protocol::HTTP)
    }
}

fn main() {
    let mut s = read_line();
    let (s_skip_proto, protocol) = fix_protocol(&s);
    let mut s_res = s_skip_proto.clone();
    let s_res_skipped: String = s_skip_proto.chars().skip(1).collect();

    // res = String::from("http://");
    // let appendix: String = s.chars().skip(4).collect();
    // res.push_str(&appendix);

    println!("{}", s_skip_proto);

    match s_res_skipped.find("ru") {
        Some(i) => {
            s_res.insert(i + 1, '.');
            if i + 4 < s_res.len() {
                // println!("------------- {}", i + 5);
                s_res.insert(i + 4, '/');
            }
        },
        _ => panic!("no ruurururur")
    }

    let mut s_res_res = match protocol {
        Protocol::HTTP => String::from("http://"),
        _ => String::from("ftp://")
    };
    s_res_res.push_str(&s_res);

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


fn gcd(a: i32, b: i32) -> i32 {
    let (mut a, mut b) = if a > b { (b, a) } else { (a, b) };
    while a != 0 {
        let tmp = a;
        a = b % a;
        b = tmp;
    }
    return b;
}

fn main() {
    let v: Vec<i32> = {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        line.trim().split(" ").map(|s| s.parse::<i32>().unwrap()).collect()
    };
    let (a, b, mut n) = (v[0], v[1], v[2]);

    while n != 0 {
        n -= gcd(a, n);
        if n == 0 {
            println!("0");
        }
        n -= gcd(b, n);
        if n == 0 {
            println!("1");
        }
    }
}


#![allow(non_snake_case, unused_imports, deprecated, dead_code)]

// 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::{VecDeque,HashMap,HashSet,BTreeMap,BTreeSet,BinaryHeap};
// Module for v1.15.1
use std::ascii::AsciiExt; // deprecated since 1.26.0: use inherent method instead

// Functions
fn gcd(a: u64, b: u64) -> u64 {
    assert!(a != 0 || b != 0);
    if a == 0 {
        return b;
    }
    else {
        return gcd(b%a, a);
    }
}

// Main
fn main() {

    input! {
        A: u64,
        B: u64,
        mut N: u64,
    }

    let mut turn = 0;
    let stones = vec![A,B];
    loop {
        println!("turn {}, N:{}", turn, N);
        let d = gcd(stones[turn], N);
        if N > d {
            N -= d;
            turn = 1-turn;
        } else if N==d {
            println!("== turn:{} d:{}", turn,d);
            turn = 1-turn;
            break;
        } else {
            break;
        }
    }

    println!("{}", 1-turn);
}


use std::io;

fn main() {
    let mut line = String::new();
    io::stdin()
        .read_line(&mut line)
        .expect("error");

    let line: String = line.trim().parse().expect("no");
    let inputs: Vec<i8> = line.split(" ")
        .map(|x| x.parse().expect("Not an integer!"))
        .collect();

    let (mut a, mut b, mut n) = (inputs[0], inputs[1], inputs[2]);
    let w = inputs[0];
    let z = inputs[1];

    loop {
        //println!(" n equal {}",n);
        let mut m = n.clone();

        while (n != 0) {
            if a == n {
                println!("{}", n);
            } else {
                let  t = n;
                n = a % n;
                a = t;
            }
        }
        if w == m {
            a = w;
        }
        //println!("gcd{} {} =  {}",w,m,a);

        if a > m {
            println!("1");
            break;
        }

        let  d = (m - a).clone();

        while (m != 0) {
            let k = m;
            m = b % m;
            b = k;
        }
        //println!("gcd {} {} = {}",z,d,b);

        n = d - b;
        if d < b {
            println!("0");
            break;
        }
    }
}


use std::io;

fn main() {
    let mut line = String::new();
    io::stdin()
        .read_line(&mut line)
        .expect("error");

    let line: String = line.trim().parse().expect("no");
    let inputs: Vec<i8> = line.split(" ")
        .map(|x| x.parse().expect("Not an integer!"))
        .collect();

    let (mut a, mut b, mut n) = (inputs[0], inputs[1], inputs[2]);
    let w = inputs[0];
    let z = inputs[1];

    loop{
        //println!(" n equal {}",n);
        let mut m = n.clone();

        while (n != 0) {

                let t = n;
                n = a % n;
                a = t;

        }
        if w == m {
            a = w;
        }
        //println!("gcd{} {} =  {}",w,m,a);

        if a > m {
            println!("1");
            break;
        }

        let d = (m - a).clone();

        while (m != 0) {
            let k = m;
            m = b % m;
            b = k;
        }
        //println!("gcd {} {} = {}",z,d,b);

        n = d - b;
        if d < b {
            println!("0");
            break;
        }

}}


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


use std::io;

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    let mut s = s.split_whitespace();
    let x: i32 = s.next().unwrap().parse().unwrap();
    let y: i32 = s.next().unwrap().parse().unwrap();
    let z: i32 = s.next().unwrap().parse().unwrap();
    let t1: i32 = s.next().unwrap().parse().unwrap();
    let t2: i32 = s.next().unwrap().parse().unwrap();
    let t3: i32 = s.next().unwrap().parse().unwrap();
    if (x - y).abs() * t1 < ((x - z).abs() + (x - y).abs()) * t2 + 2 * t3 {
        println!("NO");
    } else {
        println!("YES");
    }
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
#[allow(unused_imports)]
use std::io;
#[allow(unused_imports)]
use std::iter::*;
#[allow(unused_imports)]
use std::mem::*;
#[allow(unused_imports)]
use std::str::*;
#[allow(unused_imports)]
use std::usize;

// vec with some initial value
#[allow(unused_macros)]
macro_rules! vvec {
    ($($x:expr),+; $y:expr; $n:expr) => {{
        let mut v = vec![$y; $n];

        let mut it = v.iter_mut();
        $(
            *it.next().unwrap() = $x;
        )+

        v
    }}
}

#[allow(unused_macros)]
macro_rules! it {
    ($x:expr) => {
        once($x)
    };
    ($first:expr,$($x:expr),+) => {
        chain(
            once($first),
            it!($($x),+)
        )
    }
}

#[allow(unused_macros)]
macro_rules! pushed {
    ($c:expr, $x:expr) => {{
        let mut c = $c;
        c.push($x);
        c
    }};
}

#[allow(unused_macros)]
macro_rules! inserted {
    ($c:expr, $($x:expr),*) => {{
        let mut c = $c;
        c.insert($($x),*);
        c
    }};
}

#[allow(unused_macros)]
macro_rules! read_tuple {
    ($($t:ty),+) => {{
        let mut line = String::new();
        io::stdin().read_line(&mut line).unwrap();

        let mut it = line.trim()
            .split_whitespace();

        ($(
            it.next().unwrap().parse::<$t>().ok().unwrap()
        ),+)
    }}
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let mut line = String::new();
    io::stdin().read_line(&mut line).unwrap();
    line.trim().to_string().parse().ok().unwrap()
}

#[allow(dead_code)]
fn read_str() -> Vec<char> {
    read::<String>().chars().collect()
}

#[allow(dead_code)]
fn read_row<T: FromStr>() -> Vec<T> {
    let mut line = String::new();
    io::stdin().read_line(&mut line).unwrap();

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

#[allow(dead_code)]
fn read_col<T: FromStr>(n: usize) -> Vec<T> {
    (0..n).map(|_| read()).collect()
}

#[allow(dead_code)]
fn read_mat<T: FromStr>(n: usize) -> Vec<Vec<T>> {
    (0..n).map(|_| read_row()).collect()
}

#[allow(dead_code)]
fn read_vec<R, F: FnMut() -> R>(n: usize, mut f: F) -> Vec<R> {
    (0..n).map(|_| f()).collect()
}

trait IterCopyExt<'a, T>: IntoIterator<Item = &'a T> + Sized
where
    T: 'a + Copy,
{
    fn citer(self) -> std::iter::Copied<Self::IntoIter> {
        self.into_iter().copied()
    }
}

impl<'a, T, I> IterCopyExt<'a, T> for I
where
    I: IntoIterator<Item = &'a T>,
    T: 'a + Copy,
{
}

fn main() {
    let n = read::<String>()
        .chars()
        .map(|c| c.to_digit(10).unwrap() as usize)
        .collect::<Vec<_>>();

    const B: usize = 500;

    let dp = n.citer().fold(
        vec![
            vec![vec![0usize; B]; B],
            vvec![vec![usize::MAX; B]; vec![1usize; B]; B],
        ],
        |prev, d| {
            // eprintln!("{:?}", prev);
            (0..2)
                .map(|t| {
                    let d = d + t;
                    let mut dp = (0..B)
                        .map(|i| {
                            let mut v = vec![usize::MAX; B];

                            if i >= d {
                                v[i - d] = prev[0][i][i - d].saturating_add(i + (i - d));
                            }

                            if i + 10 >= d && i + 10 - d < B {
                                v[i + 10 - d] =
                                    prev[1][i][i + 10 - d].saturating_add(i + (i + 10 - d))
                            }

                            v
                        })
                        .collect::<Vec<_>>();
                    for i in 0..B {
                        for j in 0..B {
                            if i > 0 {
                                dp[i][j] = min(dp[i][j], dp[i - 1][j]);
                            }
                            if j > 0 {
                                dp[i][j] = min(dp[i][j], dp[i][j - 1]);
                            }
                        }
                    }
                    dp
                })
                .collect::<Vec<_>>()
        },
    );
    let ans = dp[0][B - 1][B - 1];
    println!("{}", ans);
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
#[allow(unused_imports)]
use std::io;
#[allow(unused_imports)]
use std::iter::*;
#[allow(unused_imports)]
use std::mem::*;
#[allow(unused_imports)]
use std::str::*;
#[allow(unused_imports)]
use std::usize;

// vec with some initial value
#[allow(unused_macros)]
macro_rules! vvec {
    ($($x:expr),+; $y:expr; $n:expr) => {{
        let mut v = vec![$y; $n];

        let mut it = v.iter_mut();
        $(
            *it.next().unwrap() = $x;
        )+

        v
    }}
}

#[allow(unused_macros)]
macro_rules! it {
    ($x:expr) => {
        once($x)
    };
    ($first:expr,$($x:expr),+) => {
        chain(
            once($first),
            it!($($x),+)
        )
    }
}

#[allow(unused_macros)]
macro_rules! pushed {
    ($c:expr, $x:expr) => {{
        let mut c = $c;
        c.push($x);
        c
    }};
}

#[allow(unused_macros)]
macro_rules! inserted {
    ($c:expr, $($x:expr),*) => {{
        let mut c = $c;
        c.insert($($x),*);
        c
    }};
}

#[allow(unused_macros)]
macro_rules! read_tuple {
    ($($t:ty),+) => {{
        let mut line = String::new();
        io::stdin().read_line(&mut line).unwrap();

        let mut it = line.trim()
            .split_whitespace();

        ($(
            it.next().unwrap().parse::<$t>().ok().unwrap()
        ),+)
    }}
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let mut line = String::new();
    io::stdin().read_line(&mut line).unwrap();
    line.trim().to_string().parse().ok().unwrap()
}

#[allow(dead_code)]
fn read_str() -> Vec<char> {
    read::<String>().chars().collect()
}

#[allow(dead_code)]
fn read_row<T: FromStr>() -> Vec<T> {
    let mut line = String::new();
    io::stdin().read_line(&mut line).unwrap();

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

#[allow(dead_code)]
fn read_col<T: FromStr>(n: usize) -> Vec<T> {
    (0..n).map(|_| read()).collect()
}

#[allow(dead_code)]
fn read_mat<T: FromStr>(n: usize) -> Vec<Vec<T>> {
    (0..n).map(|_| read_row()).collect()
}

#[allow(dead_code)]
fn read_vec<R, F: FnMut() -> R>(n: usize, mut f: F) -> Vec<R> {
    (0..n).map(|_| f()).collect()
}

trait IterCopyExt<'a, T>: IntoIterator<Item = &'a T> + Sized
where
    T: 'a + Copy,
{
    fn citer(self) -> std::iter::Copied<Self::IntoIter> {
        self.into_iter().copied()
    }
}

impl<'a, T, I> IterCopyExt<'a, T> for I
where
    I: IntoIterator<Item = &'a T>,
    T: 'a + Copy,
{
}

const B: i64 = 500;
const C: i64 = 50;

fn main() {
    let n = read::<String>()
        .chars()
        .map(|c| c.to_digit(10).unwrap() as i64)
        .collect::<Vec<_>>();

    let dp = n.citer().fold(
        (-C..=C)
            .map(|t| {
                (0..B)
                    .map(|i| {
                        if i < t {
                            vec![i64::MAX; B as usize]
                        } else {
                            vec![t; B as usize]
                        }
                    })
                    .collect::<Vec<_>>()
            })
            .collect::<Vec<_>>(),
        |prev, d| {
            // eprintln!("{:?}", prev);
            (-C..=C)
                .map(|t| {
                    let d = d + t;
                    let mut dp = (0..B)
                        .map(|i| {
                            let mut v = vec![i64::MAX; B as usize];

                            (-C..=C).for_each(|c| {
                                if i + 10 * c >= d && i + 10 * c < B + d {
                                    let j = i + 10 * c - d;
                                    v[j as usize] = prev[(c + C) as usize][i as usize][j as usize]
                                        .saturating_add(i + j);
                                }
                            });

                            v
                        })
                        .collect::<Vec<_>>();
                    for i in 0..B {
                        for j in 0..B {
                            if i > 0 {
                                dp[i as usize][j as usize] =
                                    min(dp[i as usize][j as usize], dp[i as usize - 1][j as usize]);
                            }
                            if j > 0 {
                                dp[i as usize][j as usize] =
                                    min(dp[i as usize][j as usize], dp[i as usize][j as usize - 1]);
                            }
                        }
                    }
                    dp
                })
                .collect::<Vec<_>>()
        },
    );
    let ans = dp[0 + C as usize][B as usize - 1][B as usize - 1];
    println!("{}", ans);
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
#[allow(unused_imports)]
use std::io;
#[allow(unused_imports)]
use std::iter::*;
#[allow(unused_imports)]
use std::mem::*;
#[allow(unused_imports)]
use std::str::*;
#[allow(unused_imports)]
use std::usize;

// vec with some initial value
#[allow(unused_macros)]
macro_rules! vvec {
    ($($x:expr),+; $y:expr; $n:expr) => {{
        let mut v = vec![$y; $n];

        let mut it = v.iter_mut();
        $(
            *it.next().unwrap() = $x;
        )+

        v
    }}
}

#[allow(unused_macros)]
macro_rules! it {
    ($x:expr) => {
        once($x)
    };
    ($first:expr,$($x:expr),+) => {
        chain(
            once($first),
            it!($($x),+)
        )
    }
}

#[allow(unused_macros)]
macro_rules! pushed {
    ($c:expr, $x:expr) => {{
        let mut c = $c;
        c.push($x);
        c
    }};
}

#[allow(unused_macros)]
macro_rules! inserted {
    ($c:expr, $($x:expr),*) => {{
        let mut c = $c;
        c.insert($($x),*);
        c
    }};
}

#[allow(unused_macros)]
macro_rules! read_tuple {
    ($($t:ty),+) => {{
        let mut line = String::new();
        io::stdin().read_line(&mut line).unwrap();

        let mut it = line.trim()
            .split_whitespace();

        ($(
            it.next().unwrap().parse::<$t>().ok().unwrap()
        ),+)
    }}
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let mut line = String::new();
    io::stdin().read_line(&mut line).unwrap();
    line.trim().to_string().parse().ok().unwrap()
}

#[allow(dead_code)]
fn read_str() -> Vec<char> {
    read::<String>().chars().collect()
}

#[allow(dead_code)]
fn read_row<T: FromStr>() -> Vec<T> {
    let mut line = String::new();
    io::stdin().read_line(&mut line).unwrap();

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

#[allow(dead_code)]
fn read_col<T: FromStr>(n: usize) -> Vec<T> {
    (0..n).map(|_| read()).collect()
}

#[allow(dead_code)]
fn read_mat<T: FromStr>(n: usize) -> Vec<Vec<T>> {
    (0..n).map(|_| read_row()).collect()
}

#[allow(dead_code)]
fn read_vec<R, F: FnMut() -> R>(n: usize, mut f: F) -> Vec<R> {
    (0..n).map(|_| f()).collect()
}

trait IterCopyExt<'a, T>: IntoIterator<Item = &'a T> + Sized
where
    T: 'a + Copy,
{
    fn citer(self) -> std::iter::Copied<Self::IntoIter> {
        self.into_iter().copied()
    }
}

impl<'a, T, I> IterCopyExt<'a, T> for I
where
    I: IntoIterator<Item = &'a T>,
    T: 'a + Copy,
{
}

const B: i32 = 500;
const C: i32 = 50;

fn main() {
    let n = read::<String>()
        .chars()
        .map(|c| c.to_digit(10).unwrap() as i32)
        .collect::<Vec<_>>();

    let dp = n.citer().fold(
        (-C..=C)
            .map(|t| {
                (0..B)
                    .map(|i| {
                        if i < t {
                            vec![i32::MAX; B as usize]
                        } else {
                            vec![t; B as usize]
                        }
                    })
                    .collect::<Vec<_>>()
            })
            .collect::<Vec<_>>(),
        |prev, d| {
            // eprintln!("{:?}", prev);
            (-C..=C)
                .map(|t| {
                    let d = d + t;
                    let mut dp = (0..B)
                        .map(|i| {
                            let mut v = vec![i32::MAX; B as usize];

                            (-C..=C).for_each(|c| {
                                if i + 10 * c >= d && i + 10 * c < B + d {
                                    let j = i + 10 * c - d;
                                    v[j as usize] = prev[(c + C) as usize][i as usize][j as usize]
                                        .saturating_add(i + j);
                                }
                            });

                            v
                        })
                        .collect::<Vec<_>>();
                    for i in 0..B {
                        for j in 0..B {
                            if i > 0 {
                                dp[i as usize][j as usize] =
                                    min(dp[i as usize][j as usize], dp[i as usize - 1][j as usize]);
                            }
                            if j > 0 {
                                dp[i as usize][j as usize] =
                                    min(dp[i as usize][j as usize], dp[i as usize][j as usize - 1]);
                            }
                        }
                    }
                    dp
                })
                .collect::<Vec<_>>()
        },
    );
    let ans = dp[0 + C as usize][B as usize - 1][B as usize - 1];
    println!("{}", ans);
}


const N:usize = 666;

fn main() {

    let mut str = String::new();
	std::io::stdin().read_line(&mut str).expect("");
    let input :Vec<&str> = str.trim().split(" ").collect();
    let n = input[0].parse::<i32>().unwrap();
    let modn = input[1].parse::<i64>().unwrap();
    let mut dp:Vec<[i64;2]> = vec![[0;2];N*N];
    let shift = N*N/2;
    dp[shift][1]=1;
    for _i in 1..n{
        let mut new_dp:Vec<[i64;2]> = vec![[0;2];N*N];
        let i = _i as usize;
        for _j in 0..(N*N-1){
            let j = _j as usize;
            if dp[j][1]==0 &&  dp[j][0]==0{
                continue;
            }
            new_dp[j-i][1] = (new_dp[j-i][1]+dp[j][1])%modn;
            new_dp[j+1][1] = (new_dp[j+1][1]-2*dp[j][1] + modn + modn)%modn;
            new_dp[j+i+2][1]=(new_dp[j+i+2][1]+dp[j][1])%modn;

            new_dp[j+1][0] = (new_dp[j+1][0]+dp[j][1]*(i as i64))%modn;
            new_dp[j][0] = (new_dp[j][0]+(modn-dp[j][1])*(i as i64+1))%modn;
            new_dp[j-i][0] = (new_dp[j-i][0]+dp[j][1])%modn;

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

}


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

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

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

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

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

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

    pub trait ConstantModulo {
        const MOD: u32;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    #[allow(dead_code)]
    impl<T: Modulo> ModInt<T> {
        pub fn new(d: u32) -> Self {
            ModInt::new_unchecked(d % T::modulo())
        }
        pub fn pow(&self, mut n: u64) -> Self {
            let mut t = Self::one();
            let mut s = *self;
            while n > 0 {
                if n & 1 == 1 {
                    t *= s;
                }
                s *= s;
                n >>= 1;
            }
            t
        }
    }
}
// ---------- end ModInt ----------

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

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

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

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

use std::collections::*;
use std::io::Write;

type Map<K, V> = HashMap<K, V>;
type Set<T> = BTreeSet<T>;
type Deque<T> = VecDeque<T>;

// 一致してる間は転倒数一致、後ろの寄与も一致
// p_0 < q_0 の問題がn=2..50 で解ければいい
// 初項を決めたらあとは転倒数を保持するdpでいいんじゃ？
// N^5 になってるが
// いや7乗だこれ

fn run() {
    input!(n: usize, modulo: u32);
    StaticMod::set_modulo(modulo);
    let mut ans = M::zero();
    let mut binom = vec![vec![M::zero(); n + 1]; n + 1];
    binom[0][0] = M::one();
    for i in 1..=n {
        binom[i][0] = M::one();
        for j in 1..=i {
            binom[i][j] = binom[i - 1][j - 1] + binom[i - 1][j];
        }
    }
    let mut dp = Map::new();
    for rem in (1..=n).rev() {
        let mut next = Map::new();
        for i in 0..rem {
            for j in (i + 1)..rem {
                *next.entry(i as i32 - j as i32).or_insert(M::zero()) += binom[n][rem];
            }
        }
        let mut trans = Map::new();
        for i in 0..rem {
            for j in 0..rem {
                *trans.entry(i as i32 - j as i32).or_insert(M::zero()) += M::one();
            }
        }
        for (diff, way) in dp {
            for (d, w) in trans.iter() {
                *next.entry(diff + *d).or_insert(M::zero()) += *w * way;
            }
        }
        dp = next;
    }
    let mut ans = M::zero();
    for (diff, way) in dp {
        if diff > 0 {
            ans += way;
        }
    }
    let ans = ans.0 % modulo;
    println!("{}", ans);
}

fn main() {
    run();
}


/*
    date   : 2021 / 4 / 7
    author : quickn (quickn.tech)
    email  : quickwshell@gmail.com
*/

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

mod scanner {
    use std::{io, str};
    /* https://github.com/EbTech/rust-algorithms */

    /// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts
    /// **REQUIRES** Rust 1.34 or higher
    pub struct UnsafeScanner<R> {
        reader: R,
        buf_str: Vec<u8>,
        buf_iter: str::SplitAsciiWhitespace<'static>,
    }

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

        /// This function should be marked unsafe, but noone has time for that in a
        /// programming contest. Use at your own risk!
        pub fn token<T: str::FromStr>(&mut self) -> T {
            loop {
                if let Some(token) = self.buf_iter.next() {
                    return token.parse().ok().expect("Failed parse");
                }
                self.buf_str.clear();
                self.reader
                    .read_until(b'\n', &mut self.buf_str)
                    .expect("Failed read");
                self.buf_iter = unsafe {
                    let slice = str::from_utf8_unchecked(&self.buf_str);
                    std::mem::transmute(slice.split_ascii_whitespace())
                }
            }
        }
    }
}

use std::cmp::{min, max};

fn s2vec(s: String) -> Vec<char> {
    s.chars().collect()
}

const MOD: i64 = 998244353;

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let (mut scan, mut sout) = (
        scanner::UnsafeScanner::new(stdin.lock()),
        BufWriter::new(stdout.lock()),
    );
    let n: usize = scan.token();
    let mut dp: Vec<i64> = vec![0;n+1];
    let mut dp2: Vec<i64> = vec![0;2*n+1];
    dp[0] = 1;
    dp[1] = 1;
    dp[2] = 1;
    dp2[1] = 1;
    let mut sum = 2;
    for i in 2..=n {
        dp2[i] = 1;
        let mut p = 2;
        while p*p <= i {
            if i % p == 0 {
                dp2[i] += 1;
                dp2[i] %= MOD;
                if i / p != p {
                    dp2[i] += 1;
                    dp2[i] %= MOD;
                }
            }
            p += 1;
        }
        dp[i] = (dp2[i] + sum)%MOD;
        sum += dp[i];
        sum %= MOD;
    }
    writeln!(sout, "{}", dp[n]).ok();
}


/*
    date   : 2021 / 4 / 7
    author : quickn (quickn.tech)
    email  : quickwshell@gmail.com
*/

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

mod scanner {
    use std::{io, str};
    /* https://github.com/EbTech/rust-algorithms */

    /// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts
    /// **REQUIRES** Rust 1.34 or higher
    pub struct UnsafeScanner<R> {
        reader: R,
        buf_str: Vec<u8>,
        buf_iter: str::SplitAsciiWhitespace<'static>,
    }

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

        /// This function should be marked unsafe, but noone has time for that in a
        /// programming contest. Use at your own risk!
        pub fn token<T: str::FromStr>(&mut self) -> T {
            loop {
                if let Some(token) = self.buf_iter.next() {
                    return token.parse().ok().expect("Failed parse");
                }
                self.buf_str.clear();
                self.reader
                    .read_until(b'\n', &mut self.buf_str)
                    .expect("Failed read");
                self.buf_iter = unsafe {
                    let slice = str::from_utf8_unchecked(&self.buf_str);
                    std::mem::transmute(slice.split_ascii_whitespace())
                }
            }
        }
    }
}

use std::cmp::{min, max};

fn s2vec(s: String) -> Vec<char> {
    s.chars().collect()
}

const MOD: i64 = 998244353;

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let (mut scan, mut sout) = (
        scanner::UnsafeScanner::new(stdin.lock()),
        BufWriter::new(stdout.lock()),
    );
    let n: usize = scan.token();
    let mut dp: Vec<i64> = vec![0;1_000_001];
    let mut dp2: Vec<i64> = vec![0;1_000_001];
    dp[0] = 1;
    dp[1] = 1;
    dp[2] = 1;
    let mut sum = 2;
    for i in 2..=n {
        dp2[i] = 1;
        let mut p = 2;
        while p*p <= i {
            if i % p == 0 {
                dp2[i] += 1;
                dp2[i] %= MOD;
                if i / p != p {
                    dp2[i] += 1;
                    dp2[i] %= MOD;
                }
            }
            p += 1;
        }
        dp[i] = (dp2[i] + sum)%MOD;
        sum += dp[i];
        sum %= MOD;
    }
    writeln!(sout, "{}", dp[n]).ok();
}


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
    }

    #[inline]
    fn norm(a: u32, m: u32) -> u32 {
        (((a as i32) >> 31) as u32 & m) + a
    }
    // for a, b < m < 2^31, undefined otherwise
    #[inline]
    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 }
        norm(a.wrapping_add(b).wrapping_sub(m), m)
    }
    #[inline]
    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 }
        norm(a.wrapping_sub(m), m)
    }
    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(if self.val == 0 { 0 } else { Self::modulus() - self.val })
            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)
        }
    }
}

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

static mut MODULUS: u32 = 998244353;
#[inline] fn get_modulus() -> u32 { unsafe { MODULUS } }
#[inline] fn set_modulus(value: u32) { unsafe { MODULUS = 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, 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);
    #[inline]
    pub fn mul_mod_u32(a: u32, b: u32, m: u32) -> u32 {
        ((a as u64) * (b as u64) % (m as u64)) as u32
    }

    #[inline]
    fn norm(a: u32, m: u32) -> u32 {
        (((a as i32) >> 31) as u32 & m) + a
    }
    // for a, b < m < 2^31, undefined otherwise
    #[inline]
    pub fn add_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        sub_mod_raw(a, m-b, m)
        //norm(a.wrapping_add(b).wrapping_sub(m), m)
    }
    #[inline]
    pub fn sub_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        let (r, c) = a.overflowing_sub(b);
        if c { r + m } else { r }
        //norm(a.wrapping_sub(b), m)
    }
    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)
        }
    }
}

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

// static mut MODULUS: u32 = 998244353;
// #[inline] fn get_modulus() -> u32 { unsafe { MODULUS } }
// #[inline] fn set_modulus(value: u32) { unsafe { MODULUS = 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(())
}