Problem:
Score : 900 points

Problem Statement

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.

Sample Input 1

2 2

Sample Output 1

3

After two operations, there are three possible outcomes:

x=(2,4)

x=(3,3)

x=(4,2)

For example, x=(3,3) can result after the following sequence of operations:

First, choose i=0,j=1, changing x from (0,0) to (2,1).

Second, choose i=1,j=0, changing x from (2,1) to (3,3).

Sample Input 2

3 2

Sample Output 2

19

Sample Input 3

10 10

Sample Output 3

211428932

Sample Input 4

100000 50000

Sample Output 4

3463133

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)

import java.util.*;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		prepareFact();
		int n = sc.nextInt();
		int m = sc.nextInt();
		int sum = m * 3;
		long ans = combiMod(n - 1 + sum, n - 1);
		for(int i = m * 2 + 1; i <= sum; i ++) {
			long tmp = combiMod(n - 2 + (sum - i), n - 2);
			tmp = mod(tmp * (long)n);
			ans = mod(ans - tmp);
		}

		for(int i = m + 1; i <= n; i ++) {
			int rest = sum - i;
			if(rest % 2 != 0) { continue; }
			long tmp = combiMod(n - 1 + rest / 2, n - 1);
			tmp = mod(tmp * combiMod(n, i));
			ans = mod(ans - tmp);
		}
		System.out.println(ans);
	}

	static long MOD = 998244353;
	public static long mod(long i) {
		return i % MOD + ((i % MOD) < 0 ? MOD : 0);
	}
	
	static long powerMod(long x, long y) {
		if (y == 0) {
			return 1;
		} else if (y == 1) {
			return x;
		} else if (y % 2 == 0) {
			long tmp = powerMod(x, y / 2);
			return mod(tmp * tmp);
		} else {
			long tmp = powerMod(x, y / 2);
			return mod(mod(tmp * tmp) * x);
		}
	}
	
	static long invMod(long x) {
		return powerMod(x, MOD - 2);
	}
	
	static int MAX_FACT = 3_000_100;
	static long factMod[] = new long[MAX_FACT];
	static void prepareFact() {
		factMod[0] = 1;
		for(int i = 1; i < MAX_FACT; i ++) {
			factMod[i] = mod(factMod[i - 1] * i);
		}
	}
	
	static long combiMod(int n, int r) {
		if(n < 0 || n < r) { return 0; }
		if(r == 0 || r == n) { return 1; }
		return mod(mod(factMod[n] * invMod(factMod[r])) * invMod(factMod[n - r]));
	}
}