#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
const int maxn = 55000 * 2;
const int Maxn = 2e6 + 100;
const int len_lim = 55000 * 2;
int ksm(int num, int t) {
  int res = 1;
  for (; t; t >>= 1, num = 1ll * num * num % mod) {
    if (t & 1) res = 1ll * res * num % mod;
  }
  return res;
}
struct NTT {
  int wn[2][Maxn], A[Maxn], B[Maxn], rev[Maxn];
  void get_wn(int len) {
    for (int l = 2; l <= len; l <<= 1) {
      int w1 = ksm(3, (mod - 1) / l), w0 = ksm(3, mod - 1 - (mod - 1) / l);
      wn[1][l >> 1] = wn[0][l >> 1] = 1;
      for (int j = 1; j < (l >> 1); j++) {
        wn[1][(l >> 1) + j] = 1ll * wn[1][(l >> 1) + j - 1] * w1 % mod;
        wn[0][(l >> 1) + j] = 1ll * wn[0][(l >> 1) + j - 1] * w0 % mod;
      }
    }
  }
  void get_rev(int len) {
    for (int i = (1), iend = ((1 << len)); i <= iend; i++)
      rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << len - 1);
  }
  void ntt(int len, int *c, int f) {
    for (int i = (0), iend = (len); i <= iend; i++)
      if (rev[i] > i) swap(c[rev[i]], c[i]);
    for (int l = 2; l <= len; l <<= 1) {
      for (int i = 0; i + l <= len; i += l) {
        for (int j = i; j < i + (l >> 1); j++) {
          int tmp1 = c[j],
              tmp2 = 1ll * wn[f][j - i + (l >> 1)] * c[j + (l >> 1)] % mod;
          c[j] = (tmp1 + tmp2) % mod;
          c[j + (l >> 1)] = (tmp1 - tmp2 + mod) % mod;
        }
      }
    }
    if (!f) {
      int inv = ksm(len, mod - 2);
      for (int i = (0), iend = (len - 1); i <= iend; i++)
        c[i] = 1ll * c[i] * inv % mod;
    }
  }
  vector<int> mul(vector<int> a, vector<int> b) {
    int l1 = a.size(), l2 = b.size();
    int len = 1, cnt = 0;
    while (len <= l1 + l2) cnt++, len <<= 1;
    get_rev(cnt);
    for (int i = (0), iend = (len); i <= iend; i++) A[i] = B[i] = 0;
    for (int i = (0), iend = (l1 - 1); i <= iend; i++) A[i] = a[i];
    for (int i = (0), iend = (l2 - 1); i <= iend; i++) B[i] = b[i];
    ntt(len, A, 1);
    ntt(len, B, 1);
    for (int i = (0), iend = (len - 1); i <= iend; i++)
      A[i] = 1ll * A[i] * B[i] % mod;
    ntt(len, A, 0);
    vector<int> re;
    for (int i = (0), iend = (len - 1); i <= iend; i++) re.push_back(A[i]);
    re.resize(min(l1 + l2, len_lim));
    return re;
  }
} t;
int h[maxn], bk[maxn], cnt[maxn];
int frac[maxn];
int C(int m, int n) {
  return 1ll * frac[n] * ksm(1ll * frac[m] * frac[n - m] % mod, mod - 2) % mod;
}
int g(int x) {
  return 1ll * frac[2 * x] * ksm(1ll * frac[x] * ksm(2, x) % mod, mod - 2) %
         mod;
}
vector<int> gen[maxn];
vector<int> solve(int l, int r) {
  if (l == r) return gen[l];
  int mid = (l + r) >> 1;
  vector<int> debug = t.mul(solve(l, mid), solve(mid + 1, r));
  return debug;
}
int tmp[maxn];
int main() {
  frac[0] = 1;
  for (int i = (1), iend = (maxn - 1); i <= iend; i++)
    frac[i] = 1ll * i * frac[i - 1] % mod;
  t.get_wn(20);
  ios::sync_with_stdio(0);
  int n;
  cin >> n;
  for (int i = (1), iend = (2 * n); i <= iend; i++) cin >> h[i], bk[i] = h[i];
  sort(bk + 1, bk + 1 + 2 * n);
  int mxid = unique(bk + 1, bk + 1 + 2 * n) - bk - 1;
  for (int i = (1), iend = (2 * n); i <= iend; i++)
    h[i] = lower_bound(bk + 1, bk + 1 + n, h[i]) - bk, cnt[h[i]]++;
  for (int i = (1), iend = (mxid); i <= iend; i++) {
    for (int j = (0), jend = (cnt[i] / 2); j <= jend; j++) {
      gen[i].push_back(1ll * C(2 * j, cnt[i]) * g(j) % mod);
    }
  }
  vector<int> ans = solve(1, mxid);
  for (int i = (0), iend = (n); i <= iend; i++) {
    tmp[i] = 1ll * ans[i] * g(n - i) % mod;
  }
  int out = 0;
  for (int i = (0), iend = (n); i <= iend; i++) {
    out = (out + 1ll * ((i & 1) ? -1 : 1) * tmp[i]) % mod;
  }
  cout << out;
  return 0;
}
