Problem: There is a number x initially written on a blackboard. You repeat the following action a fixed amount of times: 

  1. take the number x currently written on a blackboard and erase it 
  2. select an integer uniformly at random from the range [0, x] inclusive, and write it on the blackboard 



Determine the distribution of final number given the distribution of initial number and the number of steps.

Input

The first line contains two integers, N (1 ≤ N ≤ 105) — the maximum number written on the blackboard — and M (0 ≤ M ≤ 1018) — the number of steps to perform.

The second line contains N + 1 integers P0, P1, ..., PN (0 ≤ Pi < 998244353), where Pi describes the probability that the starting number is i. We can express this probability as irreducible fraction P / Q, then <image>. It is guaranteed that the sum of all Pis equals 1 (modulo 998244353).

Output

Output a single line of N + 1 integers, where Ri is the probability that the final number after M steps is i. It can be proven that the probability may always be expressed as an irreducible fraction P / Q. You are asked to output <image>.

Examples

Input

2 1
0 0 1


Output

332748118 332748118 332748118


Input

2 2
0 0 1


Output

942786334 610038216 443664157


Input

9 350
3 31 314 3141 31415 314159 3141592 31415926 314159265 649178508


Output

822986014 12998613 84959018 728107923 939229297 935516344 27254497 413831286 583600448 442738326

Note

In the first case, we start with number 2. After one step, it will be 0, 1 or 2 with probability 1/3 each.

In the second case, the number will remain 2 with probability 1/9. With probability 1/9 it stays 2 in the first round and changes to 1 in the next, and with probability 1/6 changes to 1 in the first round and stays in the second. In all other cases the final integer is 0.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <class T>
void rd(T &x) {
  x = 0;
  long long f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  x = x * f;
}
template <class T>
void output(T x) {
  if (x / 10) output(x / 10);
  putchar(x % 10 + '0');
}
template <class T>
void print(T x) {
  if (x < 0) putchar('-'), x = -x;
  output(x);
  putchar(' ');
}
namespace Basic {
const long long MOD = 998244353;
const long long G = 3;
const long long GI = 332748118;
const long long I = 86583718;
const long long iv2 = 499122177;
const double Pi = acos(-1);
long long qpow(long long x, long long y) {
  long long ret = 1;
  while (y) {
    if (y & 1) ret = (long long)ret * x % MOD;
    x = (long long)x * x % MOD;
    y >>= 1;
  }
  return ret;
}
long long ad(long long x, long long y) {
  return x + y >= MOD ? x + y - MOD : x + y;
}
long long sub(long long x, long long y) { return ad(x, MOD - y); }
long long mul(long long x, long long y) { return (long long)x * y % MOD; }
namespace Polynomial {
struct Poly {
  vector<long long> f;
  Poly() { f.clear(); }
  long long &operator[](const long long &x) { return f[x]; }
  const long long &operator[](const long long &x) const { return f[x]; }
  void resize(const long long &n) { f.resize(n); }
  long long size() const { return f.size(); }
  void cpy(Poly &b) {
    f.resize(b.size());
    for (long long i = 0; i < (long long)f.size(); i++) f[i] = b[i];
  }
  void rev() { reverse(f.begin(), f.end()); }
  void clear() { f.clear(); }
  void read(const long long &n) {
    f.resize(n);
    for (long long i = 0; i < n; i++) rd(f[i]);
  }
  void out() const {
    for (long long i = 0; i < (long long)f.size(); i++) print(f[i]);
    putchar('\n');
  }
} R;
long long init(const long long &n) {
  long long m;
  for (m = 1; m < n;) m <<= 1;
  return m;
}
template <class T>
void rev(T &f) {
  long long lp = f.size();
  if (R.size() != f.size()) {
    R.resize(f.size());
    for (long long i = 0; i < lp; i++) {
      R[i] = (R[i >> 1] >> 1) | ((i & 1) ? lp >> 1 : 0);
    }
  }
  for (long long i = 0; i < lp; i++) {
    if (i < R[i]) swap(f[i], f[R[i]]);
  }
}
}  // namespace Polynomial
using namespace Polynomial;
void operator+=(Poly &f, const Poly &g) {
  for (long long i = 0; i < f.size(); i++) f[i] = ad(f[i], g[i]);
}
void operator+=(Poly &f, const long long &c) { f[0] = ad(f[0], c); }
Poly operator+(Poly f, const Poly &g) {
  for (long long i = 0; i < f.size(); i++) f[i] = ad(f[i], g[i]);
  return f;
}
Poly operator+(Poly f, const long long &c) {
  f[0] = ad(f[0], c);
  return f;
}
void operator-=(Poly &f, const Poly &g) {
  for (long long i = 0; i < f.size(); i++) f[i] = sub(f[i], g[i]);
}
void operator-=(Poly &f, const long long &c) { f[0] = sub(f[0], c); }
Poly operator-(Poly f, const Poly &g) {
  for (long long i = 0; i < f.size(); i++) f[i] = sub(f[i], g[i]);
  return f;
}
Poly operator-(Poly f, const long long &c) {
  f[0] = sub(f[0], c);
  return f;
}
Poly operator-(Poly f) {
  for (long long i = 0; i < f.size(); i++) f[i] = MOD - f[i];
  return f;
}
namespace FastFourierTransform {
struct cplx {
  double x, y;
  cplx() {
    x = 0.0;
    y = 0.0;
  }
  cplx(double xx, double yy) {
    x = xx;
    y = yy;
  }
  cplx friend operator!(cplx a) { return cplx(a.x, -a.y); }
  cplx friend operator+(cplx a, cplx b) { return cplx(a.x + b.x, a.y + b.y); }
  cplx friend operator-(cplx a, cplx b) { return cplx(a.x - b.x, a.y - b.y); }
  cplx friend operator*(cplx a, cplx b) {
    return cplx(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
  }
};
struct Cps {
  vector<cplx> f;
  Cps() { f.clear(); }
  cplx &operator[](const long long &x) { return f[x]; }
  const cplx &operator[](const long long &x) const { return f[x]; }
  void resize(const long long &n) { f.resize(n); }
  long long size() const { return f.size(); }
  void cpy(Cps &b) {
    f.resize(b.size());
    for (long long i = 0; i < (long long)f.size(); i++) f[i] = b[i];
  }
  void rev() { reverse(f.begin(), f.end()); }
  void clear() { f.clear(); }
  void out() {
    for (long long i = 0; i < (long long)f.size(); i++) {
      cout << "(" << f[i].x << "," << f[i].y << ") ";
    }
    cout << endl;
  }
} W;
void FFT(Cps &f, long long c) {
  long long n = f.size();
  rev(f);
  for (long long p = 2; p <= n; p <<= 1) {
    long long len = p / 2;
    for (long long l = 0; l < n; l += p) {
      for (long long k = l; k < l + len; k++) {
        cplx tmp =
            f[k + len] * (c > 0 ? W[n / p * (k - l)] : !W[n / p * (k - l)]);
        f[k + len] = f[k] - tmp;
        f[k] = f[k] + tmp;
      }
    }
  }
  if (c == -1) {
    for (long long i = 0; i < n; i++) {
      f[i].x /= n;
      f[i].y /= n;
    }
  }
}
void prework(long long n) {
  if (W.size() != n) {
    W.resize(n);
    for (long long i = 0; i < n; i++) {
      W[i] = cplx(cos(2 * Pi / n * i), sin(2 * Pi / n * i));
    }
  }
}
Poly MTT(const Poly &F, const Poly &G, const long long &P) {
  long long n = F.size();
  long long m = G.size();
  Cps a, b, c, d;
  long long len = init(n + m - 1);
  a.resize(len);
  b.resize(len);
  c.resize(len);
  d.resize(len);
  for (long long i = 0; i < n; i++) {
    a[i].x = F[i] >> 15;
    a[i].y = F[i] & 32767;
  }
  for (long long i = 0; i < m; i++) {
    b[i].x = G[i] >> 15;
    b[i].y = G[i] & 32767;
  }
  prework(len);
  FFT(a, 1);
  FFT(b, 1);
  cplx ka, kb, ba, bb;
  cplx aaa = cplx(0.5, 0);
  cplx bbb = cplx(0, -0.5);
  cplx o = cplx(0, 1);
  for (long long i = 0; i < len; i++) {
    long long j = (len - i) % len;
    ka = (a[i] + !a[j]) * aaa;
    ba = (a[i] - !a[j]) * bbb;
    kb = (b[i] + !b[j]) * aaa;
    bb = (b[i] - !b[j]) * bbb;
    c[i] = ka * kb + ba * kb * o;
    d[i] = bb * ka + bb * ba * o;
  }
  FFT(c, -1);
  FFT(d, -1);
  Poly ret;
  ret.resize(n + m - 1);
  for (long long i = 0; i < n + m - 1; i++) {
    long long A = (long long)(c[i].x + 0.5) % P;
    long long B = (long long)(c[i].y + 0.5) % P;
    long long C = (long long)(d[i].x + 0.5) % P;
    long long D = (long long)(d[i].y + 0.5) % P;
    ret[i] = ((((A << 30) % P) + ((B + C) << 15) % P) % P + D) % P;
  }
  return ret;
}
void operator*=(Poly &f, Poly g) { f = MTT(f, g, MOD); }
void operator*=(Poly &f, const long long &c) {
  for (long long i = 0; i < f.size(); i++) f[i] = mul(f[i], c);
}
Poly operator*(Poly f, const Poly &g) {
  f *= g;
  return f;
}
Poly operator*(Poly f, const long long &c) {
  for (long long i = 0; i < f.size(); i++) f[i] = mul(f[i], c);
  return f;
}
Poly Inv(const Poly &f, long long n) {
  if (n == 1) {
    Poly g;
    g.resize(1);
    g[0] = qpow(f[0], MOD - 2);
    return g;
  }
  Poly h = Inv(f, (n + 1) >> 1);
  Poly tmp = h;
  Poly t;
  t.resize(n);
  for (long long i = 0; i < n; i++) t[i] = f[i];
  tmp = tmp * tmp * t;
  h.resize(tmp.size());
  Poly g = h * 2 - tmp;
  g.resize(n);
  return g;
}
}  // namespace FastFourierTransform
void NTT(Poly &f, long long c) {
  long long n = f.size();
  rev(f);
  for (long long p = 2; p <= n; p <<= 1) {
    long long gen = (c == 1) ? qpow(G, (MOD - 1) / p) : qpow(GI, (MOD - 1) / p);
    for (long long l = 0; l < n; l += p) {
      long long buf = 1;
      for (long long k = l; k < l + p / 2; ++k) {
        long long tmp = mul(f[k + p / 2], buf);
        f[k + p / 2] = sub(f[k], tmp);
        f[k] = ad(f[k], tmp);
        buf = mul(buf, gen);
      }
    }
  }
  if (c == -1) {
    long long iv = qpow(n, MOD - 2);
    for (long long i = 0; i < n; i++) f[i] = mul(f[i], iv);
  }
}
Poly Inv(const Poly &f, long long n) {
  if (n == 1) {
    Poly g;
    g.resize(1);
    g[0] = qpow(f[0], MOD - 2);
    return g;
  }
  Poly g = Inv(f, (n + 1) >> 1), t;
  long long m = init(n * 2);
  t.resize(m);
  for (long long i = 0; i < n; i++) t[i] = f[i];
  g.resize(m);
  NTT(g, 1);
  NTT(t, 1);
  for (long long i = 0; i < m; i++) g[i] = mul(sub(2, mul(g[i], t[i])), g[i]);
  NTT(g, -1);
  g.resize(n);
  return g;
}
void operator*=(Poly &f, Poly g) {
  long long st = f.size() + g.size() - 1;
  long long len = init(f.size() + g.size() - 1);
  f.resize(len);
  g.resize(len);
  NTT(f, 1);
  NTT(g, 1);
  for (long long i = 0; i < len; i++) f[i] = mul(f[i], g[i]);
  NTT(f, -1);
  f.resize(st);
}
void operator*=(Poly &f, const long long &c) {
  for (long long i = 0; i < f.size(); i++) f[i] = mul(f[i], c);
}
Poly operator*(Poly f, const Poly &g) {
  f *= g;
  return f;
}
Poly operator*(Poly f, const long long &c) {
  for (long long i = 0; i < f.size(); i++) f[i] = mul(f[i], c);
  return f;
}
Poly operator~(const Poly &f) { return Inv(f, f.size()); }
Poly operator/(Poly f, Poly g) {
  long long len = f.size() - g.size() + 1;
  f.rev();
  g.rev();
  g.resize(len);
  f = f * (~g);
  f.resize(len);
  f.rev();
  return f;
}
Poly operator%(Poly f, Poly g) {
  Poly s = f / g;
  f = f - g * s;
  f.resize(g.size() - 1);
  return f;
}
Poly Inter(Poly f) {
  long long st = f.size();
  f.resize(st + 1);
  for (long long i = st; i >= 1; i--) f[i] = mul(f[i - 1], qpow(i, MOD - 2));
  f[0] = 0;
  return f;
}
Poly Diff(Poly f) {
  long long st = f.size();
  for (long long i = 0; i < st - 1; i++) f[i] = mul(f[i + 1], (i + 1));
  f.resize(st - 1);
  return f;
}
}  // namespace Basic
using namespace Basic;
namespace Extended {
Poly Ln(const Poly &f) {
  Poly g = Diff(f);
  Poly h = (~f);
  g = g * h;
  g.resize(f.size() - 1);
  return Inter(g);
}
Poly Exp(const Poly &f, long long n) {
  if (n == 1) {
    Poly g;
    g.resize(1);
    g[0] = 1;
    return g;
  }
  Poly g = Exp(f, (n + 1) >> 1);
  g.resize(n);
  g = g * (((Ln(g) * (MOD - 1)) + 1) + f);
  g.resize(n);
  return g;
}
Poly Exp(const Poly &f) { return Exp(f, f.size()); }
Poly Cos(const Poly &f) {
  Poly g = Exp(f * I);
  return (g + (~g)) * iv2;
}
Poly Sin(const Poly &f) {
  Poly g = Exp(f * I);
  return (g - (~g)) * qpow(ad(I, I), MOD - 2);
}
Poly Pow(const Poly &f, long long k) { return Exp(Ln(f) * k); }
Poly Sqrt(const Poly &f, long long n) {
  if (n == 1) {
    Poly g;
    g.resize(1);
    g[0] = 1;
    return g;
  }
  Poly h = Sqrt(f, (n + 1) >> 1);
  h.resize(n);
  Poly g = (h * iv2) + f * (~h) * iv2;
  g.resize(n);
  return g;
}
Poly Sqrt(const Poly &f) { return Sqrt(f, f.size()); }
Poly Sinh(const Poly &f) {
  long long N = f.size();
  Poly h = Sqrt(f * f * (-1) + 1);
  h.resize(N);
  Poly g = Diff(f) * (~h);
  return Inter(g);
}
Poly Tanh(const Poly &f) {
  Poly g = Diff(f) * (~(f * f + 1));
  return Inter(g);
}
}  // namespace Extended
using namespace Extended;
long long pre[200005];
signed main() {
  pre[0] = 1;
  for (long long i = 1; i <= 200000; i++) pre[i] = pre[i - 1] * i % MOD;
  long long n, m;
  scanf("%lld%lld", &n, &m);
  Poly x, y, z;
  x.resize(n + 1);
  y.resize(n + 1);
  for (long long i = 0; i <= n; i++) {
    long long a;
    scanf("%lld", &a);
    x[n - i] = a * pre[i] % MOD;
    y[i] = qpow(pre[i], MOD - 2);
  }
  x *= y;
  x.resize(n + 1);
  y.resize(n + 1);
  for (long long i = 0; i <= n; i++) {
    y[i] = qpow(pre[i], MOD - 2) * x[n - i] % MOD;
  }
  for (long long i = 0; i <= n; i++) {
    x[i] = y[i] * qpow(qpow(i + 1, MOD - 2), m) % MOD;
  }
  z.resize(n + 1);
  for (long long i = 0; i <= n; i++) {
    y[i] = qpow(pre[i], MOD - 2) * qpow(MOD - 1, i) % MOD;
    z[n - i] = x[i] * pre[i] % MOD;
  }
  z *= y;
  z.resize(n + 1);
  for (long long i = 0; i <= n; i++) {
    x[i] = qpow(pre[i], MOD - 2) * z[n - i] % MOD;
  }
  for (long long i = 0; i <= n; i++) printf("%lld ", x[i]);
}