Problem: PolandBall is standing in a row with Many Other Balls. More precisely, there are exactly n Balls. Balls are proud of their home land — and they want to prove that it's strong.

The Balls decided to start with selecting exactly m groups of Balls, each consisting either of single Ball or two neighboring Balls. Each Ball can join no more than one group.

The Balls really want to impress their Enemies. They kindly asked you to calculate number of such divisions for all m where 1 ≤ m ≤ k. Output all these values modulo 998244353, the Enemies will be impressed anyway.

Input

There are exactly two numbers n and k (1 ≤ n ≤ 109, 1 ≤ k < 215), denoting the number of Balls and the maximim number of groups, respectively.

Output

You should output a sequence of k values. The i-th of them should represent the sought number of divisions into exactly i groups, according to PolandBall's rules.

Examples

Input

3 3


Output

5 5 1 

Input

1 1


Output

1 

Input

5 10


Output

9 25 25 9 1 0 0 0 0 0 

Note

In the first sample case we can divide Balls into groups as follows: 

{1}, {2}, {3}, {12}, {23}.

{12}{3}, {1}{23}, {1}{2}, {1}{3}, {2}{3}.

{1}{2}{3}.

Therefore, output is: 5 5 1.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using int64 = long long;
using uchar = unsigned char;
constexpr int mxdg(65536);
constexpr int p(998244353);
constexpr int proot(3);
inline int io() {
  static int _;
  return scanf("%d", &_), _;
}
namespace math_template {
using Z = int;
using mZ = long long;
template <class _Tp>
inline void swap(_Tp& x, _Tp& y) {
  _Tp z = x;
  x = y;
  y = z;
}
template <class _Tp>
inline Z fpow(_Tp v, int n) {
  Z pw = 1;
  for (; n; n >>= 1, v = (mZ)v * v % p)
    if (n & 1) pw = (mZ)pw * v % p;
  return pw;
}
template <class x_tp, class y_tp>
inline void inc(x_tp& x, const y_tp& y) {
  (p - y <= x) ? (x += y - p) : (x += y);
}
template <class x_tp, class y_tp>
inline void dec(x_tp& x, const y_tp& y) {
  x -= y;
  (x < 0) && (x += p);
}
template <class x_tp, class y_tp>
inline x_tp pls(const x_tp& x, const y_tp& y) {
  return (x < p - y) ? (x + y) : (x - p + y);
}
template <class x_tp, class y_tp>
inline x_tp sub(const x_tp& x, const y_tp& y) {
  return (x < y) ? (x - y + p) : (x - y);
}
template <class _Tp>
inline _Tp gcd(const _Tp& x, const _Tp& y) {
  return y ? gcd(y, x % y) : x;
}
template <class _Tp>
inline _Tp lcm(const _Tp& x, const _Tp& y) {
  return x / gcd(x, y) * y;
}
template <class _Tp, class x_tp>
inline void exgcd(const _Tp& x, const _Tp& y, x_tp& a, x_tp& b) {
  if (y)
    exgcd(y, x % y, b, a), b -= x / y * a;
  else
    a = 1, b = 0;
}
inline Z inv(const Z& v, const Z& mp) {
  Z x, y;
  exgcd(v, mp, x, y);
  return x < 0 ? x + mp : x;
}
template <class _Tp>
inline Z div2(const _Tp& v) {
  return (v & 1) ? (v + p) >> 1 : (v >> 1);
}
template <class x_tp, class y_tp>
inline x_tp Min(const x_tp& x, const y_tp& y) {
  return x < y ? x : y;
}
template <class x_tp, class y_tp>
inline x_tp Max(const x_tp& x, const y_tp& y) {
  return x > y ? x : y;
}
template <class x_tp, class y_tp>
inline void chkMin(x_tp& x, const y_tp& y) {
  (x > y) && (x = y);
}
template <class x_tp, class y_tp>
inline void chkMax(x_tp& x, const y_tp& y) {
  (x < y) && (x = y);
}
template <class x_tp, class y_tp>
inline bool bchkMin(x_tp& x, const y_tp& y) {
  return (x > y) && (x = y, 1);
}
template <class x_tp, class y_tp>
inline bool bchkMax(x_tp& x, const y_tp& y) {
  return (x < y) && (x = y, 1);
}
}  // namespace math_template
namespace Hashmap {
using namespace math_template;
template <class key_tp, class val_tp>
struct link_t {
  key_tp key;
  val_tp val;
  link_t<key_tp, val_tp>* las;
  link_t() : key(key_tp(0)), val(val_tp(0)), las(nullptr) {}
  inline link_t* init(const key_tp& _key, const val_tp& _val,
                      link_t<key_tp, val_tp>* const& ls) {
    return key = _key, val = _val, las = ls, this;
  }
};
link_t<Z, Z> lnk_pool[100007 * 10];
template <class key_tp, class val_tp>
struct hashmap {
  static constexpr int hashp = 100007;
  using link = link_t<key_tp, val_tp>;
  link *lnk[hashp], *lnk_alc;
  hashmap() : lnk_alc(lnk_pool - 1) {}
  inline val_tp& operator[](const key_tp& key) {
    const val_tp hash_key = key % hashp;
    for (link* o = lnk[hash_key]; o; o = o->las)
      if (o->key == key) return o->val;
    lnk[hash_key] = (++lnk_alc)->init(key, 0, lnk[hash_key]);
    return lnk[hash_key]->val;
  }
  inline bool count(const key_tp& key) {
    const val_tp hash_key = key % hashp;
    for (link* o = lnk[hash_key]; o; o = o->las)
      if (o->key == key) return true;
    return false;
  }
  inline void clear() {
    lnk_alc = lnk_pool - 1;
    memset(lnk, 0, sizeof lnk);
  }
};
}  // namespace Hashmap
namespace poly {
using namespace math_template;
using namespace Hashmap;
using poly_t = Z[mxdg];
using poly = Z* const;
inline int calcpw2(const int& n) {
  int pw2 = 1;
  for (; pw2 < n; pw2 += pw2)
    ;
  return pw2;
}
poly_t wn, iwn;
Z inv[mxdg + 1];
constexpr int rt_blk(31596);
constexpr int invpw_blk(393213064);
Hashmap::hashmap<Z, Z> lg;
inline void polyinit() {
  const Z wnv = fpow(proot, (p - 1) / mxdg);
  const Z iwnv = fpow(wnv, p - 2);
  wn[0] = iwn[0] = inv[0] = inv[1] = 1;
  Z w = 1, iw = 1, b = 1;
  for (int i = 1; i != mxdg; ++i) {
    w = (mZ)w * wnv % p;
    wn[i] = w;
    iw = (mZ)iw * iwnv % p;
    iwn[i] = iw;
  }
  for (int i = 2; i <= mxdg; ++i) inv[i] = (mZ)inv[p % i] * (p - p / i) % p;
  for (int t = 0; t < rt_blk; ++t, b = (mZ)b * proot % p) lg[b] = t;
}
inline int root(const Z& v, const int& k) {
  if (k == 1 || v < 2) return v;
  Z pw = v;
  for (int t = 0; t < p; t += rt_blk, pw = (mZ)pw * invpw_blk % p)
    if (lg.count(pw))
      return fpow(proot,
                  (mZ)(t + lg[pw]) * math_template::inv(k, p - 1) % (p - 1));
  return -1;
}
void DFT(poly& A, const int& n) {
  for (int i = 0, j = 0; i != n; ++i) {
    if (i < j) swap(A[i], A[j]);
    for (int k = n >> 1; (j ^= k) < k; k >>= 1)
      ;
  }
  Z* const td = A + n;
  for (int l = 1, tp = mxdg >> 1; l != n; l += l, tp >>= 1)
    for (Z *i = A, *w, z; i < td; i += l + l)
      for (int j = (w = wn, 0); j != l; ++j, w += tp)
        z = (mZ)i[j + l] * *w % p, i[j + l] = sub(i[j], z), inc(i[j], z);
}
void IDFT(poly& A, const int& n) {
  for (int i = 0, j = 0; i != n; ++i) {
    if (i < j) swap(A[i], A[j]);
    for (int k = n >> 1; (j ^= k) < k; k >>= 1)
      ;
  }
  Z* const td = A + n;
  for (int l = 1, tp = mxdg >> 1; l != n; l += l, tp >>= 1)
    for (Z *i = A, *w, z; i < td; i += l + l)
      for (int j = (w = iwn, 0); j != l; ++j, w += tp)
        z = (mZ)i[j + l] * *w % p, i[j + l] = sub(i[j], z), inc(i[j], z);
  const Z invn = fpow(n, p - 2);
  for (Z* i = A; i != td; ++i) *i = (mZ)*i * invn % p;
}
inline void cp(const Z* const& sl, const Z* const& sr, Z* const& dl,
               Z* const& dr) {
  std::copy(sl, sr, dl);
  if (sr - sl < dr - dl) std::fill(dl + (sr - sl), dr, 0);
}
void polyder(const poly& f, poly& df, const int& n) {
  for (int i = 1; i != n; ++i) df[i - 1] = (mZ)f[i] * i % p;
  df[n - 1] = 0;
}
void polyint(const poly& f, poly& intf, const int& n) {
  for (int i = n - 1; i; --i) intf[i] = (mZ)f[i - 1] * inv[i] % p;
  intf[0] = 0;
}
void polyinv(const poly& h, poly& f, const int& n) {
  static poly_t inv_t;
  std::fill(f, f + n + n, 0);
  f[0] = fpow(h[0], p - 2);
  for (int t = 1; (1 << t) <= n; ++t) {
    const int deg1 = 1 << t, deg2 = deg1 << 1;
    cp(h, h + deg1, inv_t, inv_t + deg2);
    DFT(f, deg2);
    DFT(inv_t, deg2);
    for (int i = 0; i != deg2; ++i)
      f[i] = (mZ)f[i] * sub(2ll, (mZ)inv_t[i] * f[i] % p) % p;
    IDFT(f, deg2);
    std::fill(f + deg1, f + deg2, 0);
  }
}
void polyln(const poly& h, poly& f, const int& n) {
  static poly_t ln_t;
  assert(h[0] == 1);
  const int n2 = n << 1;
  polyder(h, f, n);
  std::fill(f + n, f + n2, 0);
  polyinv(h, ln_t, n);
  DFT(f, n2);
  DFT(ln_t, n2);
  for (int i = 0; i != n2; ++i) f[i] = (mZ)f[i] * ln_t[i] % p;
  IDFT(f, n2);
  polyint(f, f, n);
  std::fill(f + n, f + n2, 0);
}
void polyexp(const poly& h, poly& f, const int& n) {
  static poly_t exp_t;
  assert(h[0] == 0);
  std::fill(f, f + n + n, 0);
  f[0] = 1;
  for (int t = 1; (1 << t) <= n; ++t) {
    const int deg1 = 1 << t, deg2 = deg1 << 1;
    polyln(f, exp_t, deg1);
    exp_t[0] = sub(h[0] + 1, exp_t[0]);
    for (int i = 1; i != deg1; ++i) exp_t[i] = sub(h[i], exp_t[i]);
    std::fill(exp_t + deg1, exp_t + deg2, 0);
    DFT(f, deg2);
    DFT(exp_t, deg2);
    for (int i = 0; i != deg2; ++i) f[i] = (mZ)f[i] * exp_t[i] % p;
    IDFT(f, deg2);
    std::fill(f + deg1, f + deg2, 0);
  }
}
void polydiv(const poly& f, const int& n, const poly& g, const int& m, poly& Q,
             poly& R) {
  static poly_t div_t;
  const int res = n - m + 1;
  const int deg1 = calcpw2(res + res);
  std::reverse_copy(g, g + m, Q);
  if (m < deg1) std::fill(Q + m, Q + deg1, 0);
  polyinv(Q, div_t, res);
  std::reverse_copy(f + m - 1, f + n, Q);
  std::fill(Q + res, Q + deg1, 0);
  DFT(Q, deg1);
  DFT(div_t, deg1);
  for (int i = 0; i != deg1; ++i) Q[i] = (mZ)Q[i] * div_t[i] % p;
  IDFT(Q, deg1);
  std::reverse(Q, Q + res);
  std::fill(Q + res, Q + deg1, 0);
  const int deg2 = calcpw2(n);
  cp(Q, Q + res, R, R + deg2);
  cp(g, g + m, div_t, div_t + deg2);
  DFT(R, deg2);
  DFT(div_t, deg2);
  for (int i = 0; i != deg2; ++i) R[i] = (mZ)R[i] * div_t[i] % p;
  IDFT(R, deg2);
  for (int i = 0; i != m; ++i) R[i] = sub(f[i], R[i]);
  std::fill(R + m - 1, R + deg2, 0);
}
void polymod(const poly& f, const int& n, const poly& g, const int& m,
             poly& R) {
  static poly_t mod_t;
  const int res = n - m + 1;
  const int deg1 = calcpw2(res + res);
  std::reverse_copy(g, g + m, R);
  if (m < deg1) std::fill(R + m, R + deg1, 0);
  polyinv(R, mod_t, res);
  std::reverse_copy(f + m - 1, f + n, R);
  std::fill(R + res, R + deg1, 0);
  DFT(R, deg1);
  DFT(mod_t, deg1);
  for (int i = 0; i != deg1; ++i) R[i] = (mZ)R[i] * mod_t[i] % p;
  IDFT(R, deg1);
  std::reverse(R, R + res);
  std::fill(R + res, R + deg1, 0);
  const int deg2 = calcpw2(n);
  cp(g, g + m, mod_t, mod_t + deg2);
  DFT(R, deg2);
  DFT(mod_t, deg2);
  for (int i = 0; i != deg2; ++i) R[i] = (mZ)R[i] * mod_t[i] % p;
  IDFT(R, deg2);
  for (int i = 0; i != m; ++i) R[i] = sub(f[i], R[i]);
  std::fill(R + m - 1, R + deg2, 0);
}
void polysqrt(const poly& h, poly& f, const int& n) {
  static poly_t sqrt_t, inv_t;
  std::fill(f, f + n + n, 0);
  f[0] = root(h[0], 2);
  for (int t = 1; (1 << t) <= n; ++t) {
    const int deg1 = 1 << t, deg2 = deg1 << 1;
    polyinv(f, inv_t, deg1);
    cp(h, h + deg1, sqrt_t, sqrt_t + deg2);
    DFT(sqrt_t, deg2);
    DFT(inv_t, deg2);
    for (int i = 0; i != deg2; ++i) sqrt_t[i] = (mZ)inv_t[i] * sqrt_t[i] % p;
    IDFT(sqrt_t, deg2);
    for (int i = deg1 >> 1; i != deg1; ++i) f[i] = div2(sqrt_t[i]);
    std::fill(f + deg1, f + deg2, 0);
  }
}
void polycbrt(const poly& h, poly& f, const int& n) {
  static constexpr int inv3(332748118);
  static poly_t cbrt_t, inv_t;
  std::fill(f, f + n + n, 0);
  f[0] = root(h[0], 3);
  for (int t = 1; (1 << t) <= n; ++t) {
    const int deg1 = 1 << t, deg2 = deg1 << 1;
    cp(f, f + (deg1 >> 1), cbrt_t, cbrt_t + deg2);
    DFT(cbrt_t, deg1);
    Z* const td = cbrt_t + deg1;
    for (Z* i = cbrt_t; i != td; ++i) *i = (mZ)*i * *i % p;
    IDFT(cbrt_t, deg1);
    polyinv(cbrt_t, inv_t, deg1);
    cp(h, h + deg1, cbrt_t, cbrt_t + deg2);
    DFT(cbrt_t, deg2);
    DFT(inv_t, deg2);
    for (int i = 0; i != deg2; ++i) cbrt_t[i] = (mZ)cbrt_t[i] * inv_t[i] % p;
    IDFT(cbrt_t, deg2);
    for (int i = deg1 >> 1; i != deg1; ++i)
      f[i] = (mZ)(f[i] + f[i] + cbrt_t[i]) * inv3 % p;
  }
}
void polypow(const poly& h, poly& f, const int& k, const int& n) {
  static poly_t pow_t;
  if (h[0] == 1) {
    polyln(h, pow_t, n);
    Z* const td = pow_t;
    for (Z* i = pow_t; i != td; ++i) *i = (mZ)*i * k % p;
    polyexp(pow_t, f, n);
  } else {
    int lw = 0;
    for (; !h[lw]; ++lw)
      ;
    if (n <= lw * k) return std::fill(f, f + n, 0);
    const int low = lw;
    const Z ilowc = fpow(h[low], p - 2);
    for (int i = 0; i != n - low; ++i) pow_t[i] = (mZ)h[i + low] * ilowc % p;
    std::fill(pow_t + n - low, pow_t + n, 0);
    polyln(pow_t, f, n);
    Z* const td = f + n;
    for (Z* i = f; i != td; ++i) *i = (mZ)*i * k % p;
    polyexp(f, pow_t, n);
    const int pwlow = low * k;
    const Z pwlowc = fpow(h[low], k);
    for (int i = 0; i != n - pwlow; ++i)
      f[i + pwlow] = (mZ)pow_t[i] * pwlowc % p;
    std::fill(f, f + pwlow, 0);
  }
}
void polyroot(const poly& h, poly& f, const int& k, const int& n) {
  static poly_t root_t;
  const int invk(fpow(k, p - 2));
  if (h[0] == 1) {
    polyln(h, root_t, n);
    Z* const td = root_t + n;
    for (Z* i = root_t; i != td; ++i) *i = (mZ)*i * invk % p;
    polyexp(root_t, f, n);
  } else {
    int lw = 0;
    for (; !h[lw]; ++lw)
      ;
    assert(lw % k == 0);
    const int low = lw;
    const Z ilowc = fpow(h[low], p - 2);
    for (int i = 0; i != n - low; ++i) root_t[i] = (mZ)h[i + low] * ilowc % p;
    std::fill(root_t + n - low, root_t + n, 0);
    polyln(root_t, f, n);
    Z* const td = f + n;
    for (Z* i = f; i != td; ++i) *i = (mZ)*i * invk % p;
    polyexp(f, root_t, n);
    const int pwlow = low / k;
    const Z pwlowc = root(h[low], k);
    for (int i = 0; i != n - pwlow; ++i)
      f[i + pwlow] = (mZ)root_t[i] * pwlowc % p;
    std::fill(f, f + pwlow, 0);
  }
}
}  // namespace poly
using namespace poly;
poly_t f, g, rt, invrt;
int main() {
  polyinit();
  const int n = io() + 1, k = io() + 1, deg = 32768, deg2 = deg + deg;
  f[0] = 1;
  f[1] = 6;
  f[2] = 1;
  polysqrt(f, rt, deg);
  polyinv(rt, invrt, deg);
  g[0] = div2(rt[0] + 1);
  g[1] = div2(rt[1] + 1);
  for (int i = 2; i != deg; ++i) g[i] = div2(rt[i]);
  polyln(g, f, deg);
  for (int i = 0; i != deg; ++i) f[i] = (int64)f[i] * n % p;
  polyexp(f, g, deg);
  DFT(g, deg2);
  DFT(invrt, deg2);
  for (int i = 0; i != deg2; ++i) g[i] = (int64)g[i] * invrt[i] % p;
  IDFT(g, deg2);
  const int lw = Min(n, k);
  for (int i = 1; i != lw; ++i) printf("%d ", g[i]);
  for (int i = lw; i != k; ++i) putchar('0'), putchar(' ');
  return 0;
}