Problem:
J: 左崎・右男
問題文
左崎さんと右男さんは、長さ $N$ の数列 $a_1, a_2, \dots ,a_n$ を使ったゲームで遊ぶのが好きです。
このゲームでは左崎さんと右男さんで交互に以下の操作を行います。
左崎さんの手番では $1 \leq k \leq n$ を指定し、$a_1, a_2, \dots ,a_k$ の値をそれぞれ $1$ ずつ減らす。
右男さんの手番では $1 \leq k \leq n$ を指定し、$a_k, a_{k+1}, \dots ,a_n$ の値をそれぞれ $1$ ずつ減らす。
手番終了時に数列の中に負の数が存在していた場合、その操作をした人は負けます。負けなかった方は勝ちます。最初に操作をするのは左崎さんです。
左崎さんはこのゲームをプレイするために、$0, 1, \dots, S$ からなる長さ $N$ の数列を全種類（$(S+1)^N$ 通り）買ってきました。左崎さんと右男さんがこれらの数列を使って $1$ 回ずつゲームをしました。左崎さんが勝った回数を $998244353$ で割ったあまりを求めてください。ただし、両者ともそれぞれが勝つために最適な操作をしたとします。
制約
入力は全て整数
$2 \leq N \leq 1000$
$1 \leq S \leq 10^9$
入力
入力は以下の形式で標準入力から与えられます。
$N$ $S$
出力
全ての数列を使って $1$ 回ずつゲームをしたときに、左崎さんが勝った回数を $998244353$ で割ったあまりを出力してください。
入出力例
入力例1
2 1
出力例1
2
左崎さんが買ってきた数列は (0, 0), (0, 1), (1, 0), (1, 1) の  $4$ つです。
(0, 0), (0, 1) を使ったゲームでは、左崎さんは最初の手番でどの $k$ を選んでも負けます。
(1, 0) を使ったゲームでは、左崎さんは $k = 1$ を選べば、数列が (0, 0) となり、勝てます。
(1, 1) を使ったゲームでは、左崎さんは $k = 2$ を選べば、数列が (0, 0) となり、勝てます。
入力例2
3 2
出力例2
12
左崎さんが勝つ数列は以下の $12$ 個です。
(1,0,0)
(1,1,0)
(1,1,1)
(1,2,0)
(1,2,1)
(2,0,0)
(2,0,1)
(2,1,0)
(2,1,1)
(2,1,2)
(2,2,0)
(2,2,1)
入力例3
1000 1000000000
出力例3
972070366

Submitted solutions:

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

template<int MOD>
struct mod_int {
	static const int Mod = MOD;
	unsigned x;
	mod_int() : x(0) { }
	mod_int(int sig) { int sigt = sig % MOD; if (sigt < 0) sigt += MOD; x = sigt; }
	mod_int(long long sig) { int sigt = sig % MOD; if (sigt < 0) sigt += MOD; x = sigt; }
	int get() const { return (int)x; }

	mod_int &operator+=(mod_int that) { if ((x += that.x) >= MOD) x -= MOD; return *this; }
	mod_int &operator-=(mod_int that) { if ((x += MOD - that.x) >= MOD) x -= MOD; return *this; }
	mod_int &operator*=(mod_int that) { x = (unsigned long long)x * that.x % MOD; return *this; }
	mod_int &operator/=(mod_int that) { return *this *= that.inverse(); }

	mod_int operator+(mod_int that) const { return mod_int(*this) += that; }
	mod_int operator-(mod_int that) const { return mod_int(*this) -= that; }
	mod_int operator*(mod_int that) const { return mod_int(*this) *= that; }
	mod_int operator/(mod_int that) const { return mod_int(*this) /= that; }

	mod_int inverse() const {
		long long a = x, b = MOD, u = 1, v = 0;
		while (b) {
			long long t = a / b;
			a -= t * b; swap(a, b);
			u -= t * v; swap(u, v);
		}
		return mod_int(u);
	}
};

template<int MOD>
istream& operator >> (istream& is, mod_int<MOD>& val) {
	long long x;
	is >> x; val = x;
	return is;
}

template<int MOD>
ostream& operator << (ostream& os, const mod_int<MOD>& val) {
	os << val.get();
	return os;
}

template <int MD>
mod_int<MD> lagrange_polynomial(const vector<mod_int<MD>>& ys, long long n) {
	int k = ys.size() - 1;
	if (n <= k) return ys[n];
	n %= MD;
	mod_int<MD> qi = 1, qt = n;
	for (int i = 1; i <= k; i++) {
		qi *= MD - i;
		qt *= n - i;
	}
	mod_int<MD> res = ys[0] / (qi * n);
	for (int i = 1; i <= k; i++) {
		(qi *= i) /= MD - k + (i - 1);
		res += ys[i] / (qi * (n - i));
	}
	return res * qt;
}

const int mod = 998244353;

using mint = mod_int<mod>;

mint pow(mint a, int n) {
	mint res = 1;
	while (n) {
		if (n & 1) res *= a;
		n >>= 1;
		if (n) a *= a;
	}
	return res;
}

mint calc(int N, int S) {
	mint res = 0;
	for (int i = 0; i < S; i++) {
		res += mint(S - i) * pow(mint(S + 1), N - 2);
	}
	if (N == 2) {
		res += (S + 1) / 2;
		return res;
	}
	for (int k = 0; k <= S; k++) {
		mint v = pow(mint(S + 1 - k), N - 2) - pow(mint(S - k), N - 2);
		res += v * ((k + 1) / 2);
		if (k & 1) res += v * (S - k);
	}
	return res;
}

int main()
{
	int N, S;
	cin >> N >> S;
	int b = S & 1;
	vector<mint> vs(N + 10);
	for (int i = 0; i < N + 10; i++) {
		vs[i] = calc(N, i * 2 + b);
	}
	cout << lagrange_polynomial(vs, S / 2) << endl;
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3448
final_rank: 4

code_snippet: #include <iostream>

#define ll long long
#define mod 998244353

using namespace std;

ll bin_pow(ll a, ll pw) {
    if (!pw) return 1;
    ll x = bin_pow(a, pw / 2);
    x = (x * x) % mod;
    if (pw & 1) {
        x = (x * a) % mod;
    }
    return x;
}

ll n, s;
ll val[1005];

ll calc(ll x) {
    ll ret = 0;
    for (int i = 1; i <= n + 1; i++) {
        ll tmp = val[i];
        for (int j = 1; j <= n + 1; j++) {
            if (i == j) continue;
            tmp *= (x - j + mod) % mod, tmp %= mod;
            tmp *= bin_pow((i - j + mod) % mod, mod - 2), tmp %= mod;
        }
        ret += tmp, ret %= mod;
    }
    return ret;
}

signed main() {
    cin >> n >> s;

    ll sum = 0;
    for (int i = 1; i <= n + 1; i++) {
        sum += bin_pow(i, n - 1), sum %= mod;
        val[i] = sum;
    }

    ll ans = (s + 1) * s / 2 % mod;
    ans *= bin_pow(s + 1, n - 2), ans %= mod;

    ll tmp = bin_pow(2, n - 1) * calc(s / 2) % mod;
    tmp = calc(s) - 2 * tmp % mod + mod, tmp %= mod;
    if (s % 2 == 0) tmp *= mod - 1, tmp %= mod;

    ans += tmp, ans %= mod;
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 3452
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t) - 1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T>
bool chmax(T& a, const T& b) {
    return a < b ? (a = b, 1) : 0;
}
template <typename T>
bool chmin(T& a, const T& b) {
    return a > b ? (a = b, 1) : 0;
}

template <int m>
class Modint {
    using mint = Modint;
    static_assert(m > 0, "Modulus must be positive");

   public:
    static constexpr int mod() { return m; }

    constexpr Modint(long long y = 0) : x(y >= 0 ? y % m : (y % m + m) % m) {}

    constexpr int val() const { return x; }

    constexpr mint& operator+=(const mint& r) {
        if ((x += r.x) >= m) x -= m;
        return *this;
    }
    constexpr mint& operator-=(const mint& r) {
        if ((x += m - r.x) >= m) x -= m;
        return *this;
    }
    constexpr mint& operator*=(const mint& r) {
        x = static_cast<int>(1LL * x * r.x % m);
        return *this;
    }
    constexpr mint& operator/=(const mint& r) { return *this *= r.inv(); }

    constexpr bool operator==(const mint& r) const { return x == r.x; }

    constexpr mint operator+() const { return *this; }
    constexpr mint operator-() const { return mint(-x); }

    constexpr friend mint operator+(const mint& l, const mint& r) {
        return mint(l) += r;
    }
    constexpr friend mint operator-(const mint& l, const mint& r) {
        return mint(l) -= r;
    }
    constexpr friend mint operator*(const mint& l, const mint& r) {
        return mint(l) *= r;
    }
    constexpr friend mint operator/(const mint& l, const mint& r) {
        return mint(l) /= r;
    }

    constexpr mint inv() const {
        int a = x, b = m, u = 1, v = 0;
        while (b > 0) {
            int t = a / b;
            std::swap(a -= t * b, b);
            std::swap(u -= t * v, v);
        }
        return mint(u);
    }

    constexpr mint pow(long long n) const {
        mint ret(1), mul(x);
        while (n > 0) {
            if (n & 1) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }

    friend std::ostream& operator<<(std::ostream& os, const mint& r) {
        return os << r.x;
    }

    friend std::istream& operator>>(std::istream& is, mint& r) {
        long long t;
        is >> t;
        r = mint(t);
        return is;
    }

   private:
    int x;
};


template <typename mint>
class Combination {
   public:
    Combination() = default;
    Combination(int n) : fact_(n + 1), fact_inv_(n + 1) {
        fact_[0] = 1;
        for (int i = 1; i <= n; ++i) fact_[i] = fact_[i - 1] * i;
        fact_inv_[n]=fact_[n].inv();
        for (int i = n; i > 0; --i) fact_inv_[i - 1] = fact_inv_[i] * i;
    }

    mint perm(int n, int k) const {
        if (k < 0 || n < k) return 0;
        return fact_[n] * fact_inv_[n - k];
    }

    mint comb(int n, int k) const {
        if (k < 0 || n < k) return 0;
        return fact_[n] * fact_inv_[k] * fact_inv_[n - k];
    }

    mint fact(int n) const { return fact_[n]; }
    mint fact_inv(int n) const { return fact_inv_[n]; }

   private:
    std::vector<mint> fact_, fact_inv_;
};

using mint = Modint<998244353>;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    ll S;
    cin >> N >> S;
    Combination<mint> comb(N);

    vector<map<int, mint>> memo(N+1);

    auto calc = [&](auto& calc, int n, ll s) -> mint {
        if (n == 0) return s % 2 == 0 ? 1 : 0;
        if (s == 0) return 0;
        if (s == 1) return -1;
        if (memo[n].count(s)) return memo[n][s];

        int m = s / 2;

        mint ans = 0;
        mint p = 1;
        rep(l,0,n+1) {
            ans += comb.comb(n,l) * p * calc(calc, n-l, s-m);
            p *= m;
        }
        if (m % 2 == 1) ans = -ans;
        ans += calc(calc, n, m-1);
        return memo[n][s] = ans;
    };

    mint ans = mint(S*(S+1)/2) * mint(S+1).pow(N-2);
    if (S % 2 == 1) {
        ans += -calc(calc, N-1, S);
    } else {
        ans += calc(calc, N-1, S);
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 1320
memory_kb: 7920
final_rank: 20

code_snippet: #if 1
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <array>
#include <deque>
#include <algorithm>
#include <utility>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <numeric>
#include <assert.h>
#include <bitset>
#include <list>
#include <cmath>

auto& in = std::cin;
auto& out = std::cout;
#define all_range(C) std::begin(C), std::end(C)
const double PI = 3.141592653589793238462643383279502884197169399375105820974944;

template<typename Arithmetic, typename Integral>
std::enable_if_t< std::is_unsigned<Integral>::value, Arithmetic>
ipow(Arithmetic bace, Integral n)
{
	//繰り返し二条法
	auto res = (Arithmetic)(1);
	while (n > 0) {
		if (n & 1) res *= bace;
		bace *= bace;
		n >>= 1;
	}
	return res;
}
constexpr bool is_prime(uint32_t N)
{
	if (N <= 1) {
		return false;
	}
	for (size_t i = 2; i * i <= N; ++i)
	{
		if (N % i == 0) {
			return false;
		}
	}
	return true;
}
template <uint64_t MOD> class mint_base;
//mint_base_base型用の累乗関数
template <uint64_t MOD> constexpr mint_base<MOD> m_pow(mint_base<MOD> x, uint64_t n)noexcept;
//mod計算を自動で行う整数テンプレートクラス
template <uint64_t MOD_ = 998244353>
class mint_base
{
public:
	static constexpr auto MOD = MOD_;
	static_assert(!(MOD <= 2), "MOD cannot be below 2.");
	static_assert(MOD <= (0xFFFFFFFFFFFFFFFF / 2), "MOD is too big");//加算してオーバーフローしない
	static_assert(MOD <= 0xFFFFFFFF, "MOD is too big");//乗算してオーバーフローしない
	constexpr mint_base<MOD> operator+(const mint_base<MOD>& other)const noexcept
	{
		auto v = *this;
		return v += other;
	}
	constexpr mint_base<MOD> operator-(const mint_base<MOD>& other)const noexcept
	{
		auto v = *this;
		return v -= other;
	}
	constexpr mint_base<MOD> operator*(const mint_base<MOD>& other)const noexcept
	{
		auto v = *this;
		return v *= other;
	}
	constexpr auto operator/(const mint_base<MOD>& other)const noexcept
	{
		auto v = *this;
		return v /= other;
	}
	constexpr mint_base<MOD>& operator+=(const mint_base<MOD>& other) noexcept
	{
		a += other.a;
		if (MOD <= a) { a -= MOD; };
		return *this;
	}
	constexpr mint_base<MOD>& operator-=(const mint_base<MOD>& other) noexcept
	{
		if (a >= other.a) {
			a -= other.a;
		}
		else {
			a = (a + MOD) - other.a;
		}
		return *this;
	}
	constexpr mint_base<MOD>& operator*=(const mint_base<MOD>& other) noexcept
	{
#if 1
		a *= other.a;
		a %= MOD;
#else
		//MOD <= (MAXUINT64 / 2)条件下
		uint64_t b = other.a, v = 0;
		while (b > 0) {
			if (b & 1) {
				v += a;
				if (v >= MOD)v -= MOD;
			}
			a += a;
			if (MOD <= a)a -= MOD;
			b >>= 1;
		}
		a = v;
#endif
		return *this;
	}
	constexpr mint_base<MOD>& operator/=(const mint_base<MOD>& other) noexcept
	{
		return *this *= ~other;
	}
	constexpr mint_base<MOD> operator+()const noexcept { return *this; }
	constexpr mint_base<MOD> operator-()const noexcept
	{
		return{ MOD - a, mod_value_tag{} };
	}
	constexpr mint_base<MOD>& operator++() noexcept
	{
		if (MOD <= ++a) { a = 0; };
		return *this;
	}
	constexpr mint_base<MOD>& operator--() noexcept
	{
		if (a <= 0) { a = MOD; };
		--a;
		return *this;
	}
	constexpr mint_base<MOD> operator++(int) noexcept
	{
		auto tmp = *this;
		++* this;
		return tmp;
	}
	constexpr mint_base<MOD> operator--(int) noexcept
	{
		auto tmp = *this;
		--* this;
		return tmp;
	}
	constexpr mint_base<MOD> operator~()const noexcept
	{
		return ipow(*this, e_phi - 1);
	}
	constexpr mint_base<MOD>& operator=(const mint_base<MOD>& other) noexcept
	{
		a = other.a;
		return *this;
	}
	constexpr explicit operator uint64_t()const noexcept
	{
		return a;
	}
	constexpr explicit operator unsigned()const noexcept
	{
		return (unsigned)a;
	}
	static constexpr uint64_t getmod() noexcept
	{
		return MOD;
	}
	constexpr mint_base(uint64_t a_) noexcept :a(a_% MOD) {}
	constexpr mint_base()noexcept : a(0) {}
	struct mod_value_tag {};
	constexpr mint_base(uint64_t a_, mod_value_tag) :a(a_) {}
private:
	static constexpr uint64_t get_e_phi()noexcept {
		//オイラー値の導出
		uint64_t temp = MOD;
		uint64_t m_ = MOD;
		for (uint64_t i = 2; i * i <= m_; ++i)
		{
			if (m_ % i == 0)
			{
				temp = temp / i * (i - 1);
				for (; m_ % i == 0; m_ /= i);
			}
		}
		if (m_ != 1)temp = temp / m_ * (m_ - 1);
		return temp;
	}
	static constexpr uint64_t e_phi = get_e_phi();//オイラー値
	uint64_t a;
};
//mint_base型用の累乗関数
template<uint64_t MOD>constexpr mint_base<MOD> m_pow(mint_base<MOD> x, uint64_t n)noexcept
{
	mint_base<MOD> res = 1;
	while (n > 0)
	{
		if (n & 1)res *= x;
		x *= x;
		n >>= 1;
	}
	return res;
}
//mint_baseの階乗計算
//O(x)時間が必要のため、fact_set関数を推奨する。
template<uint64_t MOD>constexpr mint_base<MOD> fact(mint_base<MOD> x)noexcept
{
	mint_base<MOD> res(1);
	for (uint64_t i = 1; i <= (uint64_t)x; ++i)
	{
		res *= i;
	}
	return res;
}
//mint_baseの階乗計算
//0からxまでの階乗を返す
//O(x)時間が必要
template<uint64_t MOD>std::vector<mint_base<MOD>> fact_set(mint_base<MOD> x = mint_base<MOD>(-1))
{
	mint_base<MOD> res(1);
	std::vector<mint_base<MOD>> set((uint64_t)(x)+1);
	set[0] = 1;
	for (uint64_t i = 1; i <= (uint64_t)x; ++i)
	{
		res *= i;
		set[i] = res;
	}
	return res;
}
//mint_base型のstreamへの出力
template<uint64_t MOD> std::ostream& operator<<(std::ostream& os, mint_base<MOD> i)
{
	os << (uint64_t)i;
	return os;
}
//mint_base型のstreamからの入力
template<uint64_t MOD> std::istream& operator >> (std::istream& is, mint_base<MOD>& i)
{
	uint64_t tmp;
	is >> tmp;
	i = tmp;
	return is;
}
typedef mint_base<> mint;
namespace mint_literal {
	constexpr mint operator""_mi(unsigned long long x)noexcept {
		return mint(x);
	}
}
using namespace mint_literal;
//mint_baseの階乗計算
//0からxまでの階乗を返す
//O(N)
template<int32_t X, uint64_t MOD = mint::MOD>
/*constexpr*/ std::array<mint_base<MOD>, X + 1> fact_set_c()
{
	mint_base<MOD> res(1);
	std::array<mint_base<MOD>, X + 1> set;
	set[0] = 1;
	for (int32_t i = 1; i <= X; ++i)
	{
		res *= i;
		set[i] = res;
	}
	return set;
}
template<typename RET = mint, typename Integral>
RET combination(Integral all, Integral get)
{
	assert(all >= get);
	get = std::min(all - get, get);
#if 1
	//時間計算量O(1)+初期化O(NlogMOD)
	static const auto fact_v = fact_set_c<4000 + 1>();
	static const auto fact_div_v = [&]() {
		auto tmp = fact_v;
		for (auto& i : tmp) { i = ~i; }
		return tmp;
	}();
	//return fact_v[all] / (fact_v[get] * fact_v[all - get]);
	return fact_v[all] * fact_div_v[get] * fact_div_v[all - get];
#elif 0
	//時間計算量O(1)
	//空間計算量、初期化時間計算量O(N^2)
	constexpr int32_t ALL_MAX = 要素数;// 10'000;
	static std::vector<RET> DP_comb[ALL_MAX + 1];
	if (!DP_comb[all].empty())
	{
		return DP_comb[all][get];
	}

	if (DP_comb[0].empty())
	{
		DP_comb[0].resize(1);
		DP_comb[0][0] = (RET)1;
		DP_comb[1].resize(1);
		DP_comb[1][0] = (RET)1;
	}
	for (int32_t i = 2; i <= all; i++)
	{
		if (DP_comb[i].empty())
		{
			int32_t size = i / 2 + 1;
			DP_comb[i].resize(size);
			DP_comb[i][0] = (RET)1;
			for (int32_t j = 1; j < size - 1; j++)
			{
				DP_comb[i][j] = DP_comb[i - 1][j - 1] + DP_comb[i - 1][j];
			}
			DP_comb[i][size - 1] = DP_comb[i - 1][size - 2] + DP_comb[i - 1][(i & 1) ? (size - 1) : (size - 2)];
		}
	}
	return DP_comb[all][get];
#else
	//時間計算量O(get * logMOD)
	RET ret = (RET)1;
	for (Integral i = 1; i <= get; ++i)
	{
		ret *= all + 1 - i;
		ret /= i;
	}
	return ret;
#endif
}

int N;
mint S;
mint Sp1;
mint SN[2000];
mint Sp1N[2000];

mint Bernoulli[4000];

//sum i=[1,n] i^k
mint sum_i_p(mint n, int k) {
	//k固定の前提
	static bool used[2000];
	static mint dp[2000];

	auto& memo = dp[k];
	if (used[k]) { return memo; }
	used[k] = true;

	static mint nn[2000];
	nn[0] = 1_mi;
	for (size_t i = 0; i < 2000 - 1; i++) {
		nn[i + 1] = nn[i] * n;
	}

	mint res = 0;
	for (int j = 0; j <= k; j++)
	{
		res += combination(k + 1, j)* Bernoulli[j]* nn[k + 1 - j];
	}
	memo = res / mint(k + 1);


	//mint res2 = 0;
	//for (int i = 1; i <= static_cast<uint64_t>(n); i++)
	//{
	//	mint tmp = 1;
	//	for (int ii = 0; ii < k; ii++)
	//	{
	//		tmp *= i;
	//	}
	//	res2 += tmp;
	//}
	//if (static_cast<uint64_t>(memo) != static_cast<uint64_t>(res2)) {
	//	out << memo << std::endl;
	//	out << res2 << std::endl;
	//	assert(static_cast<uint64_t>(memo) == static_cast<uint64_t>(res2));
	//}

	return memo;
}
//sum i=[1,k] (a+b*i)^(N-1)
mint powsum(mint a, mint b, mint k) {

	static mint an[2000];
	an[0] = 1_mi;
	for (size_t i = 0; i < 2000 - 1; i++) {
		an[i + 1] = an[i] * a;
	}
	static mint bn[2000];
	bn[0] = 1_mi;
	for (size_t i = 0; i < 2000 - 1; i++) {
		bn[i + 1] = bn[i] * b;
	}

	mint res = 0;
	for (int p = 0; p <= N-1; p++) {
		//N-1乗を展開した各項
		auto tmp = combination(N - 1, p) * an[N - 1 - p] * bn[p];
		//sumは内側で取る
		tmp *= sum_i_p(k, p); // *= Σ(i ^ p)
		res += tmp;
	}
	return res;
}

int main()
{
    using std::endl;
    in.sync_with_stdio(false);
    out.sync_with_stdio(false);
    in.tie(nullptr);
    out.tie(nullptr);

	int64_t s_raw;
    in >> N >> s_raw;
	S = s_raw;
	Sp1 = S + 1;
	Sp1N[0] = 1_mi;
	for (size_t i = 0; i < 2000-1; i++) {
		Sp1N[i + 1] = Sp1N[i] * Sp1;
	}
	SN[0] = 1_mi;
	for (size_t i = 0; i < 2000 - 1; i++) {
		SN[i + 1] = SN[i] * S;
	}

	Bernoulli[0] = 1;
	//for (size_t i = 1; i <= 4000 - 1; i++) {
	//	for (size_t k = 0; k <= i - 1; k++) {
	//		Bernoulli[i] += combination(i + 1, k) * Bernoulli[k];
	//	}
	//	Bernoulli[i] /= mint(i + 1);
	//}
	for (size_t k = 1; k <= 4000 - 1; k++) {
		Bernoulli[k] = 0;
		for (size_t i = 0; i <= k - 1; i++) {
			Bernoulli[k] += mint(i%2==0?1:mint::MOD-1) * combination(k + 1, i) * Bernoulli[i];
		}
		Bernoulli[k] *= mint::MOD - 1;
		size_t i = k;
		Bernoulli[k] /= mint(i % 2 == 0 ? 1 : mint::MOD - 1);
		Bernoulli[k] /= combination(k + 1, i);
	}

	mint mustwin = Sp1N[N - 2] * (Sp1 * S - Sp1 * S / 2);
	//sum i=[1,k] (a+b*i)^(N-1)
	mint maywin = powsum(S + 2, mint::MOD-2, (s_raw+1) / 2) - powsum(S + 1, mint::MOD -2, (s_raw+1) / 2);

	//std::cerr << mustwin << endl;
	//std::cerr << maywin << endl;
	out << mustwin + maywin << endl;

    return 0;
}
#endif
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define _GLIBCXX_DEBUG
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=2167167167167167167;
const int INF=2100000000;
const ll mod=998244353;
#define rep(i,a) for (ll i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}

ll jyo(ll x,ll y,ll z){
  ll H=y; //ここから
       ll a=1,b=(x%z+z)%z,c=1;
       while(H>0){
         a*=2;
         if(H%a!=0){
           H-=a/2;
           c*=b;
           c%=z;
         }
        b*=b;
         b%=z;
      } //ここまで
 return c;
}



void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	ll N,S;
	cin>>N>>S;
	ll rev=(mod+1)/2;
	auto f=[&](ll s)->ll{
		ll ans=0;
		rep(i,s+1){
			ll K=s+1-i;
			if(i%2==0){
				ans+=(((rev*K*(K-1))%mod)*jyo(K,N-2,mod))%mod;
				ans-=(((rev*(K-1)*(K-2))%mod)*jyo(K-1,N-2,mod))%mod;
			}else{
				ans+=(((rev*K*(K+1))%mod)*jyo(K,N-2,mod))%mod;
				ans-=(((rev*K*(K-1))%mod)*jyo(K-1,N-2,mod))%mod;
			}
			ans=(ans%mod+mod)%mod;
		}
		return ans;
	};
	if(S<20000){
		cout<<f(S)<<"\n";
		return ;
	}
	ll start=S%2+2;
	vector<ll> p(N+2),L(N+2,1),R(N+2,1),ML(N+2,1),MR(N+2,1);
	rep(i,N+2) p[i]=f(start+i*2);
	rep(i,N+1) L[i+1]=(L[i]*(S-start-i*2))%mod;
	rep(i,N+1) R[N-i]=(R[N-i+1]*(S-start-(N+1-i)*2))%mod;
	rep(i,N+1){
		ML[i+1]=(ML[i]*(i+1)*2ll)%mod;
		MR[N-i]=(MR[N-i+1]*(i+1)*-2ll)%mod;
	}
	ll ans=0;
	rep(i,N+2){
		ll tmp=(p[i]*L[i])%mod;
		tmp=(tmp*R[i])%mod;
		tmp=(tmp*jyo(ML[i]*MR[i],mod-2,mod))%mod;
		ans=(ans+tmp)%mod;
	}
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 140
memory_kb: 3452
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<ll, ll>;
#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template<typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template<typename T> void chmax(T &a, const T &b) { a = max(a, b); }
struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio;
const ll INF = 1LL<<60;

template<ll MOD>
struct modint {
    ll x;
    modint(): x(0) {}
    modint(ll y) : x(y>=0 ? y%MOD : y%MOD+MOD) {}
    static constexpr ll mod() { return MOD; }
    // e乗
    modint pow(ll e) {
        ll a = 1, p = x;
        while(e > 0) {
            if(e%2 == 0) {p = (p*p) % MOD; e /= 2;}
            else {a = (a*p) % MOD; e--;}
        }
        return modint(a);
    }
    modint inv() const {
        ll a=x, b=MOD, u=1, y=1, v=0, z=0;
        while(a) {
            ll q = b/a;
            swap(z -= q*u, u);
            swap(y -= q*v, v);
            swap(b -= q*a, a);
        }
        return z;
    }
    // Comparators
    bool operator <(modint b) { return x < b.x; }
    bool operator >(modint b) { return x > b.x; }
    bool operator<=(modint b) { return x <= b.x; }
    bool operator>=(modint b) { return x >= b.x; }
    bool operator!=(modint b) { return x != b.x; }
    bool operator==(modint b) { return x == b.x; }
    // Basic Operations
    modint operator+(modint r) const { return modint(*this) += r; }
    modint operator-(modint r) const { return modint(*this) -= r; }
    modint operator*(modint r) const { return modint(*this) *= r; }
    modint operator/(modint r) const { return modint(*this) /= r; }
    modint &operator+=(modint r) {
        if((x += r.x) >= MOD) x -= MOD;
        return *this;
    }
    modint &operator-=(modint r) {
        if((x -= r.x) < 0) x += MOD;
        return *this;
    }
    modint &operator*=(modint r) {
    #if !defined(_WIN32) || defined(_WIN64)
        x = x * r.x % MOD; return *this;
    #endif
        unsigned long long y = x * r.x;
        unsigned xh = (unsigned) (y >> 32), xl = (unsigned) y, d, m;
        asm(
            "divl %4; \n\t"
            : "=a" (d), "=d" (m)
            : "d" (xh), "a" (xl), "r" (MOD)
        );
        x = m;
        return *this;
    }
    modint &operator/=(modint r) { return *this *= r.inv(); }
    // increment, decrement
    modint operator++() { x++; return *this; }
    modint operator++(signed) { modint t = *this; x++; return t; }
    modint operator--() { x--; return *this; }
    modint operator--(signed) { modint t = *this; x--; return t; }
    // 平方剰余のうち一つを返す なければ-1
    friend modint sqrt(modint a) {
        if(a == 0) return 0;
        ll q = MOD-1, s = 0;
        while((q&1)==0) q>>=1, s++;
        modint z=2;
        while(1) {
            if(z.pow((MOD-1)/2) == MOD-1) break;
            z++;
        }
        modint c = z.pow(q), r = a.pow((q+1)/2), t = a.pow(q);
        ll m = s;
        while(t.x>1) {
            modint tp=t;
            ll k=-1;
            FOR(i, 1, m) {
                tp *= tp;
                if(tp == 1) { k=i; break; }
            }
            if(k==-1) return -1;
            modint cp=c;
            REP(i, m-k-1) cp *= cp;
            c = cp*cp, t = c*t, r = cp*r, m = k;
        }
        return r.x;
    }

    template<class T>
    friend modint operator*(T l, modint r) { return modint(l) *= r; }
    template<class T>
    friend modint operator+(T l, modint r) { return modint(l) += r; }
    template<class T>
    friend modint operator-(T l, modint r) { return modint(l) -= r; }
    template<class T>
    friend modint operator/(T l, modint r) { return modint(l) /= r; }
    template<class T>
    friend bool operator==(T l, modint r) { return modint(l) == r; }
    template<class T>
    friend bool operator!=(T l, modint r) { return modint(l) != r; }
    // Input/Output
    friend ostream &operator<<(ostream& os, modint a) { return os << a.x; }
    friend istream &operator>>(istream& is, modint &a) { 
        is >> a.x;
        a.x = ((a.x%MOD)+MOD)%MOD;
        return is;
    }
    friend string to_frac(modint v) {
        static map<ll, PII> mp;
        if(mp.empty()) {
            mp[0] = mp[MOD] = {0, 1};
            FOR(i, 2, 1001) FOR(j, 1, i) if(__gcd(i, j) == 1) {
                mp[(modint(i) / j).x] = {i, j};
            }
        }
        auto itr = mp.lower_bound(v.x);
        if(itr != mp.begin() && v.x - prev(itr)->first < itr->first - v.x) --itr;
        string ret = to_string(itr->second.first + itr->second.second * ((int)v.x - itr->first));
        if(itr->second.second > 1) {
            ret += '/';
            ret += to_string(itr->second.second);
        }
        return ret;
    }
};
using mint = modint<998244353>;

// 前計算O(N) クエリO(1)
mint combi(ll N, ll K) {
    const int maxN=5e5; // !!!
    static mint fact[maxN+1]={},factr[maxN+1]={};
    if (fact[0]==0) {
        fact[0] = factr[0] = 1;
        FOR(i, 1, maxN+1) fact[i] = fact[i-1] * i;
        factr[maxN] = fact[maxN].inv();
        for(ll i=maxN-1; i>=0; --i) factr[i] = factr[i+1] * (i+1);
    }
    if(K<0 || K>N) return 0; // !!!
    return factr[K]*fact[N]*factr[N-K];
}

// 前計算O(Klog(mod)) クエリO(K)
mint combi_bigN(ll N, ll K) {
    const int maxN=5e5; // !!!
    static mint inv[maxN+1] = {};
    if(inv[0]==0) {
        inv[0] = 1;
        FOR(i, 1, maxN+1) inv[i] = mint(i).inv();
    }
    if(K<0 || K>N) return 0; // !!!
    mint ret = 1;
    for(;K>0;N--,K--) ret *= N, ret *= inv[K];
    return ret;
}

// \sum_{i=0}^{n-1} i^k O(k^2)
// kが固定でクエリがいっぱいならベルヌーイ数を前計算で高速化
mint sum_of_powers(ll n, ll k) {
    vector<mint> b(k+1), po(k+2);
    b[0] = po[0] = 1;
    FOR(i, 1, k+2) po[i] = po[i-1] * n;
    FOR(i, 1, k+1) {
        REP(j, i) b[i] += combi(i+1, j) * b[j];
        b[i] /= -(i+1);
    }
    mint sum = 0;
    REP(i, k+1) sum += combi(k+1, i) * b[i] * po[k+1-i];
    return sum / (k+1);
}

signed main(void) {
    ll n, s0;
    cin >> n >> s0;
    mint s = s0;

    mint ans = s * (s+1).pow(n-1) / 2;
    if(s0%2 == 0) {
        ans += mint(2).pow(n) * sum_of_powers(s0/2+1, n-1);
        ans -= sum_of_powers(s0+1, n-1);
    } else {
        ans -= mint(2).pow(n) * sum_of_powers(s0/2+1, n-1);
        ans += sum_of_powers(s0+1, n-1);
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11064
final_rank: 17

code_snippet: #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<queue>
#include<stack>
using namespace std;
#define MOD 998244353
#define INF (1<<29)
#define LINF (1LL<<60)
#define EPS (1e-10)
typedef long long Int;
typedef pair<Int, Int> P;

Int mod_pow(Int x, Int a, Int m = MOD){
    if(a == 0)return 1;
    Int res = mod_pow(x, a / 2, m);
    res = res * res % m;
    if(a % 2)res *= x;
    return res % m;
}

Int inv(Int x, Int m = MOD){
    return mod_pow(x, m-2, m);
}

Int fact[1080000];
Int revfact[1080000];
Int rev[1080000];

void init(){
    Int m = MOD;
    fact[0] = 1;
    revfact[0] = 1;
    rev[0] = 0;
    rev[1] = 1;
    for(int i = 1;i < 1080000;i++){
        fact[i] = fact[i-1] * i % m;
        if(i>1)rev[i] = MOD / i * (MOD-rev[MOD % i]) % MOD;
        revfact[i] = revfact[i-1] * rev[i] % MOD;
    }
}

Int nCk(Int n, Int k){
    if(n < k)return 0;
    return fact[n] * revfact[n-k] % MOD * revfact[k] % MOD;
}



Int B[1100];

void init_B(){
    init();
    B[0] = 1;
    for(int i = 1;i < 1100;i++){
        Int sgn = 1;
        if(i%2)sgn *= -1;
        for(int j = 0;j < i;j++){
            B[i] += sgn * nCk(i+1, j) * B[j] % MOD;
            B[i] %= MOD;
            sgn *= -1;
        }
        B[i] *= -sgn * inv(nCk(i+1,i));
        B[i] %= MOD;
        if(B[i] < 0)B[i] += MOD;
    }
}

Int S(int k, int n){
    Int res = 0;
    Int pown = n;
    for(int j = 0;j <= k;j++){
        res += nCk(k+1, k-j) * B[k-j] % MOD * pown % MOD;
        res %= MOD;
        pown = pown * n % MOD;
    }
    res = res * inv(k + 1) % MOD;
    res %= MOD;
    if(res < 0)res += MOD;
    return res;

}

Int calc(Int k, Int n){
    if(n % 2 == 0)return S(k, n/2) * mod_pow(2, k) % MOD;
    else return (S(k, n) - calc(k, n-1)) % MOD;
}

Int n, s, k;
int main(){
    init_B();    
    cin >> n >> s;    
    Int ans = 0;
    ans += s * (s+1) %MOD  * inv(2) %MOD* mod_pow(s+1, n-2) %MOD;
    int odds = (s - 1) / 2;
    ans += calc(n-1, s); ans %= MOD;
    ans -= calc(n-1, s-1); ans %= MOD;
    if(ans < 0)ans += MOD;
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 28440
final_rank: 19

code_snippet: #include <iostream>
#define llint long long
#define mod 998244353

using namespace std;

llint modpow(llint a, llint n)
{
	if(n == 0) return 1;
	if(n % 2){
		return ((a%mod) * (modpow(a, n-1)%mod)) % mod;
	}
	else{
		return modpow((a*a)%mod, n/2) % mod;
	}
}

llint n, s;
llint val[1005];

llint calc(llint x)
{
	llint ret = 0;
	for(int i = 1; i <= n+1; i++){
		llint tmp = val[i];
		for(int j = 1; j <= n+1; j++){
			if(i == j) continue;
			tmp *= (x-j+mod)%mod, tmp %= mod;
			tmp *= modpow((i-j+mod)%mod, mod-2), tmp %= mod;
		}
		ret += tmp, ret %= mod;
	}
	return ret;
}

int main(void)
{
	cin >> n >> s;
	
	llint sum = 0;
	for(int i = 1; i <= n+1; i++){
		sum += modpow(i, n-1), sum %= mod;
		val[i] = sum;
	}
	
	llint ans = (s+1)*s/2%mod;
	ans *= modpow(s+1, n-2), ans %= mod;
	
	llint tmp = modpow(2, n-1) * calc(s/2) % mod;
	tmp = calc(s) - 2*tmp%mod + mod, tmp %= mod;
	if(s % 2 == 0) tmp *= mod-1, tmp %= mod;
	
	ans += tmp, ans %= mod;
	cout << ans << endl;
	
	return 0;
}
accuracy: 1
time_ms: 650
memory_kb: 3120
final_rank: 18

code_snippet: //
// Created by maze on 2019/09/15.
//

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

#define INF_LL (int64)1e18
#define INF (int64)1e9
#define REP(i, n) for(int64 i = 0;i < (n);i++)
#define FOR(i, a, b) for(int64 i = (a); i < (b); i++)
#define all(x) x.begin(),x.end()
#define fs first
#define sc second

using int32 = int32_t;
using int64 = int64_t;
using PII = pair<int32, int32>;
using PLL = pair<int64, int64>;

constexpr int64 mod = 998244353;

int64 N, S;

int64 mpow(int64 a, int64 b) {
    if (b == 0) return 1;
    if (b % 2) return a * mpow(a, b-1) % mod;
    int64 ret = mpow(a, b/2);
    return ret*ret%mod;
}

void term_mul(vector<int64>& x, int64 a) { // xの多項式に(x-a)をかける
    REP(i, x.size()-1) {
        x[i] = x[i+1] + x[i] * (mod-a) % mod;
        x[i] %= mod;
//        x[i] = x[i+1] + x[i] * -a;
    }
    x.back() = x.back() * (mod - a) % mod;
//    x.back() = x.back() * -a;
}

vector<int64> term_div(vector<int64> x, int64 a) { // (x-a)で割る
    vector<int64> res(x.size(), 0);
    REP(i, x.size()-1) {
        res[i+1] = x[i];
        x[i+1] += mod-x[i]*(mod-a)%mod;
        x[i+1] %= mod;
    }
    return res;
}

vector<int64> term_sum(const vector<int64>& a, const vector<int64>& b, const int64 co = 1) {
    vector<int64> res(max(a.size(), b.size()), 0);
    REP(i, res.size()) {
        res[i] = a[i] + b[i] * co % mod;
        res[i] %= mod;
//        cout << "(" << a[i] << " " << b[i] << " " << co << " " << res[i] << ") ";
    }
//    cout << endl;
    return res;
}

vector<int64> lagrange(vector<int64>& x, vector<int64>& fx) {
    vector<int64> coeff(N+2, 0);
    vector<int64> all_mul(N+2, 0);
    all_mul.back() = 1;
    REP(i, x.size()) {
        term_mul(all_mul, (mod+x[i])%mod);
    }
    REP(i, x.size()) {
        int64 co = 1;
        REP(j, fx.size()) {
            if (i == j) continue;
            co = co * ((mod+x[i]-x[j])%mod) % mod;
        }
        auto ret = term_div(all_mul, x[i]);

        coeff = term_sum(coeff, term_div(all_mul, x[i]), fx[i]%mod*mpow(co, mod-2)%mod);
    }
    return coeff;
}

int64 apply(const vector<int64>& exp, int64 x) {
    int64 res = 0;
    int64 xx = 1;
    for (int64 i = exp.size()-1; i >= 0; i--) {
        res = (res + xx * exp[i]) % mod;
        xx = xx * x % mod;
    }
    return res;
}

int64 calc(int64 len, int64 val) {
    int64 res = 0;
    if (len <= 4 || len/2 < N) {
        REP(i, len) {
            if (i % 2 == 0)
                res += mpow(val-i-1, N);
            else
                res += mod - mpow(val-i-1, N);
            res %= mod;
        }
    } else {
        int64 idx = (len-1)/2-(1-(len-1)/2%2)+1;
        int64 l = idx-1, r = len-idx;
//        cout << l << " " << idx << " " << r << endl;
        int64 ret = calc(r, 0);
        cout << ret << endl;
        if (N % 2)
            ret += mod - ret;
        else
            ret += ret;
        ret %= mod;
        cout << "idx" << " " << idx << " " << l << " " << r << " " << ret << ": ";
        REP(i, r-l) {
           if (i%2 == 1) {
               ret += (mod - mpow(r-i, N));
           }  else {
               ret += mpow(r-i, N);
           }
           cout << "{" << mpow(r-i, N) << " " << i << "} ";
           ret %= mod;
        }
        cout << ret << endl;

        vector<int64> x(N+1), fx(N+1);
        x[0] = idx++; fx[0] = ret;
        REP(i, N) {
            x[i+1] = idx++;
            ret += mod - mpow(l + i + 1, N);
            ret %= mod;
            if (r % 2 == 0) {
                ret += mpow(mod - r + i , N);
            } else {
                ret += mod - mpow(mod - r + i, N);
            }
            ret %= mod;
            ret = mod - ret;
            fx[i+1] = ret;
        }
        auto exp = lagrange(x, fx);
//        REP(i, x.size()) {
//            cout << "(" << x[i] << " " << fx[i] << ") ";
//        }
//        cout << endl;
//        REP(i, exp.size()) {
//            cout << exp[i] << " ";
//        }
//        cout << endl;
        res = apply(exp, val);
    }
//    cout << len << " " << val << " " << res << endl;
    return res;
}

//int64 calc(int64 len, int64 val) { // (val-1)^N-(val-2)^N+...(len-len)^N
//
//}

int64 calc(int64 S) {
    vector<int64> x(N+1), fx(N+1);
    int64 now = 2-S%2;
    REP(i, N+1) {
        x[i] = now;
        fx[i] = (i > 0 ? fx[i-1] : 0);
        fx[i] += mpow(now, N) - mpow(now-1, N);
        fx[i] = (fx[i] %mod + mod) % mod;
        now += 2;
    }
    auto ret = lagrange(x, fx);
    return apply(ret, S%mod);
}

int main(void) {
    cin >> N >> S;
    int64 res = S*(S+1)%mod;
    res *= mpow(2, mod-2);
    res %= mod;
    res *= mpow(S+1, N-2);
    res %= mod;
    N--;
    res += calc(S);
    res %= mod;
    cout << res << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3176
final_rank: 1

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template<typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }

template<typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type
fill_v(T &t, const V &v) { t=v; }
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); }

template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a) {
    out<<'('<<a.first<<','<<a.second<<')'; return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
    out<<'[';
    for(const T &i: a) out<<i<<',';
    out<<']';
    return out;
}
template<class T>
ostream &operator <<(ostream& out, const set<T>& a) {
    out<<'{';
    for(const T &i: a) out<<i<<',';
    out<<'}';
    return out;
}
template<class T, class S>
ostream &operator <<(ostream& out, const map<T,S>& a) {
    out<<'{';
    for(auto &i: a) out<<i<<',';
    out<<'}';
    return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1<<30;
const ll LLINF = 1LL<<60;
const ll MOD = 1000000007;

template<ll MOD>
struct modint {
    ll x;
    modint(): x(0) {}
    modint(ll y) : x(y>=0 ? y%MOD : y%MOD+MOD) {}
    static constexpr ll mod() { return MOD; }
    // e乗
    modint pow(ll e) {
        ll a = 1, p = x;
        while(e > 0) {
            if(e%2 == 0) {p = (p*p) % MOD; e /= 2;}
            else {a = (a*p) % MOD; e--;}
        }
        return modint(a);
    }
    modint inv() const {
        ll a=x, b=MOD, u=1, y=1, v=0, z=0;
        while(a) {
            ll q = b/a;
            swap(z -= q*u, u);
            swap(y -= q*v, v);
            swap(b -= q*a, a);
        }
        return z;
    }
    // Comparators
    bool operator <(modint b) { return x < b.x; }
    bool operator >(modint b) { return x > b.x; }
    bool operator<=(modint b) { return x <= b.x; }
    bool operator>=(modint b) { return x >= b.x; }
    bool operator!=(modint b) { return x != b.x; }
    bool operator==(modint b) { return x == b.x; }
    // Basic Operations
    modint operator+(modint r) const { return modint(*this) += r; }
    modint operator-(modint r) const { return modint(*this) -= r; }
    modint operator*(modint r) const { return modint(*this) *= r; }
    modint operator/(modint r) const { return modint(*this) /= r; }
    modint &operator+=(modint r) {
        if((x += r.x) >= MOD) x -= MOD;
        return *this;
    }
    modint &operator-=(modint r) {
        if((x -= r.x) < 0) x += MOD;
        return *this;
    }
    modint &operator*=(modint r) {
    #if !defined(_WIN32) || defined(_WIN64)
        x = x * r.x % MOD; return *this;
    #endif
        unsigned long long y = x * r.x;
        unsigned xh = (unsigned) (y >> 32), xl = (unsigned) y, d, m;
        asm(
            "divl %4; \n\t"
            : "=a" (d), "=d" (m)
            : "d" (xh), "a" (xl), "r" (MOD)
        );
        x = m;
        return *this;
    }
    modint &operator/=(modint r) { return *this *= r.inv(); }
    // increment, decrement
    modint operator++() { x++; return *this; }
    modint operator++(signed) { modint t = *this; x++; return t; }
    modint operator--() { x--; return *this; }
    modint operator--(signed) { modint t = *this; x--; return t; }

    template<class T>
    friend modint operator*(T l, modint r) { return modint(l) *= r; }
    template<class T>
    friend modint operator+(T l, modint r) { return modint(l) += r; }
    template<class T>
    friend modint operator-(T l, modint r) { return modint(l) -= r; }
    template<class T>
    friend modint operator/(T l, modint r) { return modint(l) /= r; }
    template<class T>
    friend bool operator==(T l, modint r) { return modint(l) == r; }
    template<class T>
    friend bool operator!=(T l, modint r) { return modint(l) != r; }
    // Input/Output
    friend ostream &operator<<(ostream& os, modint a) { return os << a.x; }
    friend istream &operator>>(istream& is, modint &a) { return is >> a.x; }
    friend string to_frac(modint v) {
        static map<ll, PII> mp;
        if(mp.empty()) {
            mp[0] = mp[MOD] = {0, 1};
            FOR(i, 2, 1001) FOR(j, 1, i) if(__gcd(i, j) == 1) {
                mp[(modint(i) / j).x] = {i, j};
            }
        }
        auto itr = mp.lower_bound(v.x);
        if(itr != mp.begin() && v.x - prev(itr)->first < itr->first - v.x) --itr;
        string ret = to_string(itr->second.first + itr->second.second * ((int)v.x - itr->first));
        if(itr->second.second > 1) {
            ret += '/';
            ret += to_string(itr->second.second);
        }
        return ret;
    }
};
using mint = modint<998244353>;

// 前計算O(N) クエリO(1)
mint combi(ll N, ll K) {
    const int maxN=5e5; // !!!
    static mint fact[maxN+1]={},factr[maxN+1]={};
    if (fact[0]==0) {
        fact[0] = factr[0] = 1;
        FOR(i, 1, maxN+1) fact[i] = fact[i-1] * i;
        factr[maxN] = fact[maxN].inv();
        for(ll i=maxN-1; i>=0; --i) factr[i] = factr[i+1] * (i+1);
    }
    if(K<0 || K>N) return 0; // !!!
    return factr[K]*fact[N]*factr[N-K];
}

// \sum_{i=0}^{n-1} i^k O(k^2)
// kが固定でクエリがいっぱいならベルヌーイ数を前計算で高速化
mint sum_of_powers(ll n, ll k) {
    vector<mint> b(k+1), po(k+2);
    b[0] = po[0] = 1;
    FOR(i, 1, k+2) po[i] = po[i-1] * n;
    FOR(i, 1, k+1) {
        REP(j, i) b[i] += combi(i+1, j) * b[j];
        b[i] /= -(i+1);
    }
    mint sum = 0;
    REP(i, k+1) sum += combi(k+1, i) * b[i] * po[k+1-i];
    return sum / (k+1);
}

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

    ll n, s0;
    cin >> n >> s0;
    mint s = s0;

    mint ans = s * (s+1).pow(n-1) / 2;
    if(s0%2 == 0) {
        ans += mint(2).pow(n) * sum_of_powers(s0/2+1, n-1);
        ans -= sum_of_powers(s0+1, n-1);
    } else {
        ans -= mint(2).pow(n) * sum_of_powers(s0/2+1, n-1);
        ans += sum_of_powers(s0+1, n-1);
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11004
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template<typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }

template<typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type
fill_v(T &t, const V &v) { t=v; }
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); }

template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a) {
    out<<'('<<a.first<<','<<a.second<<')'; return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
    out<<'[';
    for(const T &i: a) out<<i<<',';
    out<<']';
    return out;
}
template<class T>
ostream &operator <<(ostream& out, const set<T>& a) {
    out<<'{';
    for(const T &i: a) out<<i<<',';
    out<<'}';
    return out;
}
template<class T, class S>
ostream &operator <<(ostream& out, const map<T,S>& a) {
    out<<'{';
    for(auto &i: a) out<<i<<',';
    out<<'}';
    return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1<<30;
const ll LLINF = 1LL<<60;
const ll MOD = 1000000007;

template<ll MOD>
struct modint {
    ll x;
    modint(): x(0) {}
    modint(ll y) : x(y>=0 ? y%MOD : y%MOD+MOD) {}
    static constexpr ll mod() { return MOD; }
    // e乗
    modint pow(ll e) {
        ll a = 1, p = x;
        while(e > 0) {
            if(e%2 == 0) {p = (p*p) % MOD; e /= 2;}
            else {a = (a*p) % MOD; e--;}
        }
        return modint(a);
    }
    modint inv() const {
        ll a=x, b=MOD, u=1, y=1, v=0, z=0;
        while(a) {
            ll q = b/a;
            swap(z -= q*u, u);
            swap(y -= q*v, v);
            swap(b -= q*a, a);
        }
        return z;
    }
    // Comparators
    bool operator <(modint b) { return x < b.x; }
    bool operator >(modint b) { return x > b.x; }
    bool operator<=(modint b) { return x <= b.x; }
    bool operator>=(modint b) { return x >= b.x; }
    bool operator!=(modint b) { return x != b.x; }
    bool operator==(modint b) { return x == b.x; }
    // Basic Operations
    modint operator+(modint r) const { return modint(*this) += r; }
    modint operator-(modint r) const { return modint(*this) -= r; }
    modint operator*(modint r) const { return modint(*this) *= r; }
    modint operator/(modint r) const { return modint(*this) /= r; }
    modint &operator+=(modint r) {
        if((x += r.x) >= MOD) x -= MOD;
        return *this;
    }
    modint &operator-=(modint r) {
        if((x -= r.x) < 0) x += MOD;
        return *this;
    }
    modint &operator*=(modint r) {
    #if !defined(_WIN32) || defined(_WIN64)
        x = x * r.x % MOD; return *this;
    #endif
        unsigned long long y = x * r.x;
        unsigned xh = (unsigned) (y >> 32), xl = (unsigned) y, d, m;
        asm(
            "divl %4; \n\t"
            : "=a" (d), "=d" (m)
            : "d" (xh), "a" (xl), "r" (MOD)
        );
        x = m;
        return *this;
    }
    modint &operator/=(modint r) { return *this *= r.inv(); }
    // increment, decrement
    modint operator++() { x++; return *this; }
    modint operator++(signed) { modint t = *this; x++; return t; }
    modint operator--() { x--; return *this; }
    modint operator--(signed) { modint t = *this; x--; return t; }

    template<class T>
    friend modint operator*(T l, modint r) { return modint(l) *= r; }
    template<class T>
    friend modint operator+(T l, modint r) { return modint(l) += r; }
    template<class T>
    friend modint operator-(T l, modint r) { return modint(l) -= r; }
    template<class T>
    friend modint operator/(T l, modint r) { return modint(l) /= r; }
    template<class T>
    friend bool operator==(T l, modint r) { return modint(l) == r; }
    template<class T>
    friend bool operator!=(T l, modint r) { return modint(l) != r; }
    // Input/Output
    friend ostream &operator<<(ostream& os, modint a) { return os << a.x; }
    friend istream &operator>>(istream& is, modint &a) { return is >> a.x; }
    friend string to_frac(modint v) {
        static map<ll, PII> mp;
        if(mp.empty()) {
            mp[0] = mp[MOD] = {0, 1};
            FOR(i, 2, 1001) FOR(j, 1, i) if(__gcd(i, j) == 1) {
                mp[(modint(i) / j).x] = {i, j};
            }
        }
        auto itr = mp.lower_bound(v.x);
        if(itr != mp.begin() && v.x - prev(itr)->first < itr->first - v.x) --itr;
        string ret = to_string(itr->second.first + itr->second.second * ((int)v.x - itr->first));
        if(itr->second.second > 1) {
            ret += '/';
            ret += to_string(itr->second.second);
        }
        return ret;
    }
};
using mint = modint<998244353>;

// 前計算O(N) クエリO(1)
mint combi(ll N, ll K) {
    const int maxN=5e5; // !!!
    static mint fact[maxN+1]={},factr[maxN+1]={};
    if (fact[0]==0) {
        fact[0] = factr[0] = 1;
        FOR(i, 1, maxN+1) fact[i] = fact[i-1] * i;
        factr[maxN] = fact[maxN].inv();
        for(ll i=maxN-1; i>=0; --i) factr[i] = factr[i+1] * (i+1);
    }
    if(K<0 || K>N) return 0; // !!!
    return factr[K]*fact[N]*factr[N-K];
}

// \sum_{i=0}^{n-1} i^k O(k^2)
mint sum_of_powers(ll n, ll k) {
    vector<mint> b(k+1), po(k+2);
    b[0] = po[0] = 1;
    FOR(i, 1, k+2) po[i] = po[i-1] * n;
    FOR(i, 1, k+1) {
        REP(j, i) b[i] += combi(i+1, j) * b[j];
        b[i] /= -(i+1);
    }
    mint sum = 0;
    REP(i, k+1) sum += combi(k+1, i) * b[i] * po[k+1-i];
    return sum / (k+1);
}

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

    ll n, s0;
    cin >> n >> s0;
    mint s = s0;

    mint ans = s * (s+1).pow(n-1) / 2;
    if(s0%2 == 0) {
        ans += mint(2).pow(n) * sum_of_powers(s0/2+1, n-1);
        ans -= sum_of_powers(s0+1, n-1);
    } else {
        ans -= mint(2).pow(n) * sum_of_powers(s0/2+1, n-1);
        ans += sum_of_powers(s0+1, n-1);
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11036
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template<typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }

template<typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type
fill_v(T &t, const V &v) { t=v; }
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); }

template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a) {
    out<<'('<<a.first<<','<<a.second<<')'; return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
    out<<'[';
    for(const T &i: a) out<<i<<',';
    out<<']';
    return out;
}
template<class T>
ostream &operator <<(ostream& out, const set<T>& a) {
    out<<'{';
    for(const T &i: a) out<<i<<',';
    out<<'}';
    return out;
}
template<class T, class S>
ostream &operator <<(ostream& out, const map<T,S>& a) {
    out<<'{';
    for(auto &i: a) out<<i<<',';
    out<<'}';
    return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1<<30;
const ll LLINF = 1LL<<60;
const ll MOD = 1000000007;

template<ll MOD>
struct modint {
    ll x;
    modint(): x(0) {}
    modint(ll y) : x(y>=0 ? y%MOD : y%MOD+MOD) {}
    static constexpr ll mod() { return MOD; }
    // e乗
    modint pow(ll e) {
        ll a = 1, p = x;
        while(e > 0) {
            if(e%2 == 0) {p = (p*p) % MOD; e /= 2;}
            else {a = (a*p) % MOD; e--;}
        }
        return modint(a);
    }
    modint inv() const {
        ll a=x, b=MOD, u=1, y=1, v=0, z=0;
        while(a) {
            ll q = b/a;
            swap(z -= q*u, u);
            swap(y -= q*v, v);
            swap(b -= q*a, a);
        }
        return z;
    }
    // Comparators
    bool operator <(modint b) { return x < b.x; }
    bool operator >(modint b) { return x > b.x; }
    bool operator<=(modint b) { return x <= b.x; }
    bool operator>=(modint b) { return x >= b.x; }
    bool operator!=(modint b) { return x != b.x; }
    bool operator==(modint b) { return x == b.x; }
    // Basic Operations
    modint operator+(modint r) const { return modint(*this) += r; }
    modint operator-(modint r) const { return modint(*this) -= r; }
    modint operator*(modint r) const { return modint(*this) *= r; }
    modint operator/(modint r) const { return modint(*this) /= r; }
    modint &operator+=(modint r) {
        if((x += r.x) >= MOD) x -= MOD;
        return *this;
    }
    modint &operator-=(modint r) {
        if((x -= r.x) < 0) x += MOD;
        return *this;
    }
    modint &operator*=(modint r) {
    #if !defined(_WIN32) || defined(_WIN64)
        x = x * r.x % MOD; return *this;
    #endif
        unsigned long long y = x * r.x;
        unsigned xh = (unsigned) (y >> 32), xl = (unsigned) y, d, m;
        asm(
            "divl %4; nt"
            : "=a" (d), "=d" (m)
            : "d" (xh), "a" (xl), "r" (MOD)
        );
        x = m;
        return *this;
    }
    modint &operator/=(modint r) { return *this *= r.inv(); }
    // increment, decrement
    modint operator++() { x++; return *this; }
    modint operator++(signed) { modint t = *this; x++; return t; }
    modint operator--() { x--; return *this; }
    modint operator--(signed) { modint t = *this; x--; return t; }

    template<class T>
    friend modint operator*(T l, modint r) { return modint(l) *= r; }
    template<class T>
    friend modint operator+(T l, modint r) { return modint(l) += r; }
    template<class T>
    friend modint operator-(T l, modint r) { return modint(l) -= r; }
    template<class T>
    friend modint operator/(T l, modint r) { return modint(l) /= r; }
    template<class T>
    friend bool operator==(T l, modint r) { return modint(l) == r; }
    template<class T>
    friend bool operator!=(T l, modint r) { return modint(l) != r; }
    // Input/Output
    friend ostream &operator<<(ostream& os, modint a) { return os << a.x; }
    friend istream &operator>>(istream& is, modint &a) { return is >> a.x; }
    friend string to_frac(modint v) {
        static map<ll, PII> mp;
        if(mp.empty()) {
            mp[0] = mp[MOD] = {0, 1};
            FOR(i, 2, 1001) FOR(j, 1, i) if(__gcd(i, j) == 1) {
                mp[(modint(i) / j).x] = {i, j};
            }
        }
        auto itr = mp.lower_bound(v.x);
        if(itr != mp.begin() && v.x - prev(itr)->first < itr->first - v.x) --itr;
        string ret = to_string(itr->second.first + itr->second.second * ((int)v.x - itr->first));
        if(itr->second.second > 1) {
            ret += '/';
            ret += to_string(itr->second.second);
        }
        return ret;
    }
};
using mint = modint<998244353>;

// x座標が相異なるn+1点(x_i,y_i)を通るn次以下の多項式f(T)の値を返す
// O(n^2)
mint lagrange_interpolation(vector<mint> x, vector<mint> y, mint T) {
    const ll n = x.size() - 1;
    mint ret = 0;
    REP(i, n+1) {
        mint t = 1;
        REP(j, n+1) {
            if(i == j) continue;
            t *= T-x[j];
            t /= x[i]-x[j];
        }
        ret += t * y[i];
    }
    return ret;
}

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

    ll n, s0;
    cin >> n >> s0;
    mint s = s0;

    mint ans = s * (s+1).pow(n-1) / 2;
    vector<mint> xs(n), ys(n);
    REP(i, n) {
        ll x = 2*i + s0%2;
        mint y = 0;
        bool turn = true;
        REP(j, x) {
            if(turn) y += mint(x-j).pow(n-1);
            else y -= mint(x-j).pow(n-1);
            turn = !turn;
        }
        xs[i] = x, ys[i] = y;
    }
    ans += lagrange_interpolation(xs, ys, s);
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3200
final_rank: 5

code_snippet: #include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
using ll = long long int;
const ll mod = 998244353;

ll mod_pow(ll n, ll k, ll m=mod) {
    ll res = 1;
    for(; k>0; k>>=1) {
        if(k & 1) (res *= n) %= m;
        (n *= n) %= m;
    }
    return res;
}

template <typename NumType>
struct LagrangePolynomial {
    vector<NumType> x, y, f_table;
    LagrangePolynomial() {}
    LagrangePolynomial(vector<NumType> x_,
                       vector<NumType> y_) : x(x_), y(y_) {
        int N = x.size();
        for(int i=0; i<N; i++) {
            f_table.emplace_back(f(i, x[i]));
        }
    }

    NumType f(int i, NumType p) {
        int N = x.size();
        NumType res(1);
        for(int k=0; k<N; k++) {
            if(i == k) continue;
            (res *= NumType(p - x[k])) %= mod;
            if(res < 0) (res += mod);
        }
        return res;
    }

    NumType interpolate(NumType p) {
        int N = x.size();
        NumType res(0);
        for(int i=0; i<N; i++) {
            NumType inv = mod_pow(f_table[i], mod-2, mod);
            (res += y[i] * f(i, p) % mod * inv % mod) %= mod;
        }
        return res;
    }
};

ll solve_small(ll N, ll S, ll K) {
    ll res = 0;
    for(int k=0; k<=K; k++) {
        ll add = 0;
        if(k % 2 == 1) {
            (add += mod_pow(S-k+1, N-1) - mod_pow(S-k, N-1)) %= mod;
        }
        else {
            (add -= mod_pow(S-k+1, N-1) - mod_pow(S-k, N-1)) %= mod;
        }
        if(add < 0) add += mod;
        (res += add) %= mod;
    }
    return res;
}

int main() {
    ll N, S; cin >> N >> S;
    ll ans = mod_pow(S+1, N, mod);
    // fprintf(stderr, "ans: %lld\n", ans);

    int p = S % 2;
    vector<ll> x(N), y(N);
    for(int i=0; i<N; i++) {
        int k = 2*i + p;
        x[i] = k;
        y[i] = solve_small(N, S, k);
        // fprintf(stderr, "x = %lld: y = %lld\n", x[i], y[i]);
    }

    LagrangePolynomial<ll> lp(x, y);
    (ans += lp.interpolate(S)) %= mod;
    // fprintf(stderr, "interpolate: %lld\n", lp.interpolate(S));
    (ans *= mod_pow(2, mod-2)) %= mod;
    cout << ans << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 3212
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define fi first
#define se second
typedef pair<ll,ll> P;
#define Mod 998244353
using VP = vector<P>; using VVP = vector<VP>;
using VI = vector<ll>; using VVI = vector<VI>; using VVVI = vector<VVI>;


template<typename T>
T pow(T a, long long n, T e = 1) {
    T ret = e;
    while (n) {
        if (n & 1) ret *= a;
        a *= a;
        n >>= 1;
    }
    return ret;
}

template<int mod>
struct ModInt {
    int x;
    ModInt() : x(0) {}
    ModInt(long long x_) { if ((x = x_ % mod + mod) >= mod) x -= mod; }
    ModInt& operator+=(ModInt rhs) { if ((x += rhs.x) >= mod) x -= mod; return *this; }
    ModInt& operator-=(ModInt rhs) { if ((x -= rhs.x) < 0) x += mod; return *this; }
    ModInt& operator*=(ModInt rhs) { x = (unsigned long long) x * rhs.x % mod; return *this; }
    ModInt& operator/=(ModInt rhs) { x = (unsigned long long) x * rhs.inv().x % mod; return *this; }

    ModInt operator-() const { return -x < 0 ? mod - x : -x; }
    ModInt operator+(ModInt rhs) const { return ModInt(*this) += rhs; }
    ModInt operator-(ModInt rhs) const { return ModInt(*this) -= rhs; }
    ModInt operator*(ModInt rhs) const { return ModInt(*this) *= rhs; }
    ModInt operator/(ModInt rhs) const { return ModInt(*this) /= rhs; }
    bool operator==(ModInt rhs) const { return x == rhs.x; }
    bool operator!=(ModInt rhs) const { return x != rhs.x; }
    ModInt inv() const { return pow(*this, mod - 2); }

    friend ostream& operator<<(ostream& s, ModInt<mod> a) { s << a.x; return s; }
    friend istream& operator>>(istream& s, ModInt<mod>& a) { s >> a.x; return s; }
};

using mint = ModInt<998244353>;

mint fact[202020];
mint factinv[202020];

mint fallingfact(int n, int p) {
    return fact[n] * factinv[n - p + 1];
}

void init() {
    fact[0] = 1;
    for (int i = 1; i < 202020; i++) {
        fact[i] = fact[i - 1] * i;
    }
    factinv[202020 - 1] = fact[202020 - 1].inv();
    for (int i = 202020 - 2; i >= 0; i--) {
        factinv[i] = factinv[i + 1] * (i + 1);
    }
    assert(factinv[0] == 1);
}

mint ncr(int n, int r) {
    return fact[n] * factinv[r] * factinv[n - r];
}

map<pair<int, int>, mint> memo;

// sum_{x=1^k} x^m
mint powsum(int k, int m) {
    if (memo.count({k, m})) {
        return memo[{k, m}];
    }
    mint ret = 0;
    for (int i = 2; i <= m + 1; i++) {
        ret += ncr(m + 1, i) * powsum(k, m + 1 - i);
    }
    ret = ret + 1 - pow(mint(k + 1), m + 1);
    ret /= -(m + 1);
    return memo[{k, m}] = ret;
}

int main() {
    int n,s;
    cin>>n>>s;

    mint zo;

    if(s%2==1){
        init();
        mint a=powsum(s,n-1);
        mint b=powsum((s-1)/2,n-1);
        b*=(mint)pow((mint)2,n);
        zo=a-b;
    }
    else{
        init();
        mint a=powsum(s/2,n-1);
        mint b=powsum(s,n-1);
        a*=(mint)pow((mint)2,n);
        zo=a-b;
    }
    
    mint r=(pow((mint)(s+1),n)-pow((mint)(s+1),n-1));
    r=r/(mint)2;
    cout<<r+zo<<endl;

}
accuracy: 1
time_ms: 60
memory_kb: 4904
final_rank: 8

code_snippet: //#define NDEBUG
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <vector>

namespace n91 {

using i8 = std::int_fast8_t;
using i32 = std::int_fast32_t;
using i64 = std::int_fast64_t;
using u8 = std::uint_fast8_t;
using u32 = std::uint_fast32_t;
using u64 = std::uint_fast64_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;

constexpr usize operator"" _z(unsigned long long x) noexcept {
  return static_cast<usize>(x);
}

class rep {
  const usize f, l;

public:
  class itr {
    friend rep;
    usize i;
    constexpr itr(const usize x) noexcept : i(x) {}

  public:
    void operator++() noexcept { ++i; }
    constexpr usize operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr x) const noexcept { return i != x.i; }
  };
  constexpr rep(const usize first, const usize last) noexcept
      : f(first), l(last) {}
  constexpr itr begin() const noexcept { return itr(f); }
  constexpr itr end() const noexcept { return itr(l); }
};
class revrep {
  const usize f, l;

public:
  class itr {
    friend revrep;
    usize i;
    constexpr itr(usize x) noexcept : i(x) {}

  public:
    void operator++() noexcept { --i; }
    constexpr usize operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr x) const noexcept { return i != x.i; }
  };
  constexpr revrep(usize first, usize last) noexcept : f(--first), l(--last) {}
  constexpr itr begin() const noexcept { return itr(l); }
  constexpr itr end() const noexcept { return itr(f); }
};
template <class T> using vec_alias = std::vector<T>;
template <class T> auto md_vec(const usize n, const T &value) {
  return std::vector<T>(n, value);
}
template <class... Args> auto md_vec(const usize n, Args... args) {
  return std::vector<decltype(md_vec(args...))>(n, md_vec(args...));
}
template <class T> constexpr T difference(const T &a, const T &b) {
  return a < b ? b - a : a - b;
}
template <class T> T scan() {
  T ret;
  std::cin >> ret;
  return ret;
}

} // namespace n91

#include <cstdint>

namespace n91 {

constexpr std::uint_fast64_t totient(std::uint_fast64_t x) noexcept {
  using u64 = std::uint_fast64_t;
  u64 ret = x;
  for (u64 i = static_cast<u64>(2); i * i <= x; ++i) {
    if (x % i == static_cast<u64>(0)) {
      ret -= ret / i;
      x /= i;
      while (x % i == static_cast<u64>(0)) {
        x /= i;
      }
    }
  }
  if (x != static_cast<u64>(1)) {
    ret -= ret / x;
  }
  return ret;
}

template <std::uint_fast64_t Modulus,
          std::uint_fast64_t InverseExp =
              totient(Modulus) - static_cast<std::uint_fast64_t>(1)>
class modint {
  using u64 = std::uint_fast64_t;

  static_assert(Modulus < static_cast<u64>(1) << static_cast<u64>(32),
                "Modulus must be less than 2**32");

  u64 a;

  constexpr modint &negate() noexcept {
    if (a != static_cast<u64>(0)) {
      a = Modulus - a;
    }
    return *this;
  }

public:
  constexpr modint(const u64 x = static_cast<u64>(0)) noexcept
      : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+() const noexcept { return modint(*this); }
  constexpr modint operator-() const noexcept { return modint(*this).negate(); }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = InverseExp;
    while (exp) {
      if (exp % static_cast<u64>(2) != static_cast<u64>(0)) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= static_cast<u64>(2);
    }
    return *this;
  }
  constexpr bool operator==(const modint rhs) const noexcept {
    return a == rhs.a;
  }
  constexpr bool operator!=(const modint rhs) const noexcept {
    return a != rhs.a;
  }
};

template <class T, std::uint_fast64_t v> class modint_constant {
public:
  static constexpr T value = static_cast<T>(v);

  using value_type = T;
};

} // namespace n91

#include <vector>

namespace n91 {

template <class T> class fact_binom {
public:
  using value_type = T;
  using container_type = std::vector<value_type>;
  using size_type = typename container_type::size_type;

private:
  container_type factrial, inv_fact;

public:
  fact_binom() : factrial(), inv_fact() {}
  explicit fact_binom(const size_type n) : factrial(n + 1), inv_fact(n + 1) {
    factrial[0] = static_cast<value_type>(1);
    for (size_type i = 0; i != n; ++i) {
      factrial[i + 1] = static_cast<value_type>(i + 1) * factrial[i];
    }
    inv_fact[n] = static_cast<value_type>(1) / factrial[n];
    for (size_type i = n; i != 0; --i) {
      inv_fact[i - 1] = inv_fact[i] * static_cast<value_type>(i);
    }
  }

  value_type operator()(const size_type n, const size_type r) const {
    return factrial[n] * inv_fact[r] * inv_fact[n - r];
  }
};

} // namespace n91

#include <functional>
#include <utility>

namespace n91 {

template <class T, class U, class Operate = std::multiplies<T>>
constexpr T power(T base, U exp, const Operate &oper = Operate(),
                  T iden = static_cast<T>(1)) {
  while (exp != static_cast<U>(0)) {
    if (exp % static_cast<U>(2) != static_cast<U>(0)) {
      iden = oper(iden, base);
    }
    exp /= static_cast<U>(2);
    base = oper(base, base);
  }
  return iden;
}

} // namespace n91

#include <algorithm>
#include <iostream>
#include <utility>

namespace n91 {

void main_() {
  using mint = modint<static_cast<u64>(998244353)>;
  const usize n = scan<usize>();
  const usize s = scan<usize>();
  usize r = 2_z;
  while ((r + 2_z) * (r + 2_z) < s) {
    r += 2_z;
  }
  const fact_binom<mint> binom(n);
  std::vector<mint> coef(n, static_cast<mint>(0));
  {
    std::vector<mint> pows(r, -static_cast<mint>(1));
    for (usize i = 0_z; i < r; i += 2_z) {
      pows[i] = static_cast<mint>(1);
    }
    for (const auto i : revrep(0_z, n)) {
      for (const auto e : pows) {
        coef[i] += e;
      }
      coef[i] *= binom(n - 1_z, i);
      if (i % 2_z == 1_z) {
        coef[i] = -coef[i];
      }
      for (const auto k : rep(0_z, r)) {
        pows[k] *= static_cast<mint>(s - k);
      }
    }
  }
  mint ans = power(static_cast<mint>(s + 1_z), n - 1_z) * static_cast<mint>(s) /
             static_cast<mint>(2);
  usize i = 0_z;
  for (; (i + r) < s; i += r) {
    mint p = static_cast<mint>(1);
    for (const auto e : coef) {
      ans += e * p;
      p *= static_cast<mint>(i);
    }
  }
  for (; i < s; i += 2_z) {
    ans += power(static_cast<mint>(s - i), n - 1_z) -
           power(static_cast<mint>(s - i - 1_z), n - 1_z);
  }
  std::cout << ans.value() << std::endl;
}

} // namespace n91

int main() {
  n91::main_();
  return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 3128
final_rank: 11

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<map>
using namespace std;
#define int long long
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define mod 998244353
typedef long long ll;
int  mod_pow(int a,int b){
    if(b==0)return 1;
    if(b==1)return a;
    if(b%2==0){
        int k = mod_pow(a,b/2);
        return k*k%mod;
    }else{
        int k = mod_pow(a,b/2);
        k *= k;
        k%= mod;
        return k*a%mod;
    }
}
#define MAX_N 100005
int inv[MAX_N],fac[MAX_N],finv[MAX_N];
void make(){
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(int i=2;i<MAX_N;i++){
        inv[i] = mod -inv[mod%i]*(mod/i)%mod;
        fac[i] = fac[i-1]*i%mod;
        finv[i] = finv[i-1]*inv[i] %mod;
    }
}

inline int add(int x,int y){
    return (x+y)%mod;
}
inline int sub(int x,int y){
    return (x+mod-y)%mod;
}
inline int mul(int x,int y){
    return x*y%mod;
}

void extgcd(int a,int b,int &x,int &y){
    if(b!=0){
        extgcd(b,a%b,y,x);
        y -= (a/b)*x;
    }else{
        x = 1;
        y = 0;
    }
}

int mod_inverse(int a,int m){
    int x,y;
    extgcd(a,m,x,y);
    return (m+x%m)%m;   
}

int solve(int deg,int num,vector<int>&val){
    if(num<=deg){
        return val[num];
    }
    int ue = 1;
    rep(i,deg+1){
        ue = mul(ue,sub(num%mod,i));
    }
    int ans = 0;
    rep(i,deg+1){
        int r1 = mul(ue,mul(mod_inverse(sub(num%mod,i),mod),val[i]));
        int r2 = mul(finv[deg-i],finv[i]);
        if((deg-i)%2){
            r2 = mod-r2;
        }
        ans = add(ans,mul(r1,r2));
    }
    return ans;
}

signed main(){
    make();
    ll n;
    ll ss;
    cin >> n >> ss;
    vector<ll> p(n+1),q(n+1);
    rep(s,2*n+2){
        ll sm = 0;
        rep(x,s){
            sm += mod_pow(s+1,n-2)*(s-x)%mod;
            sm %= mod;
        }
        //cerr << sm << endl;
        for(int x=1;x<=s;x+=2){
            sm += (s-x)*((mod_pow(s-x+1,n-2)+mod-(mod_pow(s-x,n-2)))%mod)%mod;
            
            sm %= mod;
        }
        for(int x=1;x<=s;x+=2){
            sm += mod_pow(s-x+1,n-2);
            sm %= mod;
        }
        //cerr << s << " " << sm << endl;
        if(s%2==0)p[s/2] = sm;
        else q[s/2] = sm;
        //cerr << s << endl;
    }
    if(ss%2==0)cout << solve(n,ss/2,p) << endl;
    else cout << solve(n,ss/2,q) << endl;
    
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 5440
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint = long long;
template<class T = int> using V = vector<T>;
template<class T = int> using VV = V< V<T> >;

constexpr lint mod = 998244353;
lint tmod(lint a, lint p) { return (a %= p) < 0 ? a + p : a; }
lint mod_pow(lint a, lint n, lint p) {
    if (n < 0) return 0;
    a = tmod(a, p);
    lint res = 1;
    while (n) {
        if (n & 1) (res *= a) %= p;
        (a *= a) %= p;
        n >>= 1;
    }
    return res;
}
lint fact[2000], ifact[2000];
void init() {
    fact[0] = ifact[0] = 1;
    for (int i = 1; i < 2000; ++i) {
        fact[i] = i * fact[i - 1] % mod;
        ifact[i] = mod_pow(fact[i], mod - 2, mod);
    }
}


int main() {
    init();
    lint n, S; cin >> n >> S;

    auto fn = [&](int x) -> lint {
        lint res = 0;
        for (int i = 0; i < x; ++i) {
            if (i & 1) res -= mod_pow(x - i, n - 1, mod);
            else res += mod_pow(x - i, n - 1, mod);
            res %= mod;
        }
        return tmod(res, mod);
    };

    lint res = S * (S + 1) / 2 % mod * mod_pow(S + 1, n - 2, mod);
    // cerr << "naive: " << tmod(res + fn(S), mod) << endl;

    // int m = n;
    for (int k = S & 1; k <= 2 * n + 1; k += 2) {
        lint curr = 1;
        for (int i = S & 1; i <= 2 * n + 1; i += 2) if (i != k) {
            (curr *= S - i) %= mod;
            (curr *= mod_pow(k - i, mod - 2, mod)) %= mod;
        }
        curr *= fn(k);
        // cerr << k << ' ' << tmod(curr, mod) << endl;
        res += curr;
        res %= mod;
    }

    // for (int i = 0; i < S; ++i) {
    //     if (i & 1) res -= mod_pow(S - i, n - 1, mod);
    //     else res += mod_pow(S - i, n - 1, mod);
    //     res %= mod;
    //     if (i % 10000000 == 0) cerr << i / 10000000 << endl;
    // }
    cout << tmod(res, mod) << endl;
}
accuracy: 1
time_ms: 140
memory_kb: 3148
final_rank: 6

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

#define REP(i,n) for(int i=0; i<(n); i++)
#define FOR(i,a,b) for(int i=(a); i<(b); i++)
#define FORR(i,a,b) for(int i=(b)-1; i>=(a); i--)

#define DEBUG(x) cerr << #x << ": " << (x) << endl

using ll = long long;
const ll MOD = 998244353;

ll n,s;

ll modpow(ll a, ll b){
	ll r = 1;
	while(b){
		if(b&1)r=r*a%MOD;
		a=a*a%MOD;
		b>>=1;
	}
	return r;
}

typedef vector<ll> vl;

void debug(vl a){
	// REP(i,a.size())printf("%lld ",a[i]>MOD/2 ? a[i]-MOD : a[i]);
	REP(i,a.size())printf("%lld ",a[i]>MOD/2 ? a[i] : a[i]);
	puts("");
}

// meccha gambatte interpolation omoidasite kaiteru poyo
// by nari

vl mymul(vl a, vl b){
	int n = a.size();
	int m = b.size();
	vl c(n+m-1);
	REP(i,n)REP(j,m)c[i+j] = (c[i+j] + a[i]*b[j]%MOD) % MOD;
	// cerr << __LINE__ << endl;
	// debug(a);
	// debug(b);
	// debug(c);
	return c;
}
vl mydiv(vl a, ll b){
	// poly(a) / (x-b)
	vl orig = a;
	int n = a.size();
	vl c(n-1);
	FORR(i,0,n-1){
		c[i] = a[i+1];
		a[i] = (MOD + a[i] + c[i]*b%MOD) % MOD;
	}
	// cerr << __LINE__ << endl;
	// a = orig;
	// debug(a);
	// debug(c);
	// vl po = mymul(c,vl({MOD-b,1}));
	// if(po != a){
	// 	std::cerr << "error" << endl;
	// 	debug(a);
	// 	debug(vl({MOD-b,1}));
	// 	debug(c);
	// 	debug(po);
	// 	std::exit(1);
	// }
	return c;
}

vector<ll> interpo(vector<ll> dat){
	int n = dat.size();
	vector<ll> fact(2*n);
	fact[0] = 1;
	FOR(i,1,2*n)fact[i] = fact[i-1]*i%MOD;
	vl tot(1,1);
	REP(i,n){
		tot = mymul(tot, vl({MOD-i, 1}));
	}
	vl ret(n);
	REP(i,n){
		ll val = dat[i];
		vl pol = mydiv(tot, i);
		ll dv = fact[n-1-i] * fact[i] % MOD;
		if(i%2==1)dv = MOD-dv;
		ll m = val * modpow(dv, MOD-2) % MOD;
		REP(j,n){
			ret[j] += m * pol[j] % MOD;
			ret[j] %= MOD;
		}
	}
	return ret;
}

int main(){
	cin>>n>>s;
	ll ans = 0;
	// naive
	ll total = 0;
	ll inv2 = (MOD+1)/2;

	ans += modpow(s+1,n-1) * s % MOD * inv2 % MOD;
	// DEBUG(ans);
	// naive
	// ll sum = 0;
	// REP(i,10){
	// 	sum += modpow(s-i, n-1) * (i%2==0 ? 1 : MOD-1) % MOD;
	// 	sum %= MOD;
	// 	DEBUG(sum);
	// }

	// polynomial
	const int DEG = 2521;
	{
		vector<ll> dat(DEG);
		ll sum = 0;
		REP(i,DEG){
			sum += modpow(s-i, n-1);// * (i%2==s%2 ? 1 : MOD-1) % MOD;
			sum %= MOD;
			dat[i] = sum;
		}
		vector<ll> coeffs = interpo(dat);

		ll x = 1;
		ll add = 0;
		REP(i,DEG){
			add += coeffs[i] * x % MOD;
			add %= MOD;
			x = x * s % MOD;
		}
		// DEBUG(add);
		ans += MOD-add;
		ans %= MOD;

		// debug(coeffs);
	}
	{
		vector<ll> dat(DEG);
		ll sum = 0;
		REP(i,DEG){
			sum += modpow(s-2*i, n-1);// * (i%2==s%2 ? 1 : MOD-1) % MOD;
			sum %= MOD;
			dat[i] = sum;
		}
		vector<ll> coeffs = interpo(dat);

		ll x = 1;
		ll add = 0;
		REP(i,DEG){
			add += coeffs[i] * x % MOD;
			add %= MOD;
			x = x * (s/2) % MOD;
		}
		// DEBUG(add);
		ans += add * 2ll % MOD;
		ans %= MOD;

		// debug(coeffs);
	}

	printf("%lld\n",ans);
	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 3424
final_rank: 10

code_snippet: #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;
}
accuracy: 1
time_ms: 270
memory_kb: 3240
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
constexpr ll TEN(int n){return (n==0) ? 1 : 10 * TEN(n-1);}
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,N) for(int i=0;i<(int)(N);i++)
#define rep1(i,N) for(int i=1;i<=(int)(N);i++)
#define fs first
#define sc second
#define eb emplace_back
#define pb eb
#define all(x) x.begin(),x.end()
template<class T, class U> void chmin(T& t, const U& u){ if(t>u) t = u;}
template<class T, class U> void chmax(T& t, const U& u){ if(t<u) t = u;}

#ifdef LOCAL
#define show(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define show(x) true
#endif

template<class T,class U>
ostream& operator<<(ostream& os, const pair<T,U>& p){
    return os << "P(" << p.fs << ", " << p.sc << ")";
}
template<class T> ostream& operator<<(ostream& os, const V<T>& v){
    os << "[";
    for(auto d: v) os << d << ", ";
    return os << "]";
}
template<unsigned int mod_>
struct ModInt{
    using M = ModInt;
    constexpr static uint mod = mod_;
    uint v;
    ModInt():v(0){}
    ModInt(ll _v):v(normS(_v%mod+mod)){}
    explicit operator bool() const {return v!=0;}
    static uint normS(const uint&x){return (x<mod)?x:x-mod;}
    static M make(const uint&x){M m;m.v=x;return m;}
    M operator+(const M& b) const {return make(normS(v+b.v));}
    M operator-(const M& b) const {return make(normS(v+mod-b.v));}
    M operator-() const {return make(normS(mod-v));}
    M operator*(const M& b) const {return make((ull)v*b.v%mod);}
    M operator/(const M& b){return *this*b.inv();}
    M& operator+=(const M& b){return *this=*this+b;}
    M& operator-=(const M& b){return *this=*this-b;}
    M& operator*=(const M& b){return *this=*this*b;}
    M& operator/=(const M& b){return *this=*this/b;}
    ll extgcd(ll a,ll b,ll &x,ll& y) const {
        ll p[]={a,1,0},q[]={b,0,1};
        while(*q){
            ll t=*p/ *q;
            rep(i,3) swap(p[i]-=t*q[i],q[i]);
        }
        if(p[0]<0) rep(i,3) p[i] = -p[i];
        x = p[1], y = p[2];
        return p[0];
    }
    ModInt inv() const {
        ll x,y;
        extgcd(v,mod,x,y);
        return make(normS(x+mod));
    }
    M pow(ll p) const {
        if(p<0) return inv().pow(-p);
        M a = 1;
        M x = *this;
        while(p){
            if(p&1) a *= x;
            x *= x;
            p /= 2;
        }
        return a;
    }
    bool operator==(const M& b) const {return v == b.v;}
    bool operator!=(const M& b) const {return v != b.v;}
    friend ostream& operator<<(ostream &o, const M& x){return o<<x.v;}
};
using mint = ModInt<998244353>;

template<class T>
T interpolate(V<T> xs, V<T> ys, T x){
    int N = xs.size();
    rep(i,N){
        if(xs[i] == x) return ys[i];
    }
    T ret = 0;
    rep(i,N){
        T a = ys[i];
        rep(j,N) if(j!=i) a *= (x-xs[j])/(xs[i]-xs[j]);
        ret += a;
    }
    return ret;
}
int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);

    int N,S_;
    cin >> N >> S_;
    mint S(S_);

    mint ans = (S+1)*S/2 * (S+1).pow(N-2);
    {
        V<mint> xs,ys;
        rep(i,N+10){
            int x = i*2 + S_%2;
            mint y = 0;
            for(int m=1;m<=x;m+=2){
                y += mint(x+1-m).pow(N-1) - mint(x-m).pow(N-1);
            }
            xs.pb(x);ys.pb(y);
        }
        ans += interpolate(xs,ys,S);
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 140
memory_kb: 3216
final_rank: 7