#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <bits/stdc++.h>

using namespace __gnu_pbds;
using namespace std;

using ll = long long;
using ld = long double;

typedef tree<
        int,
        null_type,
        less<int>,
        rb_tree_tag,
        tree_order_statistics_node_update>
        ordered_set;

#define mp make_pair


const int MOD =  998244353;

int mul(int a, int b) {
    return (1LL * a * b) % MOD;
}

int add(int a, int b) {
    int s = (a+b);
    if (s>=MOD) s-=MOD;
    return s;
}

int sub(int a, int b) {
    int s = (a+MOD-b);
    if (s>=MOD) s-=MOD;
    return s;
}

int po(int a, ll deg)
{
    if (deg==0) return 1;
    if (deg%2==1) return mul(a, po(a, deg-1));
    int t = po(a, deg/2);
    return mul(t, t);
}

int inv(int n)
{
    return po(n, MOD-2);
}


mt19937 rnd(time(0));

/*
const int LIM = 1e6 + 5;

vector<int> facs(LIM), invfacs(LIM);

void init()
{
    facs[0] = 1;
    for (int i = 1; i<LIM; i++) facs[i] = mul(facs[i-1], i);
    invfacs[LIM-1] = inv(facs[LIM-1]);
    for (int i = LIM-2; i>=0; i--) invfacs[i] = mul(invfacs[i+1], i+1);
}

int C(int n, int k)
{
    if (n<k) return 0;
    if (n<0 || k<0) return 0;
    return mul(facs[n], mul(invfacs[k], invfacs[n-k]));
}*/


/*struct DSU
{
    vector<int> sz;
    vector<int> parent;
    void make_set(int v) {
        parent[v] = v;
        sz[v] = 1;
    }

    int find_set(int v) {
        if (v == parent[v])
            return v;
        else
        {
            auto par = find_set(parent[v]);
            parent[v] = par;
            return par;
        }
    }

    void union_sets(int a, int b) {
        find_set(a);
        find_set(b);

        a = find_set(a);
        b = find_set(b);

        if (a != b) {
            if (sz[a] < sz[b])
                swap(a, b);
            parent[b] = a;
            sz[a] += sz[b];
        };
    }

    DSU (int n)
    {
        parent.resize(n);
        sz.resize(n);
        for (int i = 0; i<n; i++) make_set(i);
    }
};*/



int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr);

    int n, m; cin>>n>>m;

    vector<vector<int>> degs(m+1, vector<int>(n+1));

    for (int i = 1; i<=m; i++)
    {
        degs[i][0] = 1;
        for (int j = 1; j<=n; j++) degs[i][j] = mul(degs[i][j-1], i);
    }

    ll tot = mul(n, degs[m][n]);
    for (int len = 1; len<=n-1; len++)
    {
        int sum = 0;
        for (int val = 1; val<=m; val++)
        {
            if (val==m && len>1) continue;
            //probability = 1/m^2 + (m - val)^(len-1)
            int cnt = degs[m][n - len - 1];
            if (len>=2) cnt = mul(cnt, degs[m - val][len-1]);
            sum = add(sum, cnt);
        }
        tot = sub(tot, mul(sum, n-len));
    }

    cout<<tot;

}

/*
f(n, m) = f(n, m-1) + //Case when there are several ones



 */
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long INF = 1LL<<60;
const double PI = acos(-1.0);
/*const double PI = atan2(0.0,-1.0)*/
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
#define rep(i, n) for(ll i = 0; i < (ll)(n); i++)
#define rep1(i,aa,n) for(ll i = aa; i <= (ll)(n); i++)
#define ALL(a)  (a).begin(),(a).end()
#define ar_init(aa,val) rep(i,aa.size()) aa[i]=val;
#define v2d(aa,val1,val2,ini) vector<vector<ll>> aa(val1,vector<ll>(val2,ini));
#define pqe priority_queue<ll>
#define pqeg priority_queue<ll,vector<ll>,greater<ll>>
#define lcin(...) ll __VA_ARGS__;CINT(__VA_ARGS__)
#define eout(...) COU(__VA_ARGS__);
#define sout(...) SCOU(__VA_ARGS__);
#define scin(...) string __VA_ARGS__;CINT(__VA_ARGS__)
#define lb(aa,val) lower_bound(ALL(aa),val)
#define pb push_back
#define mkp make_pair
#define si size()

void CINT(){}
template <class Head,class... Tail>
void CINT(Head&& head,Tail&&... tail){
    cin>>head;
    CINT(move(tail)...);
}

void COU(){}
template <class Head,class... Tail>
void COU(Head&& head,Tail&&... tail){
    cout<<head<<endl;
    COU(move(tail)...);
}

void SCOU(){}
template <class Head,class... Tail>
void SCOU(Head&& head,Tail&&... tail){
    cout<<head<<" ";
    SCOU(move(tail)...);
}

template <class T = ll>
T IN(){T x;cin>>x;return (x);}

using pii = pair<ll,ll>;
using v2 = vector<vector<ll>>;
using v1 = vector<ll>;
using v2p = vector<vector<pii>>;
using v1p = vector<pii>;
//ll mo=1000000007;
ll mo=998244353;

ll mod_pow(ll N,ll n){
if(n==0) return 1;
ll pp,hh;
pp=n/2;
hh=n%2;
int tt=mod_pow(N,n/2);
if(hh==0)return tt%mo*tt%mo;
else {return tt%mo*tt%mo*N%mo;}
}

ll pp[6000][6000];
int main(){
//cout<<fixed<<setprecision(15);

lcin(n,m);

rep1(i,1,m){
pp[i][0]=1;
rep1(k,1,n){
pp[i][k]=pp[i][k-1]*i;
pp[i][k]%=mo;
}
}

ll res=0;

rep1(i,1,m){
rep1(k,1,n){
if(k+2<=n){res+=pp[m][n-k-2]*(pp[m-i+1][k]-pp[m-i][k])%mo*max((ll)0,n-k+1-2)*(i-1)%mo*(i-1)%mo;
}
if(k!=n){res+=2*pp[m][max((ll)0,n-k-1)]*(pp[m-i+1][k]-pp[m-i][k])%mo*(i-1)%mo;
}
if(k==n){res+=pp[m-i+1][k]-pp[m-i][k];
res%=mo;
}

}
}

eout(res);
}