#include <bits/stdc++.h>
#define int long long
using namespace std;

// https://github.com/nweeks1/UltiSnips
template <const int32_t MOD> struct ModInt {
  long long x;
  ModInt() : x(0) {}
  ModInt(long long u) : x(u) {
    x %= MOD;
    if (x < 0)
      x += MOD;
  }
  friend bool operator==(const ModInt &a, const ModInt &b) {
    return a.x == b.x;
  }
  friend bool operator!=(const ModInt &a, const ModInt &b) {
    return a.x != b.x;
  }
  friend bool operator<(const ModInt &a, const ModInt &b) { return a.x < b.x; }
  friend bool operator>(const ModInt &a, const ModInt &b) { return a.x > b.x; }
  friend bool operator<=(const ModInt &a, const ModInt &b) {
    return a.x <= b.x;
  }
  friend bool operator>=(const ModInt &a, const ModInt &b) {
    return a.x >= b.x;
  }
  static ModInt sign(long long k) {
    return ((k & 1) ? ModInt(MOD - 1) : ModInt(1));
  }

  ModInt &operator+=(const ModInt &m) {
    x += m.x;
    if (x >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator-=(const ModInt &m) {
    x -= m.x;
    if (x < 0LL)
      x += MOD;
    return *this;
  }
  ModInt &operator*=(const ModInt &m) {
    x = (1LL * x * m.x) % MOD;
    return *this;
  }

  friend ModInt operator-(const ModInt &a) {
    ModInt res(a);
    if (res.x)
      res.x = MOD - res.x;
    return res;
  }
  friend ModInt operator+(const ModInt &a, const ModInt &b) {
    return ModInt(a) += ModInt(b);
  }
  friend ModInt operator-(const ModInt &a, const ModInt &b) {
    return ModInt(a) -= ModInt(b);
  }
  friend ModInt operator*(const ModInt &a, const ModInt &b) {
    return ModInt(a) *= ModInt(b);
  }

  static long long fp(long long u, long long k) {
    long long res = 1LL;
    while (k > 0LL) {
      if (k & 1LL)
        res = (res * u) % MOD;
      u = (u * u) % MOD;
      k /= 2LL;
    }
    return res;
  }

  static constexpr int mod() { return MOD; }

  ModInt fastpow(long long k) { return ModInt(fp(x, k)); }
  ModInt inv() {
    assert(x);
    return ModInt(fp(x, MOD - 2));
  }
  ModInt &operator/=(const ModInt &m) { return *this *= ModInt(m).inv(); }
  friend ModInt operator/(const ModInt &a, const ModInt &b) {
    return ModInt(a) *= ModInt(b).inv();
  }

  friend ostream &operator<<(ostream &out, const ModInt &a) {
    return out << a.x;
  }
  friend istream &operator>>(istream &in, ModInt &a) { return in >> a.x; }
};

// const int MOD = 1e9 + 7;
const int MOD = 998244353;
using Mint = ModInt<MOD>;

signed main(void) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int N, M;
  cin >> N >> M;

  vector<Mint> dp(N);
  vector<Mint> A(N);
  dp[0] = M;
  for (int i(1); i < N; ++i) {
    A[i] = A[i - 1] * M;
    Mint x = Mint(M - 1).fastpow(i - 1);
    for (int m(1); m <= M; ++m)
      A[i] += x - Mint(M - m).fastpow(i - 1);
    dp[i] = dp[i - 1] * M + M * Mint(M - 1).fastpow(i) + A[i];
  }

  cout << dp[N - 1] << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define m_p make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
typedef long long ll;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
mt19937 rnf(2106);
const int N = 5003, M = 998244353;

/*int ast(int x, int n)
{
    int ans = 1;
    while (n)
    {
        if (n % 2 == 1)
            ans = (ans * 1LL * x) % M;
        x = (x * 1LL * x) % M;
        n /= 2;
    }
    return ans;
}*/

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

int ast[N][N];

void solv()
{
    cin >> n0 >> m0;

    for (int i = 1; i < N; ++i)
    {
        ast[i][0] = 1;
        for (int j = 1; j < N; ++j)
            ast[i][j] = (ast[i][j - 1] * 1LL * i) % M;
    }

    for (int m = 1; m <= m0; ++m)
    {
        int f0 = 0;
        int f = 0;
        int s = 0;
        for (int n = 1; n <= n0; ++n)
        {
            /*for (int d = 1; d <= n - 2; ++d)
            {
                dp[n][m] = (dp[n][m] + dp[d][m - 1] * 1LL * ast(m, n - d - 2) % M * 1LL * (n - d - 1)) % M;
            }*/
            f = (f + f0) % M;
            f = (f * 1LL * m) % M;
            if (n - 2 >= 1)
                f = (f + dp[n - 2][m - 1]) % M;
            f0 = (f0 * 1LL * m) % M;
            if (n - 2 >= 1)
                f0 = (f0 + dp[n - 2][m - 1]) % M;
            /*for (int d = 1; d <= n - 1; ++d)
            {
                dp[n][m] = (dp[n][m] + dp[d][m - 1] * 2LL * ast(m, n - d - 1)) % M;
            }*/
            s = (s * 1LL * m) % M;
            if (n - 1 >= 1)
                s = (s + dp[n - 1][m - 1] * 2LL) % M;
            dp[n][m] = (f + s) % M;
            dp[n][m] = (dp[n][m] + dp[n][m - 1]) % M;
            dp[n][m] = (dp[n][m] + ast[m][n]) % M;
            dp[n][m] = (dp[n][m] - ast[m - 1][n] + M) % M;
        }
    }

    cout << dp[n0][m0] << "\n";
}

int main()
{
    #ifdef SOMETHING
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    #endif // SOMETHING
    ios_base::sync_with_stdio(false), cin.tie(0);

    int tt = 1;
    //cin >> tt;
    while (tt--)
    {
        solv();
    }
    return 0;
}
