1349_F2. Slime and Sequences (Hard Version)

Note that the only differences between easy and hard versions are the constraints on n and the time limit. You can make hacks only if all versions are solved.

Slime is interested in sequences. He defined good positive integer sequences p of length n as follows:

  * For each k>1 that presents in p, there should be at least one pair of indices i,j, such that 1 ≤ i < j ≤ n, p_i = k - 1 and p_j = k.



For the given integer n, the set of all good sequences of length n is s_n. For the fixed integer k and the sequence p, let f_p(k) be the number of times that k appears in p. For each k from 1 to n, Slime wants to know the following value:

$$$\left(∑_{p∈ s_n} f_p(k)\right)\ mod\ 998 244 353$$$

Input

The first line contains one integer n\ (1≤ n≤ 100 000).

Output

Print n integers, the i-th of them should be equal to \left(∑_{p∈ s_n} f_p(i)\right)\ mod\ 998 244 353.

Examples

Input


2


Output


3 1 


Input


3


Output


10 7 1 


Input


1


Output


1 

Note

In the first example, s=\{[1,1],[1,2]\}.

In the second example, s=\{[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,2],[1,2,3]\}.

In the third example, s=\{[1]\}.

Example input:
2

1

3


Example output:
3 1 
1 
10 7 1 

Tags: dp
fft
math
Difficulty rating: 3500

Solution:
#include <bits/stdc++.h>
using namespace std;
const int N = 300005, P = 998244353;
using ll = long long;
ll qpow(ll a, ll b) {
  ll ret = 1;
  while (b) {
    if (b & 1) ret = ret * a % P;
    a = a * a % P;
    b >>= 1;
  }
  return ret;
}
int lim, lim2, lg[N];
ll fac[N], inv[N], ifac[N], w[N];
void FFTinit(int n) {
  lim = 1;
  fac[0] = fac[1] = inv[1] = ifac[0] = ifac[1] = 1;
  while (n >= lim << 1) lim <<= 1;
  ll pw = qpow(3, (P - 1) / (lim2 = lim * 2));
  w[lim] = 1;
  for (int i = lim + 1; i < lim2; i++) w[i] = w[i - 1] * pw % P;
  for (int i = lim - 1; i > 0; --i) w[i] = w[i << 1];
  for (int i = 2; i <= lim2; i++)
    inv[i] = (P - P / i) * inv[P % i] % P, assert(inv[i] * i % P == 1),
    fac[i] = fac[i - 1] * i % P, ifac[i] = ifac[i - 1] * inv[i] % P,
    assert(fac[i] * ifac[i] % P == 1), lg[i] = lg[i >> 1] + 1;
}
void NTT(ll a[], int n, int fl) {
  static int rev[N];
  for (int i = 0; i < n; i++)
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg[n] - 1));
  if (fl == -1) reverse(a + 1, a + n);
  for (int i = 0; i < n; i++)
    if (i < rev[i]) swap(a[i], a[rev[i]]);
  for (int s = 1; s < n; s <<= 1) {
    for (int i = 0; i < n; i += s << 1)
      for (int j = 0, tt = s; j < s; j++, tt++) {
        ll x = a[i + j], y = a[i + s + j] * w[tt] % P;
        a[i + j] = (x + y) % P;
        a[i + s + j] = (x + P - y) % P;
      }
  }
  if (fl == -1)
    for (int i = 0; i < n; i++) a[i] = a[i] * 1ll * inv[n] % P;
}
void Mul(ll a[], ll b[], ll c[], int n, int m, int cl = -1) {
  static ll tt[2][N];
  int lt = 1 << (lg[n + m] + 1);
  for (int i = 0; i < lt; i++)
    tt[0][i] = i <= n ? a[i] : 0, tt[1][i] = i <= m ? b[i] : 0;
  NTT(tt[0], lt, 1);
  NTT(tt[1], lt, 1);
  for (int i = 0; i < lt; i++) c[i] = tt[0][i] * tt[1][i] % P;
  NTT(c, lt, -1);
  if (cl != -1)
    for (int i = cl + 1; i <= n + m; i++) c[i] = 0;
}
void Inv(ll a[], ll b[], int n) {
  b[b[1] = 0] = qpow(a[0], P - 2);
  static ll t[N];
  for (int k = 2, l = 4; k < (n << 1); k <<= 1, l <<= 1) {
    for (int i = 0; i < l; i++) t[i] = i < k ? a[i] : b[i] = 0;
    NTT(t, l, 1);
    NTT(b, l, 1);
    for (int i = 0; i < l; i++) b[i] = b[i] * (P + 2 - t[i] * b[i] % P) % P;
    NTT(b, l, -1);
    for (int i = min(n, k); i < l; i++) b[i] = 0;
  }
}
void Ln(ll a[], ll b[], int n) {
  static ll t[N];
  Inv(a, b, n);
  int l = 1 << (lg[n * 2 - 2] + 1);
  for (int i = 0; i < l; i++)
    t[i] = i < n - 1 ? a[i + 1] * (i + 1) % P : b[i] = 0;
  NTT(t, l, 1);
  NTT(b, l, 1);
  for (int i = 0; i < l; i++) t[i] = t[i] * b[i] % P;
  NTT(t, l, -1);
  b[0] = 0;
  for (int i = 1; i < l; i++) b[i] = i < n ? t[i - 1] * inv[i] % P : 0;
}
void Exp(ll a[], ll b[], int n) {
  static ll t[N];
  b[b[1] = 0] = 1;
  for (int k = 2, l = 4; k < (n << 1); k <<= 1, l <<= 1) {
    Ln(b, t, k);
    for (int i = 0; i < l; i++) t[i] = i < k ? !i + a[i] - t[i] : b[i] = 0;
    NTT(t, l, 1);
    NTT(b, l, 1);
    for (int i = 0; i < l; i++) b[i] = b[i] * t[i] % P;
    NTT(b, l, -1);
    for (int i = min(n, k); i < l; i++) b[i] = 0;
  }
}
ll h[N], hd[N], hi[N], hn1[N], a[N], b[N], c[N], d[N], e[N], lx[N], rx[N];
ll s[N], g[N], f[N], ans[N], p[N];
int main() {
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  FFTinit((n + 10) * 2);
  a[0] = a[1] = 1;
  Ln(a, b, n + 4);
  for (int i = 0; i <= n + 10; i++) b[i] = b[i + 1];
  Inv(b, h, n + 10);
  for (int i = 0; i <= n + 10; i++) hd[i] = h[i + 1] * (i + 1) % P;
  Ln(h, c, n + 10);
  for (int i = 0; i <= n + 10; i++) c[i] = c[i] * (n + 1) % P;
  Exp(c, hn1, n + 10);
  for (int i = 0; i <= n + 10; i++) d[i] = (P - h[i + 1]) % P;
  Inv(d, hi, n + 10);
  Mul(hn1, hi, rx, n + 10, n + 10);
  Mul(hi, hi, hi, n + 10, n + 10);
  Mul(hi, hd, lx, n + 10, n + 10);
  Mul(lx, hn1, lx, n + 10, n + 10);
  for (int i = 0; i <= n + 1; i++)
    s[i] = (rx[n + 1 - i + 1] * i % P + lx[n - i + 2]) * inv[n + 1] % P;
  reverse(s, s + n + 2);
  for (int i = 0; i <= n + 10; i++) g[i] = P - ifac[i + 2];
  Inv(g, e, n + 10);
  for (int i = 0; i <= n + 10; i++) e[i] = e[i + 1];
  for (int i = 0; i <= n + 1; i++) s[i] = (e[i] - s[i]) % P;
  s[0] = n;
  for (int i = 0; i <= n + 1; i++) s[i] = s[i] * fac[i] % P;
  for (int i = 0; i <= n; i++) f[i] = ((n - i) & 1 ? -1 : 1) * ifac[n - i];
  Mul(s, f, p, n, n);
  for (int i = 0; i <= n; i++) ans[i] = p[n + i] * fac[n] % P * ifac[i] % P;
  for (int i = 0; i < n; i++) cout << (ans[i] + P) % P << ' ';
  return 0;
}