#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
const int inv2=(mod+1)>>1;

int gi() {
    int x=0,o=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') o=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*o;
}

int add(int a,int b) {
    return a+b>=mod?a+b-mod:a+b;
}

int sub(int a,int b) {
    return a-b<0?a-b+mod:a-b;
}

int mul(int a,int b) {
    return 1ll*a*b%mod;
}

int qpow(int a,int b) {
    int ret=1;
    while(b) {
        if(b&1) ret=mul(ret,a);
        a=mul(a,a),b>>=1;
    }
    return ret;
}

vector<int> padd(vector<int> a,vector<int> b) {
    if(a.size()<b.size()) a.resize(b.size());
    for(int i=0;i<b.size();i++) a[i]=add(a[i],b[i]);
    return a;
}

vector<int> psub(vector<int> a,vector<int> b) {
    if(a.size()<b.size()) a.resize(b.size());
    for(int i=0;i<b.size();i++) a[i]=sub(a[i],b[i]);
    return a;
}

int www[1000010];

vector<int> pmul(vector<int> a,vector<int> b) {
    int n=a.size(),m=b.size(),l=0;
    if(n<70||m<70) {
        vector<int> ret(n+m-1);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++) ret[i+j]=add(ret[i+j],mul(a[i],b[j]));
        return ret;
    }
    m=n+m-1;for(n=1;n<m;n<<=1) ++l;
    vector<int> r(n);
    for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    auto dft=[&](vector<int> &a,int f) {
        for(int i=0;i<n;i++) if(i<r[i]) swap(a[i],a[r[i]]);
        for(int i=1;i<n;i<<=1) {
            int wn=qpow(3,(mod-1)/(i<<1));
			if(f==-1) wn=qpow(wn,mod-2);
			int *P=www;*P=1;
			for(int j=1;j<i;j++) *(P+j)=1ll**(P+j-1)*wn%mod;
            for(int p=i<<1,j=0;j<n;j+=p) {
                for(int k=0;k<i;k++) {
                    int x=a[j+k],y=mul(*(P+k),a[j+k+i]);
                    a[j+k]=add(x,y),a[j+k+i]=sub(x,y);
                }
            }
        }
        if(f==-1) {
            int inv=qpow(n,mod-2);
            for(int i=0;i<n;i++) a[i]=mul(a[i],inv);
        }
    };
    a.resize(n),b.resize(n);
    dft(a,1),dft(b,1);
    for(int i=0;i<n;i++) a[i]=mul(a[i],b[i]);
    dft(a,-1);
    a.resize(m);return a;
}

int get2(int n) {
    int ret=1;
    while(ret<n) ret<<=1;
    return ret;
}

vector<int> pinv(vector<int> a,int n) {
    if(n==1) return vector<int>(1,qpow(a[0],mod-2));
    auto rem_a=a;rem_a.resize(n>>1);
    auto b=pinv(rem_a,n>>1);
    auto ret=pmul(a,b);ret.resize(n);
    ret=pmul(ret,b);ret.resize(n);
    ret=psub(pmul(b,vector<int>(1,2)),ret);
    return ret;
}

vector<int> pder(vector<int> a) {
    for(int i=1;i<a.size();i++) a[i-1]=mul(i,a[i]);
    a.pop_back();
    return a;
}

vector<int> pint(vector<int> a) {
    vector<int> inv(a.size()+1);
    inv[1]=1;for(int i=2;i<inv.size();i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    a.push_back(0);
    for(int i=a.size()-2;~i;i--) a[i+1]=mul(inv[i+1],a[i]);
    a[0]=0;
    return a;
}

vector<int> pln(vector<int> a,int n) {
    auto ret=pder(a);
    ret=pmul(ret,pinv(a,n));
    ret.resize(n);
    ret=pint(ret);
    ret.resize(n);
    return ret;
}

namespace Exp {

	int w[1000010],r[1000010],F[1000010],G[1000010],A[1000010],B[1000010],len,inv[1000010];

	void inc(int &a,int b) {
		a=a+b>=mod?a+b-mod:a+b;
	}

	void dec(int &a,int b) {
		a=a-b<0?a-b+mod:a-b;
	}

	void NTT(int *a,int f) {
		for(int i=0;i<len;i++) if(i<r[i]) swap(a[i],a[r[i]]);
		for(int i=1;i<len;i<<=1) {
			int wn=qpow(3,(mod-1)/(i<<1));
			int *W=w;*W=1;for(int j=1;j<i;j++) *(W+j)=1ll**(W+j-1)*wn%mod;
			for(int p=i<<1,j=0;j<len;j+=p)
				for(int k=0;k<i;k++) {
					int x=a[j+k],y=1ll**(W+k)*a[j+k+i]%mod;
					a[j+k]=x+y>=mod?x+y-mod:x+y;
					a[j+k+i]=x-y<0?x-y+mod:x-y;
				}
		}
		if(f==-1) {
			reverse(a+1,a+len);
			int inv=qpow(len,mod-2);
			for(int i=0;i<len;i++) a[i]=1ll*a[i]*inv%mod;
		}
	}

	void init() {
		int l=__builtin_ctz(len);
		for(int i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
	}

	void init_inv() {
		inv[1]=1;
		for(int i=2;i<1000010;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	}
	
	void solve(int l,int r) {
		if(l==r) {
			if(l) G[l]=1ll*G[l]*inv[l]%mod;
			return;
		}
		int mid=(l+r)>>1;
		solve(l,mid);
		if(r-l<200) {
			for(int i=mid+1;i<=r;i++)
				for(int j=l;j<=mid;j++) G[i]=(G[i]+1ll*G[j]*F[i-j]%mod*(i-j))%mod;
		}
		else {
			len=1;while(len<=r-l) len<<=1;init();
			for(int i=0;i<len;i++) A[i]=B[i]=0;
			for(int i=l;i<=mid;i++) A[i-l]=G[i];
			for(int i=0;i<=r-l;i++) B[i]=1ll*i*F[i]%mod;
			NTT(A,1);NTT(B,1);
			for(int i=0;i<len;i++) A[i]=1ll*A[i]*B[i]%mod;
			NTT(A,-1);
			for(int i=mid+1;i<=r;i++) inc(G[i],A[i-l]);
		}
		solve(mid+1,r);
	}

}

vector<int> pexp(vector<int> a,int n) {
	a.resize(n);
	for(int i=0;i<n;i++) Exp::F[i]=a[i];
	Exp::G[0]=1;Exp::solve(0,n-1);
	for(int i=0;i<n;i++) a[i]=Exp::G[i];
	return a;
}

vector<int> pqpow(vector<int> a,int k,int n) {
	int t=a[0];
	for(auto &x:a) x=1ll*x*qpow(t,mod-2)%mod;
	vector<int> c=pln(a,n);
	for(auto &x:c) x=1ll*x*k%mod;
	c=pexp(c,n);
	for(auto &x:c) x=1ll*x*qpow(t,k)%mod;
	return c;
}

int fac[1000010];

int main() {
	int n=gi(),m=gi();Exp::init_inv();
	fac[0]=1;for(int i=1;i<=m;i++) fac[i]=1ll*fac[i-1]*i%mod;
	vector<int> G(m+1);
	for(int i=0;i<=m;i++) G[i]=1ll*(m+1-i)*qpow(fac[i],mod-2)%mod;
	vector<int> F=pqpow(G,n,get2(m+1));
	int ans=0;
	for(int i=0;i<=m;i++) ans=(ans+1ll*F[i]*qpow(fac[m-i],mod-2))%mod;
	ans=1ll*ans*fac[m]%mod;
	cout<<ans;
    return 0;
}


Measured memory_bytes: 53216