#include <time.h>
#include <iomanip>
#include <iostream>
#include <map>
#include <algorithm>
#include <queue>
#include <set>
#include <vector>
#include <iomanip>
#include <bitset>
using namespace std;
#define pi pair<int ,int>
long long n , m , p[5001][5001] , mod = 998244353 , kq = 0;
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	srand (time(NULL));
	int test = 1;
	//cin >> test;
	while (test--)
	{
		cin >> n >> m;
		for (int i = 1 ; i <= n || i <= m ; i++)
		{
			p[i][0] = 1;
			for (int e = 1 ; e <= n || e <= m ; e++)
			{
				p[i][e] = 1ll * p[i][e-1] * i % mod;
			}
		}
		p[0][0] = 1;
		for (int i = 1 ; i <= n ; i++)
		{
			for (int e = 1 ; e <= m ; e++)
			{
				long long res = p[m - e][i - 1] * p[m][n - i - 1] % mod;
				res *= 1ll * (n-i);
				res %= mod;
				kq += res;
				kq %= mod;
			}
		}
		cout <<(1ll * n * p[m][n] % mod - kq + mod) % mod<<'\n';
	}
}


// In the name of Arceus

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
 
#define For(i, l, r) for (i = int(l); i <= int(r); i++)
#define Fo(i, n) For(i, 1, n)
#define Rof(i, r, l) for (i = int(r); i >= int(l); i--)
#define Ro(i, n) Rof(i, n, 1)
#define clr(a) memset(a, 0, sizeof(a))
#define cpy(a, b) memcpy(a, b, sizeof(b))
#define fc(a, ch) memset(a, ch, sizeof(a))
 
typedef unsigned long long uint64;
typedef long long int64;
 
#define T1 template <class A>
#define T2 template <class A, class B>
#define T3 template <class A, class B, class C>
#define T4 template <class A, class B, class C, class D>
inline void read(char &x) {
    do
        x = getchar();
    while (x <= ' ');
}
inline void read(char *s) {
    char ch;
 
    do
        ch = getchar();
    while (ch <= ' ');
    while (ch > ' ') {
        (*s) = ch;
        s++;
        ch = getchar();
    }
    (*s) = 0;
}
inline void read(std::string &s) {
    char ch;
 
    do
        ch = getchar();
    while (ch <= ' ');
    while (ch > ' ') {
        s.push_back(ch);
        ch = getchar();
    }
}
T1 inline void readint(A &x) {
    bool neg = false;
    char ch;
 
    do
        ch = getchar();
    while (ch <= ' ');
    if (ch == '-') {
        neg = true;
        ch = getchar();
    }
    x = 0;
    while (ch > ' ') {
        x = x * 10 + (ch & 15);
        ch = getchar();
    }
    if (neg)
        x = -x;
}
inline void read(int &x) { readint(x); }
inline void read(int64 &x) { readint(x); }
 
T2 inline void read(A &a, B &b) {
    read(a);
    read(b);
}
T3 inline void read(A &a, B &b, C &c) {
    read(a);
    read(b);
    read(c);
}
T4 inline void read(A &a, B &b, C &c, D &d) {
    read(a);
    read(b);
    read(c);
    read(d);
}
inline void writeln() { putchar('\n'); }
T1 inline void writeint(A x) {
    static char buf[20];
    int top = 0;
 
    if (!x) {
        putchar('0');
        return;
    }
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    while (x) {
        buf[++top] = (x % 10) | 48;
        x /= 10;
    }
    while (top)
        putchar(buf[top--]);
}
inline void write(int x) { writeint(x); }
inline void write(unsigned x) { writeint(x); }
inline void write(int64 x) { writeint(x); }
inline void write(uint64 x) { writeint(x); }
inline void write(char ch) { putchar(ch); }
inline void write(char *s) {
	while(*s) {
		putchar(*s);
		s++;
	}
}
inline void write(const char *s) { printf(s); }
T1 inline void write_(A x) {
    write(x);
    putchar(' ');
}
T1 inline void writeln(A x) {
    write(x);
    putchar('\n');
}
T2 inline void write(A a, B b) {
    write_(a);
    write(b);
}
T2 inline void writeln(A a, B b) {
    write_(a);
    writeln(b);
}
T3 inline void writeln(A a, B b, C c) {
    write_(a);
    write_(b);
    writeln(c);
}
T4 inline void writeln(A a, B b, C c, D d) {
    write_(a);
    write_(b);
    write_(c);
    writeln(d);
}
#undef T1
#undef T2
#undef T3
#undef T4


// f[n][m]: 长度为 n，最大值不超过 m 
// f[n][m] = \sum_{i = 1}^n 
//			1)     (m - 1)^{n - 1} + m^{n - i} f[i - 1][m - 1] + (m - 1)^{i - 1} f[n - i][m]
//         = n(m - 1)^{n - 1} + m^n \sum_{i = 1}^n m^{-i} f[i - 1][m - 1] + (m - 1)^{-1} \sum_{i = 1}^n (m - 1)^i f[n - i][m]

// g[m][n]

const int N = 5000 + 10;
const int MOD = 998244353;

int n0, m0;
int g[N][N];

int main() {
	int n, m, mp;
	int fx, fy;
	int i;
	
	read(n0, m0);
	Fo(i, n0)
		g[1][i] = 1;
	
	For(m, 2, m0) {
		fx = fy = 0;
		mp = 1;
		Fo(n, n0) {
			fx = (1LL * fx * m + g[m - 1][n - 1]) % MOD;
			fy = (1LL * fy * (m - 1) + g[m][n - 1]) % MOD;
			g[m][n] = (g[m - 1][n] + 1LL * n * mp + fx + fy) % MOD;
			mp = mp * (m - 1LL) % MOD;
		}
	}
	writeln(g[m0][n0]);
	return 0;
}