#include "bits/stdc++.h"

#define REP(i, n) for (ll i = 0; i < ll(n); ++i)
#define RREP(i, n) for (ll i = ll(n) - 1; i >= 0; --i)
#define FOR(i, m, n) for (ll i = m; i < ll(n); ++i)
#define RFOR(i, m, n) for (ll i = ll(n) - 1; i >= ll(m); --i)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end());
#define INF 1000000001ll
#define MOD 1000000007ll
#define EPS 1e-9

constexpr int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
constexpr int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};

using namespace std;

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using vvi = vector<vi>;
using vvl = vector<vl>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

template <class T> bool chmin(T &a, const T &b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmax(T &a, const T &b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

#include "bits/stdc++.h"
template <int mod, bool isPrime = false> class Mint {
	using ll = long long;
	ll value;

  public:
	constexpr Mint() : value(0){};
	constexpr Mint(ll x) : value(x) {
		value %= mod;
		if (value < 0) value += mod;
	}
	constexpr Mint(const Mint &other) : value(other.value) {}

	ll &get() {
		return value;
	}
	ll get() const {
		return value;
	}

	constexpr Mint pow(ll n) {
		Mint ret(1), tmp(value);
		while (n) {
			if (n & 1) ret *= tmp;
			n >>= 1;
			tmp *= tmp;
		}
		return ret;
	}
	constexpr bool operator==(const Mint &a) const {
		return value == a.value;
	}
	constexpr bool operator!=(const Mint &a) const {
		return value != a.value;
	}
	constexpr Mint &operator=(const Mint &a) {
		value = a.value;
		return *this;
	}
	constexpr Mint &operator+=(const Mint &a) {
		if ((value += a.value) >= mod) value -= mod;
		return *this;
	}
	constexpr Mint &operator-=(const Mint &a) {
		if ((value += mod - a.value) >= mod) value -= mod;
		return *this;
	}
	constexpr Mint &operator*=(const Mint &a) {
		value = value * a.value % mod;
		return *this;
	}

	constexpr Mint &operator/=(const Mint &a) {
		return *this *= inv(a);
	}
	constexpr Mint operator+(const Mint &a) const {
		return Mint(*this) += a;
	}
	constexpr Mint operator-(const Mint &a) const {
		return Mint(*this) -= a;
	}
	constexpr Mint operator*(const Mint &a) const {
		return Mint(*this) *= a;
	}
	constexpr Mint operator/(const Mint &a) const {
		return Mint(*this) /= a;
	}
};
template <int mod, bool isPrime>
std::ostream &operator<<(std::ostream &os, const Mint<mod, isPrime> &m) {
	os << m.get();
	return os;
}
template <int mod, bool isPrime>
std::istream &operator>>(std::istream &is, Mint<mod, isPrime> &m) {
	is >> m.get();
	return is;
}

template <int mod> constexpr Mint<mod, true> inv(const Mint<mod, true> &m) {
	long long a = m.get(), b = mod, u = 1, v = 0;
	while (b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	return Mint<mod, true>(u);
}

template <int mod, bool isPrime>
constexpr Mint<mod, isPrime> operator+(long long lhs,
                                       const Mint<mod, isPrime> &a) {
	return Mint<mod, isPrime>(lhs + a.get());
}

template <int mod, bool isPrime>
constexpr Mint<mod, isPrime> operator-(long long lhs,
                                       const Mint<mod, isPrime> &a) {
	return Mint<mod, isPrime>(lhs - a.get());
}

template <int mod, bool isPrime>
constexpr Mint<mod, isPrime> operator*(long long lhs,
                                       const Mint<mod, isPrime> &a) {
	return Mint<mod, isPrime>(lhs % mod * a.get());
}

constexpr int default_mod = 998244353;
using mint = Mint<default_mod, true>;

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	vector<mint> dp(m + 1);
	vector<mint> fact(3 * m + n + 1), rfact(3 * m + n + 1);
	fact[0] = 1;
	REP(i, fact.size() - 1) fact[i + 1] = fact[i] * (i + 1);
	rfact.back() = inv(fact.back());
	RREP(i, rfact.size() - 1) rfact[i] = rfact[i + 1] * (i + 1);

	auto comb = [&](int a, int b) { return fact[a] * rfact[b] * rfact[a - b]; };
	auto solve = [&](int n, int m) {
		mint ans = 0;
		for (int i = 0; i <= min(n, m); ++i) {
			if ((m - i) % 2 == 1) continue;
			mint tmp = 0;
			tmp += comb((3 * m - i) / 2 + n - 1, n - 1);
			tmp -= comb((m - i) / 2 + n - 1, n - 1) * i;
			if (i != m) tmp -= comb((m - 2 - i) / 2 + n - 1, n - 1) * (n - i);
			ans += tmp * comb(n, i);
		}
		return ans;
	};
	cout << solve(n, m) << endl;
}

Measured memory_bytes: 43264