#include <bits/stdc++.h>
using namespace std;
const int N = 1e3, mod = 998244353, G = 3, G1 = (mod + 1) / G;
int n, a[N], b[N], pos[N], fa[N];
int A, B, C, D;
int r[N], lim, l;
long long ans[N], f[N], g[N], h[N], s[N][N], c[N][N];
long long fac[N], ifac[N];
void Add(long long &x, long long y) { x = (x + y) % mod; }
long long add(long long x, long long y) { return (x + y) % mod; }
void Mul(long long &x, long long y) { x = x * y % mod; }
long long mul(long long x, long long y) { return x * y % mod; }
void Sub(long long &x, long long y) { x = (x - y + mod) % mod; }
long long sub(long long x, long long y) { return (x - y + mod) % mod; }
long long qpow(long long a, long long b) {
  long long ret = 1;
  for (; b; b >>= 1, Mul(a, a))
    if (b & 1) Mul(ret, a);
  return ret;
}
void NTT(long long a[], int op) {
  for (int i = 0; i <= lim - 1; i++)
    if (i < r[i]) swap(a[i], a[r[i]]);
  for (int mid = 1; mid < lim; mid <<= 1) {
    long long W = qpow(op == 1 ? G : G1, (mod - 1) / (mid << 1));
    for (int j = 0; j < lim; j += (mid << 1)) {
      long long w = 1;
      for (int k = 0; k < mid; ++k, Mul(w, W)) {
        long long x = a[j + k], y = mul(w, a[j + k + mid]);
        a[j + k] = add(x, y), a[j + k + mid] = sub(x, y);
      }
    }
  }
  if (op == -1) {
    long long Inv = qpow(lim, mod - 2);
    for (int i = 0; i <= lim - 1; i++) Mul(a[i], Inv);
  }
}
int getfa(int x) { return fa[x] == x ? x : getfa(fa[x]); }
void merge(int x, int y) { fa[getfa(x)] = getfa(y); }
bool v1[N], v2[N];
void prework() {
  s[0][0] = fac[0] = fac[1] = ifac[0] = ifac[1] = 1;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= i; j++)
      s[i][j] = add(s[i - 1][j - 1], mul(s[i - 1][j], i - 1));
  for (int i = 2; i <= n; i++)
    fac[i] = mul(fac[i - 1], i), ifac[i] = mul(mod - mod / i, ifac[mod % i]);
  for (int i = 2; i <= n; i++) Mul(ifac[i], ifac[i - 1]);
  for (int i = 0; i <= n; i++)
    for (int j = 0; j <= i; j++)
      c[i][j] = j == 0 ? 1 : add(c[i - 1][j - 1], c[i - 1][j]);
  for (int i = 1; i <= n; i++) fa[i] = i;
  for (int i = 1; i <= n; i++)
    if (a[i] && b[i] && !v1[a[i]]) {
      int x = i;
      v1[a[i]] = 1;
      while (1) {
        if (b[x] && pos[b[x]])
          x = pos[b[x]];
        else
          break;
        v1[a[x]] = 1;
        merge(a[x], a[i]);
        if (x == i) {
          ++D;
          break;
        }
      }
    }
  for (int i = 1; i <= n; i++) a[i] = getfa(a[i]), b[i] = getfa(b[i]);
  memset(v1, 0, sizeof(v1));
  for (int i = 1; i <= n; i++) {
    if (!a[i]) v2[b[i]] = 1;
    if (!b[i]) v1[a[i]] = 1;
  }
  for (int i = 1; i <= n; i++)
    if (v1[i] && v2[i]) ++C;
  for (int i = 1; i <= n; i++) {
    if (!a[i] && !b[i])
      ++C;
    else if (a[i] && !b[i] && !v2[a[i]])
      ++A;
    else if (!a[i] && b[i] && !v1[b[i]])
      ++B;
  }
}
void Get(long long f[], int A, int C) {
  if (!C)
    for (int i = 0; i <= A; i++) f[i] = s[A][i];
  else
    for (int i = 0; i <= A; i++)
      for (int j = i; j <= A; j++)
        Add(f[i],
            mul(c[A][j], mul(s[j][i], mul(fac[A + C - j - 1], ifac[C - 1]))));
}
int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]), pos[a[i]] = i;
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  prework();
  Get(f, A, C);
  Get(g, B, C);
  for (int i = 0; i <= C; i++) h[i] = mul(s[C][i], fac[C]);
  lim = 1, l = 0;
  while (lim <= n * 2) lim <<= 1, ++l;
  for (int i = 0; i <= lim - 1; i++)
    r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
  NTT(f, 1), NTT(g, 1), NTT(h, 1);
  for (int i = 0; i <= lim - 1; i++) ans[i] = mul(f[i], mul(g[i], h[i]));
  NTT(ans, -1);
  for (int i = 0; i <= n - 1; i++) printf("%lld ", ans[n - i - D]);
  puts("");
  return 0;
}
