#include <bits/stdc++.h>
using namespace std;
mt19937_64 rng(
    (unsigned)chrono::system_clock::now().time_since_epoch().count());
const long long int mod = 998244353;
const long double PI = acosl(-1);
const int nmax = 1e5 + 10;
long long int modexpo(long long int x, long long int n, long long int m) {
  long long int ret = 1;
  while (n) {
    if (n & 1) ret = ret * x % m;
    x = x * x % m;
    n >>= 1;
  }
  return ret;
}
vector<long long int> roots;
long long int M;
int N;
int precal(long long int m, long long int rt, int max_n = (1LL << (22))) {
  long long int k = (m - 1);
  N = 1, M = m;
  while (!(k & 1) && N < max_n) k >>= 1, N <<= 1;
  roots.resize(N + 1);
  rt = modexpo(rt, k, M);
  roots[0] = 1;
  for (int i = 1; i <= N; i++) roots[i] = roots[i - 1] * rt % M;
  return N;
}
void NTT(vector<long long int> &coefs, vector<long long int> &values,
         bool invert = false) {
  int n = (int)coefs.size(), lg_n = __builtin_ctz(n),
      mask = (int)(1LL << (lg_n)) - 1;
  values.resize(n);
  for (int i = 0, j = 0; j < n;
       j++, i = (int)((i) ^ mask ^
                      ((1LL << (31 - __builtin_clz((i) ^ mask))) - 1)))
    values[j] = coefs[i];
  for (int len = 2, hlen = 1; len <= n; len <<= 1, hlen <<= 1)
    for (int i = 0; i < n; i += len)
      for (int j = 0, r = N / len; j < hlen; j++) {
        long long int w = (invert) ? roots[N - j * r] : roots[j * r];
        long long int u = values[i + j], v = values[i + j + hlen] * w % M;
        values[i + j] = u + v;
        if (values[i + j] >= M) values[i + j] -= M;
        values[i + j + hlen] = u - v;
        if (values[i + j + hlen] < 0) values[i + j + hlen] += M;
      }
  if (invert) {
    long long int inv_n = modexpo(n, M - 2, M);
    for (auto &x : values) x = x * inv_n % M;
  }
}
void multiply(vector<long long int> &A, vector<long long int> &B,
              vector<long long int> &C) {
  vector<long long int> va, vb;
  int a = (int)A.size(), b = (int)B.size(), n = 1;
  while (n < a + b) n <<= 1;
  A.resize(n), B.resize(n);
  NTT(A, va), NTT(B, vb);
  for (int i = 0; i < n; i++) va[i] = va[i] * vb[i] % mod;
  NTT(va, C, true);
  C.resize(a + b - 1);
}
vector<vector<long long int> > P;
long long int fac[nmax];
long long int facinv[nmax];
void precalNCR() {
  fac[0] = 1;
  for (int i = 1; i < nmax; i++) fac[i] = fac[i - 1] * i % mod;
  facinv[nmax - 1] = modexpo(fac[nmax - 1], mod - 2, mod);
  for (int i = nmax - 1; i > 0; i--) facinv[i - 1] = facinv[i] * i % mod;
}
long long int ncr(int n, int r) {
  if (r < 0 || n < r) return 0;
  return fac[n] * facinv[r] % mod * facinv[n - r] % mod;
}
int cnt[nmax];
long long int oddfac[nmax];
int recurse(int l, int r) {
  if (l == r) return l;
  int mid = (l + r) >> 1;
  int lid = recurse(l, mid);
  int rid = recurse(mid + 1, r);
  multiply(P[lid], P[rid], P[lid]);
  return lid;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  ;
  precal(mod, 3, 1 << 20);
  precalNCR();
  int n;
  cin >> n;
  for (int i = 0; i < 2 * n; i++) {
    int x;
    cin >> x;
    cnt[x]++;
  }
  oddfac[0] = 1;
  for (int i = 2; i <= 2 * n; i += 2) {
    oddfac[i] = oddfac[i - 2] * (i - 1) % mod;
  }
  for (int i = 1; i < nmax; i++) {
    if (cnt[i] <= 1) {
      continue;
    }
    P.emplace_back(cnt[i] + 1);
    P.back()[0] = 1;
    long long int tmp = 1;
    for (int j = 2; j <= cnt[i]; j += 2) {
      P.back()[j] = ncr(cnt[i], j) * oddfac[j] % mod;
    }
  }
  int id = recurse(0, (int)P.size() - 1);
  long long int ans = 0;
  for (int i = 0; i < P[id].size(); i += 2) {
    long long int tmp = P[id][i] * oddfac[2 * n - i];
    if (i / 2 % 2 == 0) {
      ans += tmp;
    } else {
      ans -= tmp;
    }
    ans %= mod;
  }
  if (ans < 0) ans += mod;
  cout << ans << endl;
  return 0;
}
