#include <bits/stdc++.h>
using namespace std;
using lint = long long;
const int MAXN = 2000005;
const int mod = 998244353;

int n, m;
lint fact[MAXN], invf[MAXN];

lint ipow(int x, int p){
	lint ret = 1, piv = x;
	while(p){
		if(p & 1) ret = ret * piv % mod;
		piv = piv * piv % mod;
		p >>= 1;
	}
	return ret;
}

lint binom(int x, int y){
	return fact[x] * (invf[y] * invf[x - y] % mod) % mod;
}

int f(int n, int odds, int sum){
	lint ret = 0;
	for(int i=0; i<=odds && i <= sum && i <= n; i++){
		if(sum % 2 == i % 2){
			ret += binom((sum - i) / 2 + n - 1, n - 1) * binom(n, i) % mod;
		}
	}
	return ret % mod;
}

lint g(int n, int sum){
	return binom(sum + n - 1, n - 1);
}

int main(){
	fact[0] = invf[0] = 1;
	for(int i=1; i<MAXN; i++){
		fact[i] = fact[i-1] * i % mod;
		invf[i] = ipow(fact[i], mod - 2);
	}
	cin >> n >> m;
	lint ret = f(n, m, 3 * m);
	for(int i=2*m+1; i<=3*m; i++){
		ret += mod - n * g(n - 1, 3 * m - i) % mod;
	}
	cout << ret % mod << endl;
}

### Prompt

Please create a solution in CPP to the following problem:

We have a sequence of N integers: x=(x_0,x_1,\cdots,x_{N-1}). Initially, x_i=0 for each i (0 \leq i \leq N-1).

Snuke will perform the following operation exactly M times:

* Choose two distinct indices i, j (0 \leq i,j \leq N-1,\ i \neq j). Then, replace x_i with x_i+2 and x_j with x_j+1.



Find the number of different sequences that can result after M operations. Since it can be enormous, compute the count modulo 998244353.

Constraints

* 2 \leq N \leq 10^6
* 1 \leq M \leq 5 \times 10^5
* All values in input are integers.

Input

Input is given from Standard Input in the following format:


N M


Output

Print the number of different sequences that can result after M operations, modulo 998244353.

Examples

Input

2 2


Output

3


Input

3 2


Output

19


Input

10 10


Output

211428932


Input

100000 50000


Output

3463133

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
const int MAXN = 2000005;
const int mod = 998244353;

int n, m;
lint fact[MAXN], invf[MAXN];

lint ipow(int x, int p){
	lint ret = 1, piv = x;
	while(p){
		if(p & 1) ret = ret * piv % mod;
		piv = piv * piv % mod;
		p >>= 1;
	}
	return ret;
}

lint binom(int x, int y){
	return fact[x] * (invf[y] * invf[x - y] % mod) % mod;
}

int f(int n, int odds, int sum){
	lint ret = 0;
	for(int i=0; i<=odds && i <= sum && i <= n; i++){
		if(sum % 2 == i % 2){
			ret += binom((sum - i) / 2 + n - 1, n - 1) * binom(n, i) % mod;
		}
	}
	return ret % mod;
}

lint g(int n, int sum){
	return binom(sum + n - 1, n - 1);
}

int main(){
	fact[0] = invf[0] = 1;
	for(int i=1; i<MAXN; i++){
		fact[i] = fact[i-1] * i % mod;
		invf[i] = ipow(fact[i], mod - 2);
	}
	cin >> n >> m;
	lint ret = f(n, m, 3 * m);
	for(int i=2*m+1; i<=3*m; i++){
		ret += mod - n * g(n - 1, 3 * m - i) % mod;
	}
	cout << ret % mod << endl;
}

```