#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline LL read()
{
	LL f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int stack[20];
template<typename T>inline void write(T x)
{
	if(x<0){putchar('-');x=-x;}
    if(!x){putchar('0');return;}
    int top=0;
    while(x)stack[++top]=x%10,x/=10;
    while(top)putchar(stack[top--]+'0');
}
template<typename T>inline void pr1(T x){write(x);putchar(' ');}
template<typename T>inline void pr2(T x){write(x);putchar('\n');}
const int mod=998244353;
const int MAXN=3000005;
int pre[MAXN],inv[MAXN];
int C(int n,int m)
{
	if(n<m)return 0;
	return 1LL*pre[n]*inv[m]%mod*inv[n-m]%mod;
}
int n,m;
void ad(int &x,int y){x+=y;if(x>=mod)x-=mod;}
void dl(int &x,int y){x-=y;if(x<0)x+=mod;}
int pow_mod(int a,int b)
{
	int ret=1;
	while(b)
	{
		if(b&1)ret=1LL*ret*a%mod;
		a=1LL*a*a%mod;b>>=1;
	}
	return ret;
}
int main()
{
	pre[0]=1;for(int i=1;i<MAXN;i++)pre[i]=1LL*pre[i-1]*i%mod;
	inv[MAXN-1]=pow_mod(pre[MAXN-1],mod-2);
	for(int i=MAXN-2;i>=0;i--)inv[i]=1LL*inv[i+1]*(i+1)%mod;
	n=read();m=read();
	int ans=0;
	for(int i=0;i<=m;i++)
		if(!((3*m-i)&1))
			ad(ans,1LL*C(n,i)*C(((3*m-i)>>1)+n-1,n-1)%mod);
//	dl(ans,1LL*n*C(m-2+n-1,n-1)%mod);
	dl(ans,1LL*n*C(m-1+n-1,n-1)%mod);
	pr2(ans);
	return 0;
}



#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SZ(x) ((int)x.size())
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define FORD(i,a,b) for (int i=a;i>=b;--i)
using namespace std;
typedef long long LL;
typedef pair<LL,int> pa;
typedef vector<int> vec;
void getint(int &v){
    char ch,fu=0;
    for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
    if(ch=='-') fu=1, ch=getchar();
    for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
    if(fu) v=-v;
}
const LL INF=1e18;
int n,D,a[500010];
bool u[500010];
LL ans;
struct node{
	pa v[2][2]; //[in MST now];[use + -]
	pa t;
	node(){
		v[0][0]=v[0][1]=v[1][0]=v[1][1]=mp(INF,0);
		t=mp(INF,0);
	}
}T[800010];
void pushup(int rt){
	T[rt].t=min(T[rt<<1].t,T[rt<<1|1].t);
	T[rt].t=min(T[rt].t,mp(T[rt<<1].v[0][0].fi+T[rt<<1|1].v[1][1].fi,T[rt<<1].v[0][0].se));
	T[rt].t=min(T[rt].t,mp(T[rt<<1].v[1][0].fi+T[rt<<1|1].v[0][1].fi,T[rt<<1|1].v[0][1].se));
	T[rt].v[0][0]=min(T[rt<<1].v[0][0],T[rt<<1|1].v[0][0]);
	T[rt].v[0][1]=min(T[rt<<1].v[0][1],T[rt<<1|1].v[0][1]);
	T[rt].v[1][0]=min(T[rt<<1].v[1][0],T[rt<<1|1].v[1][0]);
	T[rt].v[1][1]=min(T[rt<<1].v[1][1],T[rt<<1|1].v[1][1]);
}
void build(int l,int r,int rt){
	if (l==r){
		T[rt].v[u[l]][0]=mp(a[l]-1ll*l*D,l);
		T[rt].v[u[l]][1]=mp(a[l]+1ll*l*D,l);
		T[rt].v[u[l]^1][0]=mp(INF,0);
		T[rt].v[u[l]^1][1]=mp(INF,0);
		return;
	}
	int m=l+r>>1;
	build(l,m,rt<<1);
	build(m+1,r,rt<<1|1);
	pushup(rt);
}
void upd(int l,int r,int rt,int x){
	if (l==r){
		T[rt].v[u[l]][0]=mp(a[l]-1ll*l*D,l);
		T[rt].v[u[l]][1]=mp(a[l]+1ll*l*D,l);
		T[rt].v[u[l]^1][0]=mp(INF,0);
		T[rt].v[u[l]^1][1]=mp(INF,0);
		return;
	}
	int m=l+r>>1;
	if (x<=m) upd(l,m,rt<<1,x);
	else upd(m+1,r,rt<<1|1,x);
	pushup(rt);
}
void prim(){
	build(1,n,1);
	u[1]=1;
	upd(1,n,1,1);
	FOR(rp,2,n){
		pa tmp=T[1].t;
		ans+=tmp.fi;
		u[tmp.se]=1;
		upd(1,n,1,tmp.se);
	}
}
int main(){
	cin>>n>>D;
	FOR(i,1,n) getint(a[i]);
	prim();
	printf("%lld\n",ans);
	return 0;
}
