fn read() -> (usize, usize) { let mut s = String::new(); std::io::stdin().read_line(&mut s).unwrap(); let mut it = s.trim().split_whitespace(); let n = it.next().unwrap().parse::().unwrap(); let k = it.next().unwrap().parse::().unwrap(); (n, k) } fn solve(n: usize, k: usize) { let encode = |t: usize, a: usize, b: usize| -> usize { (t * k + a) * k + b }; let decode = |x: usize| -> (usize, usize, usize) { (x / (k * k), x / k % k, x % k) }; let size = 2 * k * k; let mut trans = vec![vec![0usize; size]; size]; for (i, trans) in trans.iter_mut().enumerate() { for (j, trans) in trans.iter_mut().enumerate() { let (a, b, c) = decode(i); let (d, e, f) = decode(j); if c != e || b == c || c == f || b == f || !(c < b.min(f) || c > b.max(f)) { continue; } match (a, d) { (0, 0) => { *trans += 1; }, (0, 1) => { *trans += f; }, (1, 1) => { *trans += 1; }, _ => (), } } } const MOD: usize = 998_244_353; type Mat = Vec>; let mul = |a: &Mat, b: &Mat| -> Mat { let mut c = vec![vec![0; a.len()]; a.len()]; for (c, a) in c.iter_mut().zip(a) { for (a, b) in a.iter().zip(b) { for (c, b) in c.iter_mut().zip(b) { *c = (*c + *a * *b) % MOD; } } } c }; let mut t = vec![vec![0; size]; size]; let mut s = trans; for (i, t) in t.iter_mut().enumerate() { t[i] = 1; } let mut m = n - 2; while m > 0 { if m & 1 == 1 { t = mul(&t, &s); } s = mul(&s, &s); m >>= 1; } let mut ini = vec![0; size]; for i in 0..k { for j in 0..k { if i != j { ini[encode(0, i, j)] += 1; ini[encode(1, i, j)] += i + j; } } } let mut ans = [0; 2]; for j in 0..size { let mut s = 0; for (ini, t) in ini.iter().zip(t.iter()) { s = (s + *ini * t[j]) % MOD; } let x = j / k / k; ans[x] = (ans[x] + s) % MOD; } println!("{} {}", ans[0], ans[1]); } fn main() { let (n, k) = read(); solve(n, k); }