#include <bits/stdc++.h>

typedef long long LL;
typedef unsigned long long ULL;

#define debug printf("fuck %d\n", __LINE__);

inline LL read() {
	LL res = 0, bo = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') bo = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		res = (res << 1) + (res << 3) + ch - '0';
		ch = getchar();
	}
	return bo * res;
}

template <typename T>
void read(T &x) {
	x = read();
}

template <typename T, typename... Argv>
void read(T &a, Argv &... argv) {
	read(a);
	read(argv...);
}

const int N = 1e6 + 100, p = 998244353;
int fac[N], inv[N], _n[N], _m[N];

template <typename T>
T mul(T x, T y) {
	return 1LL * x * y % p;
}

template <typename T, typename... Argv>
T mul(T x, Argv... argv) {
	return mul(x, mul(argv...));
}

int ksm(int x, int y) {
	int res = 1;
	for (; y; y >>= 1, x = mul(x, x))
		if (y & 1) res = mul(res, x);
	return res;
}

void init(int n, int m) {
	int M = std::max(n, m);
	fac[0] = _n[0] = _m[0] = 1;
	for (int i = 1; i <= M; ++i) fac[i] = mul(fac[i - 1], i);
	inv[M] = ksm(fac[M], p - 2);
	for (int i = M; i >= 1; --i) inv[i - 1] = mul(inv[i], i);
	for (int i = 1; i <= M; ++i) _n[i] = mul(_n[i - 1], n + 1);
	for (int i = 1; i <= M; ++i) _m[i] = mul(_m[i - 1], m + 1);
}

int C(int n, int m) {
	return m > n || m < 0 ? 0 : mul(fac[n], inv[m], inv[n - m]);
}

int main() {
	int n = read(), m = read(), ans = 0;
	init(n, m);
	for (int i = 0, opt = 1; i <= n; ++i, opt = p - opt) {
		(ans += mul(opt, C(n, i), C(m, i), fac[i], _m[n - i], _n[m - i])) %= p;
	}
	std::cout << ans << std::endl;
	return 0;
}
