fn getline() -> String { let mut ret = String::new(); std::io::stdin().read_line(&mut ret).ok().unwrap(); ret } fn amod(a: i64, b: i64, p: i64) -> i64 { let mut r = a + b; if r >= p { r -= p; } r } fn powmod(x: i64, mut e: i64, m: i64) -> i64 { let mut sum = 1; let mut cur = x % m; while e > 0 { if e % 2 != 0 { sum = sum * cur % m; } cur = cur * cur % m; e /= 2; } sum } // https://yukicoder.me/problems/no/3187 (3) fn main() { let ints = getline() .trim() .split_whitespace() .map(|x| x.parse::().unwrap()) .collect::>(); let n = ints[0] as usize; let p = ints[1]; let mut dp = vec![0; n + 1]; let mut divs = vec![vec![]; n + 1]; for i in 1..=n { for j in (i..=n).step_by(i) { divs[j].push(i); } } let mut mul_acc = vec![vec![]; n + 1]; for i in 1..=n { mul_acc[i] = vec![0; n / i + 2]; } for i in 3..=n { let mut loopback = 0; let mut sq = 0; let mut me = 0; while sq * sq <= i { sq += 1; } sq -= 1; for b in 1..=sq { let to = i / b * b; if to == i { loopback += 1; } else { me = amod(me, dp[to], p); } } for d in 1..=sq + 1 { let l = sq.max(i / (d + 1)); let mut r = i / d; // (l, r] if l >= r { continue; } if r * d == i { loopback += 1; r -= 1; } me = amod(me, mul_acc[d][r + 1], p); me = amod(me, p - mul_acc[d][l + 1], p); } // (me + i) / non_loopback // naive if false { let mut non_loopback = i; let mut naive_me = 0; for j in 1..= i { if i / j * j == i { non_loopback -= 1; } else { naive_me = amod(naive_me, dp[i / j * j], p); } } eprintln!("naive: {} {}", i - non_loopback, naive_me); } me = amod(me, i as i64, p); dp[i] = me * powmod(i as i64 - loopback, p - 2, p) % p; for &d in &divs[i] { let j = i / d; mul_acc[d][j + 1] = amod(mul_acc[d][j], dp[i], p); } } println!("{}", dp[n]); }