#include <bits/stdc++.h>
template <typename T>
inline void read(T &x) {
  x = 0;
  char c = getchar();
  bool flag = false;
  while (!isdigit(c)) {
    if (c == '-') flag = true;
    c = getchar();
  }
  while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
  if (flag) x = -x;
}
using namespace std;
const int P = 998244353;
inline void ADD(long long &a, long long b) {
  a += b;
  if (a >= P) a -= P;
}
inline long long quickpow(long long x, int k) {
  long long res = 1;
  while (k) {
    if (k & 1) res = res * x % P;
    x = x * x % P;
    k >>= 1;
  }
  return res;
}
int n;
int p[266], q[266];
struct edge {
  int nxt, to;
  edge(int jzp, int zzz) { nxt = jzp, to = zzz; }
  edge() {}
} e[266 << 1];
int head[266], ecnt;
int ind[266], outd[266];
inline void addedge(int from, int to) {
  ++ind[to];
  ++outd[from];
  e[++ecnt] = edge(head[from], to);
  head[from] = ecnt;
}
int fath[266];
int find(int cur) {
  return fath[cur] == cur ? cur : fath[cur] = find(fath[cur]);
}
int circnt, A, B, C;
void dfs_x(int cur) {
  if (!cur) return ++B, void();
  if (!outd[cur]) return;
  for (int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    dfs_x(to);
  }
}
void dfs_0(int cur) {
  if (!cur) return ++C, void();
  if (!outd[cur]) return ++A, void();
  for (int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    dfs_0(to);
  }
}
long long s[266][266], jie[266 << 1], jieni[266 << 1];
long long f[266], g[266], h[266], yu[266], ans[266];
inline long long get_c(int n, int m) {
  if (n < 0 || m < 0 || n - m < 0) return 0;
  return jie[n] * jieni[m] % P * jieni[n - m] % P;
}
inline void init() {
  s[0][0] = 1;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      s[i][j] = (s[i - 1][j - 1] + s[i - 1][j] * (i - 1)) % P;
    }
  }
  const int up = 505;
  jie[0] = jieni[0] = 1;
  for (int i = 1; i <= up; ++i) jie[i] = jie[i - 1] * i % P;
  jieni[up] = quickpow(jie[up], P - 2);
  for (int i = up - 1; i; --i) jieni[i] = jieni[i + 1] * (i + 1) % P;
}
inline void work() {
  init();
  for (int i = 0; i <= max(A, B); ++i) {
    yu[i] = get_c(C + i - 1, C - 1) * jie[i] % P;
  }
  if (!C) yu[0] = 1;
  for (int m = 0; m <= A; ++m)
    for (int i = 0; i <= A; ++i)
      f[m] = (f[m] + s[i][m] * yu[A - i] % P * get_c(A, i)) % P;
  for (int m = 0; m <= B; ++m)
    for (int i = 0; i <= B; ++i)
      g[m] = (g[m] + s[i][m] * yu[B - i] % P * get_c(B, i)) % P;
  for (int m = 0; m <= C; ++m) h[m] = s[C][m] * jie[C] % P;
  for (int i = 0; i <= A; ++i) {
    for (int j = 0; j <= B; ++j) {
      for (int k = 0; k <= C; ++k) {
        ADD(ans[i + j + k + circnt], f[i] * g[j] % P * h[k] % P);
      }
    }
  }
  for (int i = 0; i < n; ++i) cout << ans[n - i] << ' ';
  puts("");
}
int main() {
  read(n);
  for (int i = 1; i <= n; ++i) read(p[i]);
  for (int i = 1; i <= n; ++i) read(q[i]);
  for (int i = 1; i <= n; ++i) fath[i] = i;
  for (int i = 1; i <= n; ++i) {
    if (!p[i] && !q[i])
      ++C;
    else
      addedge(p[i], q[i]);
    if (p[i] && q[i]) {
      int fp = find(p[i]), fq = find(q[i]);
      if (fp == fq)
        ++circnt;
      else
        fath[fp] = fq;
    }
  }
  for (int i = 1; i <= n; ++i)
    if (!ind[i]) dfs_x(i);
  for (int i = head[0]; i; i = e[i].nxt) {
    int to = e[i].to;
    dfs_0(to);
  }
  work();
  return 0;
}
