#[macro_export] macro_rules! read_line { ($($xs: tt)*) => { let mut buf = String::new(); std::io::stdin().read_line(&mut buf).unwrap(); let mut iter = buf.split_whitespace(); expand!(iter, $($xs)*); }; } #[macro_export] macro_rules! expand { ($iter: expr,) => {}; ($iter: expr, mut $var: ident : $type: tt, $($xs: tt)*) => { let mut $var = value!($iter, $type); expand!($iter, $($xs)*); }; ($iter: expr, $var: ident : $type: tt, $($xs: tt)*) => { let $var = value!($iter, $type); expand!($iter, $($xs)*); }; } #[macro_export] macro_rules! value { ($iter:expr, ($($type: tt),*)) => { ($(value!($iter, $type)),*) }; ($iter: expr, [$type: tt; $len: expr]) => { (0..$len).map(|_| value!($iter, $type)).collect::>() }; ($iter: expr, Chars) => { value!($iter, String).unwrap().chars().collect::>() }; ($iter: expr, $type: ty) => { if let Some(v) = $iter.next() { v.parse::<$type>().ok() } else { None } }; } use std::{fmt, ops}; const MOD: usize = 998244353; // 119 * (1 << 23) + 1 #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct ModInt { value: usize, } impl ModInt { pub fn new(value: usize) -> ModInt { ModInt { value: value % MOD } } pub fn value(&self) -> usize { self.value } pub fn inverse(&self) -> ModInt { // (a, b) -> (x, y) s.t. a * x + b * y = gcd(a, b) fn extended_gcd(a: isize, b: isize) -> (isize, isize) { if (a, b) == (1, 0) { (1, 0) } else { let (x, y) = extended_gcd(b, a % b); (y, x - (a / b) * y) } } let (x, _y) = extended_gcd(self.value() as isize, MOD as isize); ModInt::new((MOD as isize + x) as usize) } // a^n pub fn pow(&self, mut n: usize) -> ModInt { let mut res = ModInt::new(1); let mut x = *self; while n > 0 { if n % 2 == 1 { res *= x; } x *= x; n /= 2; } res } } impl ops::Add for ModInt { type Output = ModInt; fn add(self, other: Self) -> Self { ModInt::new(self.value + other.value) } } impl ops::Sub for ModInt { type Output = ModInt; fn sub(self, other: Self) -> Self { ModInt::new(MOD + self.value - other.value) } } impl ops::Mul for ModInt { type Output = ModInt; fn mul(self, other: Self) -> Self { ModInt::new(self.value * other.value) } } impl ops::Div for ModInt { type Output = ModInt; fn div(self, other: Self) -> Self { self * other.inverse() } } impl ops::AddAssign for ModInt { fn add_assign(&mut self, other: Self) { *self = *self + other; } } impl ops::SubAssign for ModInt { fn sub_assign(&mut self, other: Self) { *self = *self - other; } } impl ops::MulAssign for ModInt { fn mul_assign(&mut self, other: Self) { *self = *self * other; } } impl ops::DivAssign for ModInt { fn div_assign(&mut self, other: Self) { *self = *self / other; } } // n! pub fn factorial(n: usize) -> ModInt { (1..=n).fold(ModInt::new(1), |x, y| x * ModInt::new(y)) } // nPr pub fn permutation(n: usize, r: usize) -> ModInt { if n < r { ModInt::new(0) } else { (n - r + 1..=n).fold(ModInt::new(1), |x, y| x * ModInt::new(y)) } } // nCr pub fn combination(n: usize, r: usize) -> ModInt { if n < r { ModInt::new(0) } else { permutation(n, r) / factorial(r) } } // nHr pub fn homogeneous(n: usize, r: usize) -> ModInt { combination(n + r - 1, r) } // Catalan number pub fn catalan(n: usize) -> ModInt { combination(2 * n, n) / ModInt::new(n + 1) } impl fmt::Display for ModInt { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.value()) } } pub fn gen_divisors(n: usize) -> Vec { let mut res = vec![]; for i in (1..).take_while(|&x| x * x <= n) { if n % i == 0 { res.push(i); if i * i < n { res.push(n / i); } } } res.sort(); res } fn main() { read_line!(n: usize, m: usize,); let n = n.unwrap(); let m = m.unwrap(); read_line!(a: [usize; n],); let a = a.into_iter().map(|x| x.unwrap()).collect::>(); let mut cnt = vec![0; m + 1]; for i in 0..n { for d in gen_divisors(a[i]) { cnt[d] += 1; } } let mut ans = vec![ModInt::new(0); m + 1]; for i in 1..=m { ans[i] = ModInt::new(2).pow(cnt[i]) - ModInt::new(1); } for i in (1..=m).rev() { for d in gen_divisors(i) { if d < i { ans[d] = ans[d] - ans[i]; } } } for i in 1..=m { println!("{}", ans[i]); } }