#include <bits/stdc++.h>
#define Inf 0x3f3f3f3f
#define rg register
using std::cin;
using std::cout;
const int Maxn = 2e7 + 5, Mod = 998244353;
typedef long long ll;
typedef ll arr[Maxn];
ll Add(ll x, ll y) { return (x += y) >= Mod ? x - Mod : (x < 0 ? x + Mod : x); }
ll min(ll x, ll y) { return x < y ? x : y; }
ll max(ll x, ll y) { return x > y ? x : y; }
inline ll read()
{
	rg ll res = 0, sign = 1;
	rg char ch = getchar();
	while (!isdigit(ch))
	{
		if (ch == '-')
			sign = -1;
		ch = getchar();
	}
	do
	{
		res = (res << 3) + (res << 1) + (ch ^ 48);
		ch = getchar();
	} while (isdigit(ch));
	return res * sign;
}
int n, m;
arr fac, inv, invfac;
ll ans;
ll qp(ll x, int y)
{
	ll res = 1;
	while (y)
	{
		if (y & 1)
			res = res * x % Mod;
		x = x * x % Mod;
		res >>= 1;
	}
	return res;
}
ll C(int x, int y) { return fac[x] * invfac[y] % Mod * invfac[x - y] % Mod; }
int main()
{
	fac[0] = inv[1] = invfac[0] = 1;
	for (rg int i = 1; i <= 20000000; i++)
	{
		fac[i] = fac[i - 1] * i % Mod;
		if (i > 1)
			inv[i] = (Mod - Mod / i) * inv[Mod % i] % Mod;
		invfac[i] = invfac[i - 1] * inv[i] % Mod;
	}
	rg int tmp;
	cin >> n >> m;
	ans = 1;
	for (rg int i = 1; i < n; i++)
		ans = ans * (3 * m + i) % Mod;
	ans = ans * invfac[n - 1] % Mod;
	ans = Add(ans, -(n * C(m - 1 + n - 1, n - 1) % Mod));
	if (n > m)
	{
		tmp = min(3 * m, n);
		for (rg int i = m + 2; i <= tmp; i += 2)
			ans = Add(ans, -(C(n, i) * C((3 * m - i) / 2 + n - 1, n - 1) % Mod));
	}
	cout << ans << '\n';
	return 0;
}
    #include<bits/stdc++.h>
    using namespace std;
    
    //                                 (POLICY BASED DS)
    // #include <ext/pb_ds/assoc_container.hpp>
    // #include <ext/pb_ds/tree_policy.hpp>
    // using namespace __gnu_pbds;
    // template<typename T>
    // using ordered_set=tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
    // template<typename T>
    // using ordered_multiset=tree<T,null_type,less_equal<T>,rb_tree_tag,tree_order_statistics_node_update>;
    //                      ( find_by_order( )  ,  order_of_key( ) )
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    typedef vector<int> vi;
    typedef vector<long long> vll;
    typedef pair<ll,ll> pll;
     
    const ll mod = 1e9 + 7;
    const ld PI = 3.1415926535897932384626;
    const ld eps = 1e-9;                            
     
    #define boost ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
    #define sidha(i,a,b) for(ll i=(ll)(a);i<(ll)(b);++i)
    #define ulta(i,a,b) for(ll i=(ll)(a);i>=(ll)(b);--i)
    #define stl(container,itr) \
        for(auto itr = container.begin(); itr != container.end(); itr++)
    #define sab(v) v.begin(), v.end()
    #define rall(v) v.rbegin(), v.rend()            
    #define test ll t;cin>>t;while(t--)
    #define sz size()
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define LOG2(X) (63ll - __builtin_clzll(X))
    #define endl '\n'
    #define modinv(x) power(x, mod-2)
    #define ncr(n,r) ( n >= r ? ((((fact[n]*modinv(fact[r]))%mod)*modinv(fact[n-r]))%mod) : (ll)0)
    #define MAX 100005
     
    ll power(ll x, ll y) { 
        ll ans=1;
        x=x%mod;
        while(y>0) { 
            if (y&1) 
                ans=(ans*x)%mod; 
            y=y>>1;
            x=(x*x)%mod; 
        } 
        return ans; 
    }
    
    // vector<ll> adj[MAX];
    // ll visit[MAX];
    // void dfs(ll node){
    //     visit[node]=1;
    //     for(auto i : adj[node]){
    //         if(!visit[i]) dfs(i);
    //     }
    // }
    
    // ll spf[MAX];
    // void sieve(){
    //     sidha(i,1,MAX)  spf[i]=i;
    //     for(ll i=4;i<MAX;i+=2)  spf[i]=2;
    //     for(ll i=3;i*i<=MAX;i++){
    //         if(spf[i]==i){
    //             for(ll j=i*i;j<MAX;j+=i){
    //                 if(spf[j]==j)   spf[j]=i;
    //             }
    //         }
    //     }
    // }

    int main()
    {
        boost;
        ll n,count=0,ans=0;
        cin>>n;
        ll arr[n],suff[n];
        sidha(i,0,n)    cin>>arr[i];
        ulta(i,n-1,0){
            suff[i]=count;
            count=((count+arr[i])%mod);
        }
        sidha(i,0,n){
            ans=((ans+((arr[i]*suff[i])%mod))%mod);
        }
        cout<<ans;
        return 0;
    }
    