#include using namespace std; using ll=long long; using ull=unsigned long long; using P=pair; templateusing minque=priority_queue,greater>; templatebool chmax(T &a,const T &b){return (abool chmin(T &a,const T &b){return (a>b?(a=b,true):false);} templateistream &operator>>(istream &is,pair&p){is>>p.first>>p.second;return is;} templateistream &operator>>(istream &is,tuple&a){is>>std::get<0>(a)>>std::get<1>(a)>>std::get<2>(a);return is;} templateistream &operator>>(istream &is,array&a){for(auto&i:a)is>>i;return is;} templateistream &operator>>(istream &is,vector &a){for(auto &i:a)is>>i;return is;} templatevoid operator++(pair&a,int n){a.first++,a.second++;} templatevoid operator--(pair&a,int n){a.first--,a.second--;} templatevoid operator++(vector&a,int n){for(auto &i:a)i++;} templatevoid operator--(vector&a,int n){for(auto &i:a)i--;} #define overload3(_1,_2,_3,name,...) name #define rep1(i,n) for(int i=0;i<(int)(n);i++) #define rep2(i,l,r) for(int i=(int)(l);i<(int)(r);i++) #define rep(...) overload3(__VA_ARGS__,rep2,rep1)(__VA_ARGS__) #define reps(i,l,r) rep2(i,l,r) #define all(x) x.begin(),x.end() #define pcnt(x) __builtin_popcountll(x) #define fin(x) return cout<<(x)<<'\n',static_cast(0) #define yn(x) cout<<((x)?"Yes\n":"No\n") #define uniq(x) sort(all(x)),x.erase(unique(all(x)),x.end()) template inline int fkey(vector&z,T key){return lower_bound(z.begin(),z.end(),key)-z.begin();} ll myceil(ll a,ll b){return (a+b-1)/b;} template auto vec(const int (&d)[n],const T &init=T()){ if constexpr (id(d,init)); else return init; } #ifdef LOCAL #include #define SWITCH(a,b) (a) #else #define debug(...) static_cast(0) #define debugg(...) static_cast(0) #define SWITCH(a,b) (b) templateostream &operator<<(ostream &os,const pair&p){os<>testcase; for(int i=0;idat; long long n,s; Quotients(){} explicit Quotients(long long n_):n(n_),s(std::sqrt(n_)){ dat.resize(s*2-(s==n/s)); std::iota(dat.begin(),dat.begin()+s,1); for(int i=s-(s==n/s);i>=1;i--)dat[dat.size()-i]=n/i; } const long long &operator[](int i)const{return dat[i];} int get_key(long long k)const{ if(k<=s)return k-1; else return dat.size()-(int)((double)n/(double)k); } int size()const{return dat.size();} }; #include #include #include constexpr bool isprime_constexpr(unsigned long long n){ if(n==998244353)return true; if(n==1000000007)return true; if(n<64)return 2891462833508853932ll>>n&1; if(n%2==0)return false; unsigned long long d=n-1; int s=0; while(!(d&1))d>>=1,s++; int q=63; while(!(d>>q))q--; unsigned long long r=n; for(int i=0;i<5;i++)r*=2-r*n; auto redc=[&r,&n](__uint128_t x)->unsigned long long { x=(x+__uint128_t((unsigned long long)x*-r)*n)>>64; return x>=n?x-n:x; }; __uint128_t r2=-__uint128_t(n)%n; unsigned long long one=redc(r2); for(unsigned long long base:{2,325,9375,28178,450775,9780504,1795265022}){ if(base%n==0)continue; unsigned long long a=base=redc((base%n)*r2); for(int i=q-1;i>=0;i--){ a=redc(__uint128_t(a)*a); if(d>>i&1)a=redc(__uint128_t(a)*base); } if(a==one)continue; for(int i=1;a!=n-one;i++){ if(i>=s)return false; a=redc(__uint128_t(a)*a); } } return true; } constexpr std::pairext_gcd(long long a,long long b){ if(b==0)return std::make_pair(1,0); auto [x,y]=ext_gcd(b,a%b); std::swap(x,y); return std::make_pair(x,y-a/b*x); } template constexpr std::pair inv_mod(T a,T b){ a%=b; if(a<0)a+=b; if(a==0)return std::make_pair(b,0); T s=b,t=a; T m0=0,m1=1; while(t){ T u=s/t; s-=t*u; m0-=m1*u; std::swap(s,t); std::swap(m0,m1); } if(m0<0)m0+=b/s; return std::make_pair(s,m0); } template struct modint{ static_assert(1<=m&&m<(1ull<<63)); using value_type=std::conditional_t<((m>>31)==0),uint32_t,uint64_t>; using mul_type=std::conditional_t<((m>>31)==0),uint64_t,__uint128_t>; private: value_type v; static constexpr value_type umod=m; constexpr modint sqrt_impl()const{ if(this->val()<=1)return *this; if(umod%8==1){ modint b=2; while(b.pow((umod-1)/2).val()==1)b++; value_type m2=umod-1; int e=0; while(m2%2==0)m2>>=1,e++; modint x=this->pow((m2-1)/2); modint y=(*this)*x*x; x*=*this; modint z=b.pow(m2); while(y.val()!=1){ int j=0; modint t=y; while(t.val()!=1)t*=t,j++; z=z.pow((value_type(1))<<(e-j-1)); x*=z; z*=z; y*=z; e=j; } return x; } else if(umod%8==5){ modint res=this->pow((umod+3)/8); if((res*res).val()==this->val())return res; else return res*modint(2).pow((umod-1)/4); } else return this->pow((umod+1)/4); } template||std::is_same_v,std::nullptr_t> =nullptr> static constexpr value_type take_mod(U x){ if constexpr(std::numeric_limits::max()>61)+(x&umod); if(res>=umod)res-=umod; return res; } if constexpr(umod==(1ull<<61)-(1ull<<24)+1){ static constexpr value_type mask=(1ull<<61)-1; value_type high=x>>61,low=x&mask; mul_type t=low+(mul_type(high)<<24)-high; high=t>>61,low=t&mask; low=low+(mul_type(high)<<24)-high; if(low>=umod)low-=umod; return low; } return x%umod; } public: constexpr modint():v(0){} template||std::is_same_v,std::nullptr_t> =nullptr> constexpr modint(U x){ x%=std::make_signed_t(umod); v=x>=0?x:x+umod; } template||std::is_same_v,std::nullptr_t> =nullptr> constexpr modint(U x):v(take_mod(x)){} static constexpr value_type mod(){return umod;} template static constexpr modint raw(U x){ modint res; res.v=x; return res; } constexpr std::make_signed_t val()const{return v;} constexpr modint &operator+=(const modint&b){ this->v+=b.v; if(this->v>=umod)this->v-=umod; return *this; } constexpr modint &operator-=(const modint&b){ this->v-=b.v; if(this->v>=umod)this->v+=umod; return *this; } constexpr modint &operator*=(const modint&b){ this->v=take_mod(mul_type(this->v)*mul_type(b.v)); return *this; } constexpr modint &operator/=(const modint&b){return *this*=b.inv();} constexpr modint operator+()const{return *this;} constexpr modint operator-()const{return modint()-*this;} friend constexpr modint operator+(const modint&a,const modint&b){return modint(a)+=b;} friend constexpr modint operator-(const modint&a,const modint&b){return modint(a)-=b;} friend constexpr modint operator*(const modint&a,const modint&b){return modint(a)*=b;} friend constexpr modint operator/(const modint&a,const modint&b){return modint(a)/=b;} constexpr auto operator<=>(const modint&)const=default; constexpr modint operator++(int){ modint res=*this; this->v++; if(this->v==umod)this->v=0; return res; } constexpr modint operator--(int){ modint res=*this; if(this->v==0)this->v=umod; this->v--; return res; } template constexpr modint pow(U k)const{ if constexpr(std::is_signed_v){ assert(0<=k); } modint res=1,a(*this); while(k){ if(k&1)res*=a; a*=a; k>>=1; } return res; } constexpr modint inv()const{ if constexpr(isprime_constexpr(umod)){ if(std::is_constant_evaluated()){ if(v==0){ throw "no inverse"; } } else assert(v!=0); return pow(umod-2); } else{ modint res; auto [g,x]=inv_mod>(this->v,umod); if(std::is_constant_evaluated()){ if(g!=1){ throw "no inverse"; } } else assert(g==1); res.v=x; return res; } } std::optionalsqrt()const{ if(this->val()<=1||this->pow((umod-1)/2)==1)return std::make_optional(this->sqrt_impl()); else return std::nullopt; } friend std::istream &operator>>(std::istream&is,modint&b){ long long a; is>>a; b=modint(a); return is; } friend std::ostream &operator<<(std::ostream&os,const modint&b){ os< struct std::hash>{ std::size_t operator()(modintx)const{ return std::hash::value_type>(x.val()); } }; using mint998=modint<998244353>; using mint107=modint<1000000007>; using mint61=modint<2305843009213693951>; using mint6124=modint<2305843009196916737>; std::vectorprime_sieve(int n){ if(n<=6){ if(n<=1)return std::vector{}; else if(n==2)return std::vector{2}; else if(n<=4)return std::vector{2,3}; else return std::vector{2,3,5}; } static constexpr int mod30table[8]={1,7,11,13,17,19,23,29}; static constexpr uint8_t k_mask[][8] = { {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}, {0xfd, 0xdf, 0xef, 0xfe, 0x7f, 0xf7, 0xfb, 0xbf}, {0xfb, 0xef, 0xfe, 0xbf, 0xfd, 0x7f, 0xf7, 0xdf}, {0xf7, 0xfe, 0xbf, 0xdf, 0xfb, 0xfd, 0x7f, 0xef}, {0xef, 0x7f, 0xfd, 0xfb, 0xdf, 0xbf, 0xfe, 0xf7}, {0xdf, 0xf7, 0x7f, 0xfd, 0xbf, 0xfe, 0xef, 0xfb}, {0xbf, 0xfb, 0xf7, 0x7f, 0xfe, 0xef, 0xdf, 0xfd}, {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}, }; static constexpr int c0[][8] = { {0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 0, 1, 1, 1, 1}, {2, 2, 0, 2, 0, 2, 2, 1}, {3, 1, 1, 2, 1, 1, 3, 1}, {3, 3, 1, 2, 1, 3, 3, 1}, {4, 2, 2, 2, 2, 2, 4, 1}, {5, 3, 1, 4, 1, 3, 5, 1}, {6, 4, 2, 4, 2, 4, 6, 1}, }; static constexpr int c1[8]={6,4,2,4,2,4,6,2}; n++; int sz=(n+29)/30; std::vectorp(sz,0xff); { int r=n%30; if(r==0); else if(r==1)p.back()=0x00; else if(r<=7)p.back()=0x01; else if(r<=11)p.back()=0x03; else if(r<=13)p.back()=0x07; else if(r<=17)p.back()=0x0f; else if(r<=19)p.back()=0x1f; else if(r<=23)p.back()=0x3f; else if(r<=29)p.back()=0x7f; } p[0]=0xfe; int sq=std::min(sz-1,((int)std::sqrt(n)+29)/30); for(int i=0;i<=sq;i++){ for(uint8_t f=p[i];f>0;f=f&(f-1)){ uint8_t l=__builtin_ctz(f); int m=mod30table[l]; int pm=i*30+m*2; for(int j=i*pm+m*m/30,k=l;j<(int)p.size();j+=i*c1[k]+c0[l][k],k=(k+1)&7){ p[j]&=k_mask[l][k]; } } } std::vectorres{2,3,5}; for(int i=0;i<(int)p.size()-1;i++){ for(int j=p[i];j>0;j=j&(j-1))res.push_back(i*30+mod30table[__builtin_ctz(j)]); } for(int j=p.back();j>0;j=j&(j-1)){ int l=__builtin_ctz(j); int k=(p.size()-1)*30+mod30table[l]; if(k void divisor_zeta(std::vector&a){ int n=a.size()-1; std::vectorp=prime_sieve(n); for(int i:p)for(int j=1;j<=n/i;j++)a[i*j]+=a[j]; } template void divisor_mobius(std::vector&a){ int n=a.size()-1; std::vectorp=prime_sieve(n); for(int i:p)for(int j=n/i;j>=1;j--)a[i*j]-=a[j]; } template void multiplier_zeta(std::vector&a){ int n=a.size()-1; std::vectorp=prime_sieve(n); for(int i:p)for(int j=n/i;j>=1;j--)a[j]+=a[i*j]; } template void multiplier_mobius(std::vector&a){ int n=a.size()-1; std::vectorp=prime_sieve(n); for(int i:p)for(int j=1;j<=n/i;j++)a[j]-=a[i*j]; } using mint=mint998; constexpr int nmax=1e6; void SOLVE(){ vector>dp(11); rep(i,1,11){ vectorf(nmax+1); rep(j,nmax+1)f[j]=mint(j).pow(i); divisor_mobius(f); rep(j,1,nmax+1)f[j]+=f[j-1]; dp[i]=move(f); } int t; cin>>t; while(t--){ int n,m,k; cin>>n>>m>>k; const vector&f=dp[k]; Quotients quo(m); mint ans=0; for(int i=1;i<=m;){ int j=m/(m/i); ans+=(f[j]-f[i-1])*mint(m/i).pow(n); i=j+1; } cout<