#include <bits/stdc++.h>
using namespace std;
const int N = 1 << 19, M = 1e5 + 10, mod = 998244353, G = 3;
int n;
int a[N], b[N], fac[N], finv[N], two[N];
long long A[N], B[N], inv, tong[M];
int R[N];
int power(int x, int n) {
  int res = 1;
  for (; n; n >>= 1, x = 1ll * x * x % mod)
    if (n & 1) res = 1ll * res * x % mod;
  return res;
}
vector<int> colors[N << 1];
struct cmp {
  bool operator()(int a, int b) { return colors[a].size() > colors[b].size(); }
};
priority_queue<int, vector<int>, cmp> heap;
void NTT(long long a[], int n, int re) {
  for (int i = 0; i < n; i++)
    if (i < R[i]) swap(a[i], a[R[i]]);
  for (int i = 2; i <= n; i <<= 1) {
    long long mid = i >> 1;
    long long wn = power(G, (mod - 1) / i);
    if (re) wn = power(wn, (mod - 2));
    for (int j = 0; j < n; j += i) {
      long long w = 1;
      for (int k = 0; k < mid; k++) {
        long long temp1 = a[j + k];
        long long temp2 = a[j + k + mid] * w % mod;
        a[j + k] = (temp1 + temp2) % mod;
        a[j + k + mid] = (temp1 - temp2);
        a[j + k + mid] = (a[j + k + mid] % mod + mod) % mod;
        w = w * wn % mod;
      }
    }
  }
  if (re) {
    for (int i = 0; i < n; i++) a[i] = (a[i] * inv) % mod;
  }
}
void NTT_times(vector<int> &a, vector<int> &b, vector<int> &c) {
  int n, d;
  for (int i = 0; i < a.size(); i++) A[i] = a[i];
  for (int i = 0; i < b.size(); i++) B[i] = b[i];
  for (n = 1, d = 0; n < a.size() + b.size() - 1; n <<= 1, d++)
    ;
  inv = power(n, mod - 2);
  for (int i = 0; i < n; i++) {
    R[i] = (R[i >> 1] >> 1) | ((i & 1) << (d - 1));
  }
  for (int i = a.size(); i < n; i++) A[i] = 0;
  for (int i = b.size(); i < n; i++) B[i] = 0;
  NTT(A, n, 0), NTT(B, n, 0);
  for (int i = 0; i < n; i++) A[i] = A[i] * B[i] % mod;
  NTT(A, n, 1);
  c.clear();
  for (int i = 0; i <= a.size() + b.size() - 2; i++) c.push_back(A[i] % mod);
}
void init() {
  fac[0] = fac[1] = finv[0] = 1;
  two[0] = 1;
  two[1] = (mod + 1) / 2;
  for (int i = 2; i < N; ++i) {
    fac[i] = 1ll * fac[i - 1] * i % mod;
    two[i] = 1ll * two[i - 1] * two[1] % mod;
  }
  finv[N - 1] = power(fac[N - 1], mod - 2);
  for (int i = N - 2; i >= 1; --i) finv[i] = 1ll * finv[i + 1] * (i + 1) % mod;
}
int C(int n, int m) {
  if (m < 0 || n < m) return 0;
  return 1ll * fac[n] * finv[m] % mod * finv[n - m] % mod;
}
int cal(int x) { return 1ll * fac[2 * x] * two[x] % mod * finv[x] % mod; }
int main() {
  init();
  scanf("%d", &n);
  int mx = 0;
  for (int i = 1; i <= 2 * n; ++i) {
    int v;
    scanf("%d", &v);
    mx = max(mx, v);
    tong[v]++;
  }
  int sz = 0;
  for (int i = 1; i <= mx; i++) {
    if (tong[i] < 2) continue;
    colors[++sz].clear();
    int up = tong[i] / 2;
    colors[sz].push_back(1);
    int now = 1, left = tong[i], v;
    for (int j = 1; j <= up; ++j) {
      now = 1ll * now * C(left, 2) % mod;
      v = 1ll * now * finv[j] % mod;
      colors[sz].push_back(v);
      left -= 2;
    }
    heap.push(sz);
  }
  while (heap.size() >= 2) {
    int x = heap.top();
    heap.pop();
    int y = heap.top();
    heap.pop();
    NTT_times(colors[x], colors[y], colors[++sz]);
    colors[x].clear(), colors[y].clear();
    heap.push(sz);
  }
  long long ans = 0;
  for (int i = 0; i < colors[sz].size(); ++i) {
    long long v = 1ll * colors[sz][i] * cal(n - i) % mod;
    if (i & 1) {
      ans = (ans - v + mod) % mod;
    } else {
      ans = (ans + v) % mod;
    }
  }
  printf("%lld\n", ans);
  return 0;
}
