#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;
}
