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.
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
namespace _buff {
const size_t BUFF = 1 << 19;
char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
char getc() {
  if (ib == ie) {
    ib = ibuf;
    ie = ibuf + fread(ibuf, 1, BUFF, stdin);
  }
  return ib == ie ? -1 : *ib++;
}
}  // namespace _buff
LL read() {
  using namespace _buff;
  LL ret = 0;
  bool pos = true;
  char c = getc();
  for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
    assert(~c);
  }
  if (c == '-') {
    pos = false;
    c = getc();
  }
  for (; c >= '0' && c <= '9'; c = getc()) {
    ret = (ret << 3) + (ret << 1) + (c ^ 48);
  }
  return pos ? ret : -ret;
}
using uint = unsigned;
const int MOD = 998244353;
using Poly = vector<int>;
void iadd(int &dp, const int &val) {
  dp += val;
  if (dp >= MOD) {
    dp -= MOD;
  }
}
void ladd(int &dp, const LL &val) { dp = (dp + val) % MOD; }
int qpow(int base, int e) {
  int ret = 1;
  for (; e; e >>= 1) {
    if (e & 1) {
      ret = (LL)ret * base % MOD;
    }
    base = (LL)base * base % MOD;
  }
  return ret;
}
int get_lg(int x) { return 32 - __builtin_clz(x) - ((x & (-x)) == x); }
const size_t SZ = 1 << 19;
int inv[SZ + 5], ww[SZ];
void prep() {
  static bool has_prep = false;
  if (has_prep) return;
  inv[0] = inv[1] = 1;
  for (uint i = 2; i <= SZ; ++i) {
    inv[i] = MOD - (LL)MOD / i * inv[MOD % i] % MOD;
  }
  ww[0] = 1;
  int mul = qpow(3, (MOD - 1) / SZ);
  for (uint i = 1; i < SZ; ++i) {
    ww[i] = (LL)ww[i - 1] * mul % MOD;
  }
  has_prep = true;
}
void fft(LL a[], int lg, bool flag) {
  prep();
  int n = 1 << lg;
  if (flag) reverse(a + 1, a + n);
  static int rev[SZ], rev_lg = -1;
  if (rev_lg != lg) {
    for (int i = 0; i < n; ++i) {
      rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << lg >> 1);
    }
    rev_lg = lg;
  }
  for (int i = 0; i < n; ++i) {
    if (rev[i] > i) {
      swap(a[i], a[rev[i]]);
    }
  }
  for (int m = 1, l = 2; m < n; m <<= 1, l <<= 1) {
    LL *x = a, *y = a + m, xx, yy;
    static int *w, mul[SZ];
    for (int i = 0, j = 0, step = SZ / l; i < m; ++i, j += step) {
      mul[i] = ww[j];
    }
    for (int i = 0; i < n; i += l) {
      w = mul;
      for (int j = 0; j < m; ++j, ++x, ++y, ++w) {
        xx = *x;
        yy = *y % MOD * *w;
        *x = xx + yy;
        *y = xx - yy;
      }
      x += m;
      y += m;
    }
    if (l >> 15 & 1) {
      for (int i = 0; i < n; ++i) {
        a[i] %= MOD;
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    a[i] %= MOD;
    if (flag) {
      (a[i] *= inv[n]) %= MOD;
    }
    if (a[i] < 0) a[i] += MOD;
  }
}
Poly operator+=(Poly &f, const Poly &g) {
  if (g.size() > f.size()) {
    f.resize(g.size());
  }
  auto it = f.begin();
  auto jt = g.begin();
  while (jt != g.end()) {
    iadd(*it++, *jt++);
  }
  return f;
}
Poly operator+(const Poly &f, const Poly &g) {
  Poly ret = f;
  return ret += g;
}
Poly operator-=(Poly &f, const Poly &g) {
  if (g.size() > f.size()) {
    f.resize(g.size());
  }
  auto it = f.begin();
  auto jt = g.begin();
  while (jt != g.end()) {
    iadd(*it++, MOD - *jt++);
  }
  return f;
}
Poly operator-(const Poly &f, const Poly &g) {
  Poly ret = f;
  return ret -= g;
}
Poly operator*(const Poly &f, const Poly &g) {
  if (f.empty() || g.empty()) return {};
  uint n = f.size() + g.size() - 1;
  if ((LL)f.size() * g.size() <= 2048) {
    static uint64_t ans[SZ];
    memset(ans, 0, sizeof(uint64_t) * n);
    for (uint i = 0; i < f.size(); ++i) {
      for (uint j = 0; j < g.size(); ++j) {
        if ((ans[i + j] += (uint64_t)f[i] * g[j]) >> 62) {
          ans[i + j] %= MOD;
        }
      }
    }
    Poly ret(n);
    for (uint i = 0; i < n; ++i) {
      ret[i] = ans[i] % MOD;
    }
    return ret;
  }
  Poly ret(f.size() + g.size() - 1);
  static LL a[SZ], b[SZ];
  int lg = get_lg(n);
  memset(a, 0, sizeof(LL) << lg);
  memset(b, 0, sizeof(LL) << lg);
  copy(f.begin(), f.end(), a);
  copy(g.begin(), g.end(), b);
  fft(a, lg, 0);
  fft(b, lg, 0);
  for (uint i = 0, _ = 1 << lg; i < _; ++i) {
    (a[i] *= b[i]) %= MOD;
  }
  fft(a, lg, 1);
  copy(a, a + n, ret.begin());
  return ret;
}
Poly &operator*=(Poly &f, const Poly &g) { return f = f * g; }
Poly &operator*=(Poly &f, int x) {
  for (int &c : f) {
    c = (LL)c * x % MOD;
  }
  return f;
}
Poly operator*(const Poly &f, int x) {
  Poly ret = f;
  return ret *= x;
}
Poly operator*(int x, const Poly &f) { return f * x; }
void calc_inv(int arr[], int brr[], int n) {
  if (n == 1) {
    brr[0] = qpow(arr[0], MOD - 2);
    return;
  }
  calc_inv(arr, brr, n >> 1);
  int lg = get_lg(n << 1);
  static LL ta[SZ], tb[SZ];
  memset(ta, 0, sizeof(LL) << lg);
  memset(tb, 0, sizeof(LL) << lg);
  copy(arr, arr + n, ta);
  copy(brr, brr + (n >> 1), tb);
  fft(ta, lg, 0);
  fft(tb, lg, 0);
  for (int i = 0, _ = 1 << lg; i < _; ++i) {
    ta[i] = (2 - ta[i] * tb[i]) % MOD * tb[i] % MOD;
  }
  fft(ta, lg, 1);
  copy(ta, ta + n, brr);
}
Poly calc_inv(const Poly &f) {
  static int a[SZ], b[SZ];
  int lg = get_lg(f.size());
  memset(a, 0, sizeof(int) << lg);
  copy(f.begin(), f.end(), a);
  calc_inv(a, b, 1 << lg);
  return Poly(b, b + f.size());
}
Poly operator/(const Poly &f, const Poly &g) {
  if (f.size() < g.size()) {
    return Poly();
  }
  Poly tf = f;
  reverse(tf.begin(), tf.end());
  Poly tg = g;
  reverse(tg.begin(), tg.end());
  tg.resize(f.size() - g.size() + 1);
  Poly ret = tf * calc_inv(tg);
  ret.resize(f.size() - g.size() + 1);
  reverse(ret.begin(), ret.end());
  return ret;
}
Poly &operator/=(Poly &f, const Poly &g) { return f = f / g; }
Poly operator%(const Poly &f, const Poly &g) {
  Poly ret = f - (f / g) * g;
  ret.resize(g.size() - 1);
  return ret;
}
Poly &operator%=(Poly &f, const Poly &g) { return f = f % g; }
Poly calc_der(const Poly &f) {
  Poly ret(f.size() - 1);
  for (uint i = 1; i < f.size(); ++i) {
    ret[i - 1] = (LL)f[i] * i % MOD;
  }
  return ret;
}
Poly calc_pri(const Poly &f) {
  prep();
  Poly ret(f.size() + 1);
  for (uint i = 1; i <= f.size(); ++i) {
    ret[i] = (LL)f[i - 1] * inv[i] % MOD;
  }
  return ret;
}
Poly calc_ln(const Poly &f) {
  assert(f[0] == 1);
  Poly g = calc_der(f) * calc_inv(f);
  g.resize(f.size() - 1);
  return calc_pri(g);
}
Poly calc_exp(int arr[], int n) {
  if (n == 1) {
    assert(arr[0] == 0);
    return Poly{1};
  }
  Poly f = calc_exp(arr, n >> 1);
  Poly tf = f;
  tf.resize(n);
  Poly a = Poly(arr, arr + n);
  Poly g = f * (Poly{1} - calc_ln(tf) + a);
  g.resize(n);
  return g;
}
Poly calc_exp(const Poly &f) {
  static int a[SZ];
  int lg = get_lg(f.size());
  memset(a, 0, sizeof(int) << lg);
  copy(f.begin(), f.end(), a);
  Poly ret = calc_exp(a, 1 << lg);
  ret.resize(f.size());
  return ret;
}
Poly operator^(const Poly &f, const int &e) {
  uint trail = 0;
  for (uint i = 0; i < f.size(); ++i) {
    if (f[i])
      break;
    else
      ++trail;
  }
  if ((LL)trail * e >= f.size()) {
    return Poly(f.size(), 0);
  }
  int lst = f[trail], inv = qpow(lst, MOD - 2);
  Poly g;
  for (uint i = trail; i < f.size(); ++i) {
    g.emplace_back((LL)f[i] * inv % MOD);
  }
  Poly ret = calc_exp(calc_ln(g) * e) * qpow(lst, e);
  Poly t0 = Poly(trail * e, 0);
  ret.insert(ret.begin(), t0.begin(), t0.end());
  ret.resize(f.size());
  return ret;
}
Poly &operator^=(Poly &f, const int &e) { return f = f ^ e; }
Poly calc_sqrt(int arr[], int n) {
  if (n == 1) {
    assert(arr[0] == 1);
    return Poly{1};
  }
  Poly f = calc_sqrt(arr, n >> 1);
  Poly a = Poly(arr, arr + n);
  f.resize(n);
  Poly g = f + a * calc_inv(f);
  g.resize(n);
  g *= (MOD + 1) / 2;
  return g;
}
Poly calc_sqrt(const Poly &f) {
  static int a[SZ];
  int lg = get_lg(f.size());
  memset(a, 0, sizeof(int) << lg);
  copy(f.begin(), f.end(), a);
  Poly ret = calc_sqrt(a, 1 << lg);
  ret.resize(f.size());
  return ret;
}
int main() {
  int n = read(), m = read();
  Poly a = Poly{1, 6, 1};
  a.resize(m + 1);
  a = calc_sqrt(a);
  Poly f = calc_inv(a);
  Poly g = (Poly{1, 1} + a) * ((MOD + 1) >> 1);
  g ^= n + 1;
  Poly ans = f * g;
  ans.resize(m + 1);
  for (int i = n + 1; i <= m; ++i) {
    ans[i] = 0;
  }
  for (int i = 1; i <= m; ++i) {
    printf("%d ", ans[i]);
  }
  return 0;
}
