#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
long long modPow(long long a, long long p) {
  if (p == 0) return 1;
  auto res = modPow(a, p / 2);
  res = (res * res) % MOD;
  if (p % 2) res = (res * a) % MOD;
  return res;
}
long long calcInv(long long a) { return modPow(a, MOD - 2); }
void ntt(vector<long long>& v, int inv) {
  const int n = v.size();
  auto w = modPow(3, (MOD - 1) / n);
  if (inv == -1) w = calcInv(w);
  int rev = 0;
  for (int i = 1; i < n - 1; i++) {
    for (int j = n / 2; j > (rev ^= j); j /= 2)
      ;
    if (i < rev) swap(v[i], v[rev]);
  }
  for (int m = 1; m < n; m *= 2) {
    auto cur = 1;
    auto rot = modPow(w, n / (2 * m));
    for (int i = 0; i < m; i++) {
      for (int j = i; j < n; j += 2 * m) {
        auto p = v[j];
        auto q = v[j + m] * cur % MOD;
        v[j] = (p + q) % MOD;
        v[j + m] = (p + MOD - q) % MOD;
      }
      cur = (cur * rot) % MOD;
    }
  }
}
vector<long long> convolution(const vector<long long>& a,
                              const vector<long long>& b) {
  int _n = a.size() + b.size();
  int n = 1;
  while (n < _n) n *= 2;
  vector<long long> na(n, 0), nb(n, 0);
  for (int i = 0; i < a.size(); i++) na[i] = a[i];
  for (int i = 0; i < b.size(); i++) nb[i] = b[i];
  ntt(na, 1);
  ntt(nb, 1);
  for (int i = 0; i < n; i++) na[i] = na[i] * nb[i] % MOD;
  ntt(na, -1);
  auto inv = calcInv(n);
  for (int i = 0; i < n; i++) na[i] = na[i] * inv % MOD;
  na.resize(a.size() + b.size() - 1);
  return na;
}
bool op(const vector<long long>& a, const vector<long long>& b) {
  return a.size() < b.size();
}
int main() {
  const int maxSize = 100001;
  vector<long long> inv(maxSize);
  vector<long long> fact(maxSize);
  vector<long long> factInv(maxSize);
  for (int i = 0; i < 2; i++) inv[i] = fact[i] = factInv[i] = 1;
  for (int i = 2; i < maxSize; i++) {
    inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
    fact[i] = fact[i - 1] * i % MOD;
    factInv[i] = factInv[i - 1] * inv[i] % MOD;
  }
  auto comb = [&](int n, int r) {
    if (n < r || r < 0) return 0LL;
    return fact[n] * factInv[n - r] % MOD * factInv[r] % MOD;
  };
  auto perm = [&](int n, int r) {
    if (n < r || r < 0) return 0LL;
    return fact[n] * factInv[n - r] % MOD;
  };
  vector<long long> inv2pow(maxSize);
  inv2pow[0] = 1;
  for (int i = 1; i < maxSize; i++) inv2pow[i] = inv2pow[i - 1] * inv[2] % MOD;
  int N;
  cin >> N;
  vector<int> cnt(100001, 0);
  for (int i = 0; i < 2 * N; i++) {
    int h;
    cin >> h;
    cnt[h]++;
  }
  priority_queue<
      vector<long long>, vector<vector<long long>>,
      function<bool(const vector<long long>&, const vector<long long>&)>>
      qu([](const vector<long long>& a, const vector<long long>& b) {
        return a.size() < b.size();
      });
  qu.push(vector<long long>(1, 1));
  for (auto& t : cnt) {
    if (t < 2) continue;
    vector<long long> v(t / 2 + 1);
    v[0] = 1;
    for (int i = 1; i < v.size(); i++) {
      v[i] = perm(t, 2 * i) * inv2pow[i] % MOD;
    }
    qu.emplace(v);
  }
  while (qu.size() >= 2) {
    auto a = qu.top();
    qu.pop();
    auto b = qu.top();
    qu.pop();
    auto v = convolution(a, b);
    qu.emplace(v);
  }
  long long res = 0;
  auto v = qu.top();
  for (int i = 0; i < v.size(); i++) {
    long long rest = N - i;
    long long cur = perm(2 * rest, rest) * inv2pow[rest] % MOD;
    if (i % 2) {
      res = (res + MOD - cur * v[i] % MOD) % MOD;
    } else {
      res = (res + cur * v[i]) % MOD;
    }
  }
  cout << res << endl;
}
