#include #include #define rep(i,n) for(int i=0;i vi; typedef vector vl; typedef vector> vvi; typedef vector> vvl; typedef long double ld; typedef pair P; template ostream& operator<<(ostream& os, const static_modint& a) {os << a.val(); return os;} template ostream& operator<<(ostream& os, const dynamic_modint& a) {os << a.val(); return os;} template istream& operator>>(istream& is, static_modint& a) {long long x; is >> x; a = x; return is;} template istream& operator>>(istream& is, dynamic_modint& a) {long long x; is >> x; a = x; return is;} template istream& operator>>(istream& is, vector& v){int n = v.size(); assert(n > 0); rep(i, n) is >> v[i]; return is;} template ostream& operator<<(ostream& os, const pair& p){os << p.first << ' ' << p.second; return os;} template ostream& operator<<(ostream& os, const vector& v){int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? "\n" : " "); return os;} template ostream& operator<<(ostream& os, const vector>& v){int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? "\n" : ""); return os;} template ostream& operator<<(ostream& os, const set& se){for(T x : se) os << x << " "; os << "\n"; return os;} template ostream& operator<<(ostream& os, const unordered_set& se){for(T x : se) os << x << " "; os << "\n"; return os;} template ostream& operator<<(ostream& os, const atcoder::segtree& seg){int n = seg.max_right(0, [](S){return true;}); rep(i, n) os << seg.get(i) << (i == n - 1 ? "\n" : " "); return os;} template ostream& operator<<(ostream& os, const atcoder::lazy_segtree& seg){int n = seg.max_right(0, [](S){return true;}); rep(i, n) os << seg.get(i) << (i == n - 1 ? "\n" : " "); return os;} template void chmin(T& a, T b){a = min(a, b);} template void chmax(T& a, T b){a = max(a, b);} using mint = modint998244353; // combination mod prime // https://youtu.be/8uowVvQ_-Mo?t=6002 // https://youtu.be/Tgd_zLfRZOQ?t=9928 struct modinv { int n; vector d; modinv(): n(2), d({0,1}) {} mint operator()(int i) { while (n <= i) d.push_back(-d[mint::mod()%n]*(mint::mod()/n)), ++n; return d[i]; } mint operator[](int i) const { return d[i];} } invs; struct modfact { int n; vector d; modfact(): n(2), d({1,1}) {} mint operator()(int i) { while (n <= i) d.push_back(d.back()*n), ++n; return d[i]; } mint operator[](int i) const { return d[i];} } facts; struct modfactinv { int n; vector d; modfactinv(): n(2), d({1,1}) {} mint operator()(int i) { while (n <= i) d.push_back(d.back()*invs(n)), ++n; return d[i]; } mint operator[](int i) const { return d[i];} } ifacts; mint comb(int n, int k) { if (n < k || k < 0) return 0; return facts(n)*ifacts(k)*ifacts(n-k); } mint c = 5; template struct Ring{ mint p, q; Ring(mint p = 0, mint q = 0) : p(p), q(q) {} bool operator==(const Ring & r) const{return p == r.p && q == r.q;} bool operator!=(const Ring & r) const{return p != r.p || q != r.q;} Ring operator+(const Ring &r) const { return Ring(*this) += r; } Ring operator-(const Ring &r) const { return Ring(*this) -= r; } Ring operator*(const Ring &r) const { return Ring(*this) *= r; } Ring operator/(const Ring &r) const { return Ring(*this) /= r; } Ring &operator+=(const Ring &r) { return *this = Ring(p + r.p, q + r.q); } Ring &operator-=(const Ring &r) { return *this = Ring(p - r.p, q - r.q); } Ring &operator*=(const Ring &r) { return *this = Ring(p * r.p + c * q * r.q, p * r.q + q * r.p); } Ring &operator/=(const Ring &r) { *this *= r.inv(); return *this; } Ring inv() const{ Ring res(p / (p * p - c * q * q), -q / (p * p - c * q * q)); return res; } Ring pow(long long n) const { assert(0 <= n); Ring x = *this, r(1, 0); while (n) { if (n & 1) r *= x; x *= x; n >>= 1; } return r; } }; template ostream& operator<<(ostream& os, const Ring& r){os << r.p << ':' << r.q; return os;} using R = Ring; int main(){ long long n; int k; cin >> n >> k; R sum(0, 0); mint half = mint(1) / 2; for(int i = 0; i <= k; i++){ R v = R(half, half).pow(i) * R(half, -half).pow(k - i); if(v == R(1, 0)){ sum += R(n, 0) * mint(-1).pow(k - i) * comb(k, i); }else{ sum += (R(1, 0) - v.pow(n)) / (R(1, 0) - v) * v * mint(-1).pow(k - i) * comb(k, i); } } sum /= R(0, 1).pow(k); cout << sum.p << "\n"; return 0; }