#ifdef NACHIA #define _GLIBCXX_DEBUG #else #define NDEBUG #endif #include #include #include #include #include #include #include #include using i64 = long long; using u64 = unsigned long long; #define rep(i,n) for(int i=0; i=0; i--) const i64 INF = 1001001001001001001; const char* yn(bool x){ return x ? "Yes" : "No"; } template void chmin(A& l, const A& r){ if(r < l) l = r; } template void chmax(A& l, const A& r){ if(l < r) l = r; } template using nega_queue = std::priority_queue,std::greater>; template auto ComparingBy(R f){ return [g=std::move(f)](auto l, auto r) -> bool { return g(l) < g(r); }; } #include using Modint = atcoder::static_modint<998244353>; using namespace std; void testcase(){ i64 Z = 64; int T; cin >> T; i64 primes[] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97 }; vector Inv(Z+1); for(int i=1; i<=Z; i++) Inv[i] = Modint(i).inv(); rep(t,T){ i64 N, S; cin >> N >> S; vector F(25); rep(i,25) while(N % primes[i] == 0){ N /= primes[i]; F[i]++; } vector comb(Z+1); comb[0] = 1; for(int i=1; i<=Z; i++) comb[i] = comb[i-1] * (S + i - 2) * Inv[i]; Modint ans = 1; rep(i,25) if(F[i]){ Modint p = primes[i]; Modint pp = 1; Modint t = 0; rep(k,F[i]+1){ t += pp * comb[F[i]-k]; pp *= p; } ans *= t; } ans *= S; cout << ans.val() << '\n'; } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); testcase(); return 0; }