#include <bits/stdc++.h>

#include <atcoder/all>

// #LIB#

using namespace std;
using namespace atcoder;
using ll = long long;
#define double long double
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repr(i, a, b) for (auto i = (a); i < (b); ++i)
#define itr(x, c) for (auto&& x : (c))
#define updatemax(t, v) ((t) = std::max((t), (v)))
#define updatemin(t, v) ((t) = std::min((t), (v)))
#ifdef ONLINE_JUDGE
#define endl _endl
const char _endl = (cin.tie(0), cout.tie(0), ios::sync_with_stdio(0), cout.precision(16), '\n');
#endif

using mint = static_modint<998244353>;

int main() {
  int n;
  cin >> n;
  vector<int> h(2 * n);
  rep(i, 2 * n) cin >> h[i];
  sort(h.begin(), h.end());
  const int FMAX = n + 2;
  vector<mint> f(FMAX), ff(2 * n), finv(FMAX);
  f[0] = ff[0] = ff[1] = finv[0] = 1;
  repr(i, 1, FMAX) {
    f[i] = f[i - 1] * i;
    finv[i] = finv[i - 1] / i;
  }
  repr(i, 2, 2 * n) ff[i] = ff[i - 2] * i;
  auto fbps_cp = [](const vector<mint>& a, const vector<mint>& b) { return a.size() > b.size(); };
  priority_queue<vector<mint>, vector<vector<mint>>, decltype(fbps_cp)> fbps(fbps_cp);
  int _fs = 0;
  rep(i, 2 * n) {
    if (i + 1 >= 2 * n || h[i] != h[i + 1]) {
      auto _fw = i + 1 - _fs;
      if (_fw >= 2) {
        vector<mint> _fbs(_fw / 2 + 1);
        _fbs[0] = 1;
        repr(j, 1, _fw / 2 + 1) {
          _fbs[j] = f[_fw] * finv[j * 2] * finv[_fw - j * 2] * ff[j * 2 - 1];
        }
        fbps.push(move(_fbs));
      }
      _fs = i + 1;
    }
  }
  vector<mint> forbidden({1});
  while (!fbps.empty()) {
    auto top = fbps.top();
    forbidden = convolution(forbidden, top);
    fbps.pop();
  }
  mint ans = 0;
  rep(i, n + 1) {
    if (i >= forbidden.size()) break;
    mint counts = forbidden[i];
    mint v = counts * (i == n ? 1 : ff[2 * n - 1 - i * 2]);
    if (i % 2 == 0) {
      ans += v;
    } else {
      ans -= v;
    }
  }
  cout << ans.val() << endl;
}
