#include<bits/stdc++.h>
using namespace std;

using Int = long long;
using ll = long long;

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b)a=b;};

template<typename T> void drop(T x){cout<<x<<endl;exit(0);};

template<typename T, T MOD = 1000000007>
struct Mint{
  static constexpr T mod = MOD;
  T v;
  Mint():v(0){}
  Mint(signed v):v(v){}
  Mint(long long t){v=t%MOD; if(v<0) v += MOD;}

  Mint pow(long long k){
    Mint res(1), tmp(v);
    while(k){
      if(k & 1) res *= tmp;
      tmp *= tmp;
      k>>=1;
    }
    return res;
  }

  static Mint add_identity(){return Mint(0);}
  static Mint mul_identity(){return Mint(1);}

  Mint inv(){return pow(MOD - 2);}

  Mint& operator +=(Mint a){v+=a.v; if(v>=MOD) v-= MOD; return *this;}
  Mint& operator -=(Mint a){v+=MOD-a.v; if(v>=MOD) v-= MOD; return *this;}
  Mint& operator *=(Mint a){v = 1LL * v * a.v%MOD; return *this;}
  Mint& operator /=(Mint a){return (*this) *= a.inv();}

  Mint operator+(Mint a)const{return Mint(v)+=a;}
  Mint operator-(Mint a)const{return Mint(v)-=a;}
  Mint operator*(Mint a)const{return Mint(v)*=a;}
  Mint operator/(Mint a)const{return Mint(v)/=a;}

  Mint operator-()const{return v?Mint(MOD-v):Mint(v);}

  bool operator==(const Mint a)const{return v==a.v;}
  bool operator!=(const Mint a)const{return v!=a.v;}
  bool operator<(const Mint a)const{return v<a.v;}

  static Mint comb(long long n, int k){
    Mint num(1), dom(1);
    for(int i=0;i<k;i++){
      num *= Mint(n - i);
      dom *= Mint(i + 1);
    }
    return num / dom;
  }
};

template<typename T, T MOD> constexpr T Mint<T, MOD>::mod;
template<typename T, T MOD>
ostream& operator<<(ostream &os, Mint<T, MOD> m){os<<m.v;return os;}

template<typename M>
class Enumeration{
private:
  static vector<M> fact, finv, invs;
public:
  static void init(int n){
    n = min<decltype(M::mod)>(n, M::mod-1);
    int m = fact.size();
    if(n < m) return;

    fact.resize(n + 1, 1);
    finv.resize(n + 1, 1);
    invs.resize(n + 1, 1);

    if(m == 0) m = 1;
    for(int i=m;i<=n;i++) fact[i] = fact[i-1] * M(i);
    finv[n] = M(1) / fact[n];
    for(int i=n;i>=m;i--) finv[i-1] = finv[i] * M(i);
    for(int i=m;i<=n;i++) invs[i] = finv[i] * fact[i-1];
  }

  static M LagrangePolynomial(vector<M> &y, M t){
    int n = y.size() - 1;
    if(t.v <= n) return y[t.v];
    init(n + 1);
    vector<M> dp(n + 1, 1), pd(n + 1, 1);
    for(int i=0;i<n;i++) dp[i+1] = dp[i] * (t - M(i));
    for(int i=n;i>0;i--) pd[i-1] = pd[i] * (t - M(i));
    M res{0};
    for(int i=0;i<=n;i++){
      M tmp = y[i] * dp[i] * pd[i] * finv[i] * finv[n-i];
      if((n - i) & 1) res -= tmp;
      else res += tmp;
    }
    return res;
  }
};

template<typename M>
vector<M> Enumeration<M>::fact = vector<M>();
template<typename M>
vector<M> Enumeration<M>:: finv = vector<M>();
template<typename M>
vector<M> Enumeration<M>:: invs = vector<M>();

using MI = Mint<int, 998244353>;

//[0,mx]
MI cul(ll mx,ll s,ll k){
  mx++;
  using EM=Enumeration<MI>;
  MI ret=0;
  ll i=1;
  EM enm;
  enm.init(k);
  vector<MI> A(k+1);
  vector<MI> B(k+1);
  for(int i=0;i<=k;i++){
    A[i]=MI(s-2*i).pow(k)-MI(s-2*i-1).pow(k);
  }
  while(mx>0){
    if(mx&i){
      ret+=enm.LagrangePolynomial(A,mx^i);
      mx^=i;
    }
    for(int j=0;j<=k;j++){
      B[j]=enm.LagrangePolynomial(A,j+i);
    }
    for(int j=0;j<=k;j++){
      A[j]+=B[j];
    }
    i<<=1;
  }
  return ret;
}

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  ll n,s;
  cin>>n>>s;

  using M = Mint<int, 998244353>;
  M ans{0};

  // a[0] > a[n-1]
  ans+=M(s*(s+1)/2)*M(s+1).pow(n-2);

  // a[0] = a[n-1], min(a) is odd
  /*
  // i = min(a)
  for(int i=1;i<=s;i+=2){
    ans+=M((s+1)-i).pow(n-1)-M((s+1)-(i+1)).pow(n-1);
  }
  */
  ans+=cul((s-1)/2,s,n-1);

  cout<<ans<<endl;
  return 0;
}



Measured memory_bytes: 3240