#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include "debug.h"
#else
#define deb(...)
#endif
#define endl "\n"
#define pb push_back
#define int long long
#define ll long long
#define pii pair<int,int>
#define F first
#define S second
#define all(c) c.begin(),c.end()
#define read(v) for(auto &it:v) cin>>it;
const int inf = 1e18;
const int N   = 5e3 + 5;
const int mod = 998244353;
int maxi[12];
int n, m;
int ans = 0;
namespace factorial {
int fact[N + 5];
int power(int a, int b)
{
	if (b == 0) return 1;
	if (b == 1) return a % mod;
	if (b % 2 == 1) return (power(a, b - 1) * a) % mod;
	int q = power(a, b / 2);
	return (q * q) % mod;
}
int modinverse(int n)
{
	return power(n, mod - 2);
}
void generate_fact_()
{
	fact[0] = 1;
	for (int i = 1; i < N; i++)
		fact[i] = (fact[i - 1] * i) % mod;
}
int ncr(int n, int r)
{
	if (fact[n] == 0) {
		cerr << "Call generate_fact_ you dope" << endl;
		exit(1);
	}
	if (r == 0) return 1;
	return (fact[n] * (modinverse(fact[r]) ) % mod * (modinverse(fact[n - r]) ) % mod) % mod;
}

}
using namespace factorial;
namespace modop {
ll madd(ll a, ll b) {
	return (a + b) % mod;
}
ll msub(ll a, ll b) {
	return (((a - b) % mod) + mod) % mod;
}
ll mmul(ll a, ll b) {
	return ((a % mod) * (b % mod)) % mod;
}
ll mpow(ll base, ll exp) {
	ll res = 1;
	while (exp) {
		if (exp % 2 == 1) {
			res = (res * base) % mod;
		}
		exp >>= 1;
		base = (base * base) % mod;
	}
	return res;
}
ll minv(ll base) {
	return mpow(base, mod - 2);
}
ll mdiv(ll a, ll b) {
	return mmul(a, minv(b));
}
}

using namespace modop;
int dp[12][5005];
int go(int bit, int sum) {
	if (bit == 12) {
		if (sum == 0) {
			return 1;
		}
		else {
			return 0;
		}

	}
	if (dp[bit][sum] != -1) {
		return dp[bit][sum];
	}
	int ans = 0;
	int p = (1LL << bit);
	for (int i = 0; i <= maxi[bit]; i += 2) {
		int zx = i * p;
		if (zx <= sum) {
			int coeff = ncr(n, i);
			ans = madd(ans, mmul(coeff, go(bit + 1, sum - zx)));
		}
		else {
			break;
		}
	}

	return dp[bit][sum] = ans;

}
void testCase() {
	cin >> n >> m;
	generate_fact_();

	for (int i = 0; i <= 11; i++) {
		int max_take = min(n, m / (1 << i));
		maxi[i] = max_take;
	}
	memset(dp, -1, sizeof dp);
	cout << go(0, m) << endl;


}

int32_t main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int  t = 1;
	// cin >> t;
	while (t--)testCase();
	return 0;
}
#include<bits/stdc++.h>
using namespace std;

#define Mod(x) (x>=P)&&(x-=P)
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
#define erep(i,a) for(int i=hd[a];i;i=nxt[i])

typedef long long ll;
void Max(int &x,int y){(x<y)&&(x=y);}
void Min(int &x,int y){(x>y)&&(x=y);}

bool vio;
char IO;
int rd(int res=0){
	bool f=0;
	while(IO=getchar(),IO<48||IO>57)
		f=IO=='-';
	do res=(res<<1)+(res<<3)+(IO^48);
	while(IO=getchar(),isdigit(IO));
	return f?-res:res;
}
const int M=5005,P=998244353;
int pw[M][M],s[M];
bool let;
int main(){
	cerr<<(&vio-&let)/1024.0/1024<<endl;
	int n=rd(),m=rd();
	rep(i,0,m){
		rep(j,pw[i][0]=1,n){
			pw[i][j]=1ll*pw[i][j-1]*i%P;
			if(i!=m)s[j]+=pw[i][j],Mod(s[j]);
		}
	}
	s[0]=m;
	int ans=0;
	rep(i,1,n){
		if(i!=1)ans=1ll*ans*m%P;
		rep(j,1,i-1){
			ans+=1ll*pw[m][j-1]*(1ll*m*pw[m-1][i-j-1]%P-s[i-j-1]+P)%P;
			//rep(k,1,m)
			//ans+=1ll*pw[m][j-1]*(pw[m-1][i-j-1]-pw[m-k][i-j-1]+P)%P,Mod(ans);
			Mod(ans);
		}
		ans+=1ll*pw[m-1][i-1]*m%P,Mod(ans);
	}
	printf("%d",ans);
}
