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

using namespace std;
using namespace __gnu_pbds;

using LL = long long;
using LD = long double;
using ordered_set = tree<LL,null_type,less<LL>,rb_tree_tag,tree_order_statistics_node_update>;

void fastio() {
	cin.tie(nullptr);
	cin.sync_with_stdio(false);
}

const LL MOD = 998244353;
const LL INF = 1e18;
const LL N = 2e5+5;

#define S second
#define F first
#define vt vector

LL binpow(LL x, LL p, LL m) {
	LL res = 1;
	x %= m;
	while (p) {
		if (p&1) {
			res = res * x % m;
		}
		x = x * x % m;
		p >>= 1;
	}
	return res;
}

int main() {
	fastio();

	LL n, m;
	cin >> n >> m;

	LL sub = 0;

	for (LL d = 2; d <= n; ++d) {
		LL tim = n-d+1;
		LL res = 0;
		for (LL x = 1; x <= m; ++x) {
			res = (res + binpow(m-x, d-2, MOD) % MOD * binpow (m, n-d, MOD)) % MOD;
		}
		LL trm = (res * tim) % MOD;
		//cerr << trm << "?";
		sub = (sub + trm) % MOD;

	}

	LL ans = n*binpow(m, n, MOD) % MOD;

	ans -= sub;
	if (ans < 0) {
		ans += MOD;
	}

	cout << ans << "\n";

}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <climits>
#include <algorithm>
#include <string>
#include <sstream>
#include <complex>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <fstream>

using namespace std;
#define SZ(x) (int)(x).size()
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REPR(i,n) for(int i=(n)-1;i>=0;i--)
#define ALL(s) (s).begin(), (s).end()
#define so(V) sort(ALL(V))
#define rev(V) reverse(ALL(V))
#define uni(v) v.erase( unique(ALL(v)) , v.end());

typedef long long unsigned int llu;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<vi> vvi;
const double EPS = 1e-9;
const int MOD = 1e9 + 7;
const int INF = (1 << 29);
const ll LINF = 1e18;
const double PI = acos(-1);

template<typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }

template<typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
	return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T& t, const V& v) { t = v; }

template<typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T& t, const V& v) {
	for (auto& e : t) fill_v(e, v);
}
template<class T> bool chmax(T& a, const T& b) {
	if (a < b) { a = b; return 1; }
	return 0;
}
template<class T> bool chmin(T& a, const T& b) {
	if (a > b) { a = b; return 1; }
	return 0;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	ll S, P;
	cin >> S >> P;
	ll cur = 1;
	int ans = 0;
	while (cur * cur <= P) {
		if (P % cur == 0) {
			ll other = P / cur;
			if (cur + other == S) {
				ans++;
			}
		}
		cur++;
	}
	cout << ((ans != 0) ? "Yes" : "No") << endl;
	return 0;
}