#![allow(unused)] #![allow(non_snake_case)] #![allow(dead_code)] fn main() { let input_str = std::io::read_to_string(std::io::stdin()).unwrap(); let mut input = input_str.split_whitespace(); let mut read_int = ||->usize {input.next().unwrap().parse().unwrap()}; //階乗と階乗逆元を前計算 const MOD:usize = 998244353; let mut fac = vec![1usize;202503]; for i in 1..=202502{ fac[i] = fac[i-1]*i%MOD; } let mut invfac = vec![668772755usize;202503]; for i in (0..=202501).rev(){ invfac[i] = invfac[i+1]*(i+1)%MOD; } let T = read_int(); for _ in 0..T{ let (N,A) = (read_int(),read_int()); //約数を列挙する let mut divisors = vec![]; for d in 1..=(A as f64).sqrt() as usize{ if A%d != 0 {continue;} divisors.push(d); if d*d != A{ divisors.push(A/d); } } let mut ans = 0; for &d in divisors.iter(){ if N-1 < d {continue;} if (N-1-d)%2 == 1 {continue;} //下降がp回,上昇がq回の個数 let (p,q) = ((N-1+d)/2,(N-1-d)/2); ans += (p+1-q)*fac[p+q]%MOD*invfac[p+1]%MOD*invfac[q]%MOD; ans %= MOD; } println!("{}",ans); } }