![](https://images.cnblogs.com/cnblogs_com/pidan123/2184440/o_230919121348_t0102c921497c78168e.jpg)
#include<bits/stdc++.h>
#define int long long
#define N 2000005
using namespace std;
int read(){
int w=0,h=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')h=-h;ch=getchar();}
while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();}
return w*h;
}
// My poly template✨
const int mod=998244353;int n;
namespace Polynomial{
const int g=3,ig=332748118,B=25000;
int pwg[B+1],PWG[B+1],pwig[B+1],PWIG[B+1],inv[N<<1],lg[N<<1],pw[N<<1],trans[N<<1];
inline void add(int&x,int y){(x+=y)>=mod?x-=mod:x;}
inline void Init(){
for(int i=pwg[0]=1;i<=B;i++)pwg[i]=pwg[i-1]*g%mod;
for(int i=PWG[0]=1;i<=B;i++)PWG[i]=PWG[i-1]*pwg[B]%mod;
for(int i=pwig[0]=1;i<=B;i++)pwig[i]=pwig[i-1]*ig%mod;
for(int i=PWIG[0]=1;i<=B;i++)PWIG[i]=PWIG[i-1]*pwig[B]%mod;
for(int i=pw[0]=inv[1]=1;i<N;i++)pw[i]=pw[i-1]*2%mod;
for(int i=2;i<N;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod,lg[i]=lg[i>>1]+1;
}
inline int qpow(int k){
if(k==0)return 1;
if(k>0)return PWG[k/B]*pwg[k%B]%mod;
if(k<0)return PWIG[(-k)/B]*pwig[(-k)%B]%mod;
return 114514;
}
inline int qpow(int b,int k){
int s=1;
while(k){
if(k&1)s=s*b%mod;
b=b*b%mod;k>>=1;
}
return s;
}
struct Poly{
#define ite vector<int>::iterator
#define rite vector<int>::reverse_iterator
vector<int>f;
Poly(int x,int y=0){f=vector<int>(x,y);}
Poly(vector<int>x=vector<int>(0)){f=x;}
inline int size(){return f.size();}
inline int back(){return f.back();}
inline bool empty(){return f.empty();}
inline int&operator[](int x){return f[x];}
inline ite begin(){return f.begin();}
inline ite end(){return f.end();}
inline rite rbegin(){return f.rbegin();}
inline rite rend(){return f.rend();}
inline void swap(Poly&b){vector<int>tmp=f;f=b.f;b.f=tmp;}
inline void sort(ite BEGIN,ite END){sort(BEGIN,END);}
inline void sort(rite BEGIN,rite END){sort(BEGIN,END);}
inline void erase(ite BEGIN,ite END){f.erase(BEGIN,END);}
inline void reverse(ite BEGIN,ite END){reverse(BEGIN,END);}
inline void emplace_back(int x){f.emplace_back(x);}
inline void clear(){f.clear();}
inline void erase(ite x){f.erase(x);}
inline void pop_back(){f.pop_back();}
inline void resize(int x){f.resize(x);}
inline void reserve(int x){f.reserve(x);}
inline void resize(int x,int y){f.resize(x,y);}
inline void shrink_to_fit(){f.shrink_to_fit();}
inline bool operator==(Poly b){return f==b.f;}
inline bool operator!=(Poly b){return f!=b.f;}
inline bool operator<(Poly b){return f<b.f;}
inline bool operator>(Poly b){return f>b.f;}
inline bool operator<=(Poly b){return f<=b.f;}
inline bool operator>=(Poly b){return f>=b.f;}
};
inline void Complete(Poly&f,int len){while(f.size()<len)f.emplace_back(0);}
inline void Init(Poly&x,int len){
int p=pw[lg[len]];
while(p<len)p<<=1;
if(len<p)Complete(x,p);
}// Complete to 2^x
inline void NTT(Poly&f,int t){
/*
// Recurrence
if(f.size()==1)return;
int n=f.size(),buf=1,G=qpow(t*(mod-1)/n);
Poly l(n>>1),r(n>>1);
for(int i=0;i<n>>1;i++)l[i]=f[i<<1],r[i]=f[i<<1|1];
NTT(l,t);NTT(r,t);
for(int i=0;i<n>>1;i++,buf=buf*G%mod){
f[i]=(l[i]+buf*r[i]%mod)%mod;
f[i+(n>>1)]=(l[i]+mod-buf*r[i]%mod)%mod;
}
*/
// Butterfly
int n=f.size();
for(int i=0;i<n;i++)trans[i]=(trans[i>>1]>>1)|((i&1)?n>>1:0);
for(int i=0;i<n;i++)if(i<trans[i])swap(f[i],f[trans[i]]);
for(int p=2;p<=n;p<<=1){
int len=p>>1,G=qpow(t*(mod-1)/p);
for(int i=0;i<n;i+=p)
for(int j=i,buf=1;j<i+len;j++,buf=1ll*buf*G%mod){
int d=1ll*buf*f[j+len]%mod;
f[j+len]=(f[j]+mod-d)%mod;
f[j]=(f[j]+d)%mod;
}
}
}// NTT
inline Poly Convol(Poly a,Poly b){
int len=a.size()+b.size(),p=pw[lg[len]];
while(p<len)p<<=1;
Complete(a,p);NTT(a,1);
Complete(b,p);NTT(b,1);
for(int i=0;i<p;i++)a[i]=a[i]*b[i]%mod;
NTT(a,-1);
for(int i=0;i<p;i++)a[i]=a[i]*inv[p]%mod;
while(a.back()==0)a.pop_back();
return a;
}// Convolution
inline Poly Inverse(Poly f){
Init(f,f.size());
if(f.size()==1)return Poly(1,qpow(f[0],mod-2));
int n=f.size(),p=pw[lg[n]];
Poly hlf(n>>1);
for(int i=0;i<n>>1;i++)hlf[i]=f[i];
Poly g=Inverse(hlf);
while(p<n<<1)p<<=1;
Complete(f,p);NTT(f,1);
Complete(g,p);NTT(g,1);
for(int i=0;i<p;i++)g[i]=(2+mod-f[i]*g[i]%mod)%mod*g[i]%mod;
NTT(g,-1);
for(int i=n;i<p;i++)g[i]=0;
for(int i=0;i<p;i++)g[i]=g[i]*inv[p]%mod;
return g;
}// Inverse
inline Poly operator+(Poly a,Poly b){
Poly ret(max(a.size(),b.size()));
for(int i=0;i<a.size();i++)add(ret[i],a.f[i]);
for(int i=0;i<b.size();i++)add(ret[i],b.f[i]);
return ret;
}
inline Poly operator-(Poly a,Poly b){
Poly ret(max(a.size(),b.size()));
for(int i=0;i<a.size();i++)add(ret[i],a.f[i]);
for(int i=0;i<b.size();i++)add(ret[i],mod-b.f[i]);
while(ret.f.back()==0)ret.f.pop_back();
return ret;
}
inline Poly operator*(Poly a,Poly b){return Poly(Convol(a.f,b.f));}
inline Poly operator*(Poly x,int v){return Poly(x*Poly(1,v));}
inline Poly operator/(Poly a,Poly b){return Poly(Convol(a.f,Inverse(b.f)));}
inline Poly Derivative(Poly x){
if(x.size()==0)return x;
Poly ret(x.size()-1);
for(int i=0;i<ret.size();i++)ret[i]=x[i+1]*(i+1)%mod;
return ret;
}// F'(x)
inline Poly Integral(Poly x){
Poly ret(x.size()+1);
for(int i=1;i<ret.size();i++)ret[i]=x[i-1]*inv[i]%mod;
return ret;
}// ∫ F(x)dx
inline Poly Ln(Poly x){return Integral(Derivative(x)*Inverse(x));}// ln(F(x))
inline Poly Exp(Poly f){
Init(f,f.size());
if(f.size()==1)return Poly(1,1);
int n=f.size(),p=pw[lg[n]];
Poly hlf(n>>1);
for(int i=0;i<n>>1;i++)hlf[i]=f[i];
Poly g=Exp(hlf);
while(p<n<<1)p<<=1;
Complete(f,p);
Complete(g,p);
Poly lng=Ln(g);
Complete(lng,p);f[0]++;
for(int i=n;i<p;i++)f[i]=lng[i]=0;
for(int i=0;i<n;i++)f[i]=(f[i]-lng[i]+mod)%mod;
NTT(f,1);NTT(g,1);
for(int i=0;i<p;i++)g[i]=g[i]*f[i]%mod;
NTT(g,-1);
for(int i=n;i<p;i++)g[i]=0;
for(int i=0;i<p;i++)g[i]=g[i]*inv[p]%mod;
return g;
}// exp(F(x))
inline Poly operator^(Poly x,int k){return Exp(Ln(x)*k);}
inline Poly operator^(Poly x,string k){
int len=k.size(),k1=0,k2=0,k3=0,shift=0;
for(int i=0;i<len;i++)k1=(k1*10ll%mod+k[i]-'0')%mod;
for(int i=0;i<len;i++)k2=(k2*10ll%(mod-1)+k[i]-'0')%(mod-1);
for(int i=0;i<len;i++)if(k3*10ll+k[i]-'0'<=mod)k3=k3*10ll+k[i]-'0';
while(shift<x.size()&&x[shift]==0)shift++;
if(shift>=x.size()||shift*k3>=x.size())return Poly(0);
int inver=qpow(x[shift],mod-2),coef=qpow(x[shift],k2);
Poly tmp=Poly(x.size()-shift);
for(int i=0;i+shift<x.size();i++)tmp[i]=x[i+shift]*inver%mod;
tmp=tmp^(k1%mod);shift=shift*k1;x=Poly(tmp.size()+shift);
for(int i=0;i<shift;i++)x[i]=0;
for(int i=0;i<tmp.size();i++)x[i+shift]=tmp[i]*coef%mod;
return x;
}// F^k(x)
}
using namespace Polynomial;// call Init() before use
namespace Math{
int Fac[N],IFac[N];
void Init(int n){
for(int i=Fac[0]=1;i<=n;i++)Fac[i]=Fac[i-1]*i%mod;
IFac[n]=qpow(Fac[n],mod-2);
for(int i=n-1;~i;i--)IFac[i]=IFac[i+1]*(i+1)%mod;
}
inline int C(int n,int m){return n<m?0:Fac[n]*IFac[m]%mod*IFac[n-m]%mod;}
}
using namespace Math;
// ending