#line 1 "..\\Main.cpp" #include #include #include #include #include #line 3 "D:\\Programming\\VSCode\\competitive-cpp\\nachia\\math\\combination.hpp" namespace nachia{ template class Comb{ private: static constexpr int MOD = Modint::mod(); std::vector F; std::vector iF; public: void extend(int newN){ int prevN = (int)F.size() - 1; if(newN >= MOD) newN = MOD - 1; if(prevN >= newN) return; F.resize(newN+1); iF.resize(newN+1); for(int i=prevN+1; i<=newN; i++) F[i] = F[i-1] * Modint::raw(i); iF[newN] = F[newN].inv(); for(int i=newN; i>prevN; i--) iF[i-1] = iF[i] * Modint::raw(i); } Comb(int n = 1){ F.assign(2, Modint(1)); iF.assign(2, Modint(1)); extend(n); } Modint factorial(int n) const { return F[n]; } Modint invFactorial(int n) const { return iF[n]; } Modint invOf(int n) const { return iF[n] * F[n-1]; } Modint comb(int n, int r) const { if(n < 0 || n < r || r < 0) return Modint(0); return F[n] * iF[r] * iF[n-r]; } Modint invComb(int n, int r) const { if(n < 0 || n < r || r < 0) return Modint(0); return iF[n] * F[r] * F[n-r]; } Modint perm(int n, int r) const { if(n < 0 || n < r || r < 0) return Modint(0); return F[n] * iF[n-r]; } Modint invPerm(int n, int r) const { if(n < 0 || n < r || r < 0) return Modint(0); return iF[n] * F[n-r]; } Modint operator()(int n, int r) const { return comb(n,r); } }; } // namespace nachia #line 7 "..\\Main.cpp" using Modint = atcoder::static_modint<998244353>; using namespace std; using i64 = long long; using u64 = unsigned long long; #define rep(i,n) for(int i=0; i<(int)(n); i++) const i64 INF = 1001001001001001001; struct F{ Modint a,b,c; }; F operator+(F l, F r){ return { l.a+r.a, l.b+r.b, l.c+r.c }; } F operator*(F l, F r){ return { l.a*r.a + l.b*r.c + l.c*r.b, l.a*r.b + l.b*r.a + l.c*r.c, l.a*r.c + l.b*r.b + l.c*r.a }; } F Omega(i64 t){ t %= 3; t += 3; t %= 3; if(t == 0) return { 1, 0, 0 }; if(t == 1) return { 0, 1, 0 }; return { 0, 0, 1 }; } F powMod(F a, i64 i){ if(i == 0) return {1,0,0}; F f = powMod(a*a, i/2); if(i%2 == 1) f = f * a; return f; } ostream& operator<<(ostream& ostr, F f){ return ostr << "(" << f.a.val() << ' ' << f.b.val() << ' ' << f.c.val() << ")"; } void testcase(){ auto comb = nachia::Comb(1000); i64 N, M; cin >> N >> M; F Q = {0,0,0}; for(i64 a=0; a<=M; a++) for(i64 b=0; a+b<=M; b++){ i64 c = M - a - b; F ex = { a, b, c }; //cout << "ex = " << ex << endl; ex = powMod(ex, N); //cout << "pow ex = " << ex << endl; F t = F{ comb.factorial(M) / comb.factorial(a) / comb.factorial(b) / comb.factorial(c), 0, 0 }; Q = Q + ex * t * Omega(b+b+c); } //cout << Q.a.val() << " " << Q.b.val() << " " << Q.c.val() << endl; Modint ans = (Q.a - (Q.b + Q.c) / 2) / Modint(3).pow(M); cout << ans.val() << endl; } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); //int T; cin >> T; rep(t,T) testcase(); return 0; }