#include using namespace std; #if __has_include() #include #endif 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,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 reps(i,a,n) for(int i=(a);i(0) 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 #else #define debug(...) static_cast(0) #define debugg(...) static_cast(0) templateostream &operator<<(ostream &os,const pair&p){os<>testcase; for(int i=0;i struct mod_int{ private: using uint=unsigned int; using mint=mod_int; uint v; static_assert(mv;} static constexpr int mod(){return m;} inline mint &operator+=(const mint &b){ this->v+=b.v; if(this->v>=m)this->v-=m; return *this; } inline mint &operator-=(const mint &b){ this->v-=b.v; if(this->v>=m)this->v+=m; return *this; } inline mint &operator*=(const mint &b){ this->v=(uint64_t(this->v)*uint64_t(b.v))%m; return *this; } inline mint &operator/=(const mint &b){ *this*=b.inv(); return *this; } inline mint operator+()const{return *this;} inline mint operator-()const{return mint()-*this;} friend inline mint operator+(const mint &a,const mint &b){return mint(a)+=b;} friend inline mint operator-(const mint &a,const mint &b){return mint(a)-=b;} friend inline mint operator*(const mint &a,const mint &b){return mint(a)*=b;} friend inline mint operator/(const mint &a,const mint &b){return mint(a)/=b;} friend inline bool operator==(const mint &a,const mint &b){return a.val()==b.val();} friend inline bool operator!=(const mint &a,const mint &b){return !(a==b);} inline mint operator++(int){ mint ret=*this; *this+=1; return ret; } inline mint operator--(int){ mint ret=*this; *this-=1; return ret; } mint pow(ll n)const{ mint ret=1,a(*this); while(n){ if(n&1)ret*=a; a*=a; n>>=1; } return ret; } inline mint inv()const{ assert(this->v!=0); return pow(m-2); } mint sqrt()const{ if(this->val()<=1)return *this; if constexpr(m%8==1){ mint b=2; while(b.pow((m-1)/2).val()==1)b++; int m2=m-1,e=0; while(m2%2==0)m2>>=1,e++; mint x=this->pow((m2-1)/2); mint y=(*this)*x*x; x*=*this; mint z=b.pow(m2); while(y.val()!=1){ int j=0; mint t=y; while(t.val()!=1)t*=t,j++; z=z.pow(1<<(e-j-1)); x*=z; z*=z; y*=z;e=j; } return x; } else if constexpr(m%8==5){ mint ret=this->pow((m+3)/8); if((ret*ret).val()==this->val())return ret; else return ret*mint::raw(2).pow((m-1)/4); } else{ return this->pow((m+1)/4); } } pair safe_sqrt()const{ if(this->pow((m-1)/2)==1)return make_pair(true,this->sqrt()); else return make_pair(false,0); } friend istream &operator>>(istream &is,mint &b){ ll a; is>>a; b=mint(a); return is; } friend ostream &operator<<(ostream &os,const mint &b){ os<; using mint107=mod_int<1000000007>; template struct F{ private: static int capacity; static vectorfact,factinv,inv; static void resize(int n){ fact.resize(n+1),factinv.resize(n+1),inv.resize(n+1); for(int i=capacity+1;i<=n;i++){ fact[i]=fact[i-1]*i; inv[i]=-inv[T::mod()%i]*(T::mod()/i); factinv[i]=factinv[i-1]*inv[i]; } capacity=n; } public: static T C(int n,int k){ if(n static T O(INT...k){ int n=0; for(int i:initializer_list{k...}){ if(i<0)return 0; n+=i; } if(capacity{k...})ret*=factinv[i]; return ret; } }; templateint F::capacity=1; templatevectorF::fact{1,1}; templatevectorF::factinv{1,1}; templatevectorF::inv{0,1}; using namespace std; template struct BinomialPrefixSum{ private: static vector>table; static const T inv2; static void resize(int n){ if(table.size()>n)return; int pre=table.size(); table.resize(n+1); for(int i=pre;i<=n;i++){ table[i].resize(i+1); table[i][0]=1; for(int j=1;j<=i;j++){ table[i][j]=table[i][j-1]; for(int k=1;k<=i;k++)table[i][j]+=F::C(i*i,i*(j-1)+k); } } } public: static T get(int n,int k){ if(n0&&n-sn*sn<(sn+1)*(sn+1)-n){ int sk=min(sn,k/sn); int sk2=sk*sn; T now=table[sn][sk]; for(int i=sn*sn;i::C(i,sk2); for(int i=sk2+1;i<=k;i++)now+=F::C(n,i); return now; } else{ sn++; int sk=k/sn; if(k-sk*sn<(sk+1)*sn-k){ int sk2=sk*sn; T now=table[sn][sk]; for(int i=sn*sn-1;i>=n;i--)now=(now+F::C(i,sk2))*inv2; for(int i=sk2+1;i<=k;i++)now+=F::C(n,i); return now; } else{ sk++; int sk2=sk*sn; int sn2=sn*sn; T now=table[sn][sk]; for(int i=sk2;i>k;i--)now-=F::C(sn2,i); for(int i=sn2-1;i>=n;i--)now=(now+F::C(i,k))*inv2; return now; } } } static inline T get(int n,int k1,int k2){ return get(n,k2)-get(n,k1-1); } }; templatevector>BinomialPrefixSum::table; templateconst T BinomialPrefixSum::inv2(T(2).inv()); using mint=mint998; void SOLVE(){ int n,m; cin>>n>>m; cout<<(mint(2).pow(n)-1)*BinomialPrefixSum::get(n-1,m-1)<<'\n'; }