#include <bits/stdc++.h>
#include <atcoder/convolution>
#include <atcoder/modint>
using namespace std;
using namespace atcoder;

#ifdef LOCAL
#define DEBUG(...) debug(#__VA_ARGS__, __VA_ARGS__);
#else
#define DEBUG(...) 6;
#endif

template<typename T, typename S> ostream& operator << (ostream &os, const pair<T, S> &p) {return os << "(" << p.first << ", " << p.second << ")";}
template<typename C, typename T = decay<decltype(*begin(declval<C>()))>, typename enable_if<!is_same<C, string>::value>::type* = nullptr>
ostream& operator << (ostream &os, const C &c) {bool f = true; os << "["; for (const auto &x : c) {if (!f) os << ", "; f = false; os << x;} return os << "]";}
template<typename T> void debug(string s, T x) {cerr << s << " = " << x << "\n";}
template<typename T, typename... Args> void debug(string s, T x, Args... args) {cerr << s.substr(0, s.find(',')) << " = " << x << " | "; debug(s.substr(s.find(',') + 2), args...);}

const int MAXN = 1e5 + 5;

typedef modint998244353 M;

struct cmp {
    bool operator () (const vector<M> &a, const vector<M> &b) {
        return a.size() > b.size();
    }
};

M fact[MAXN], inv[MAXN], power[MAXN];

M choose(int n, int k) {
    return fact[n] * inv[k] * inv[n-k];
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;
    vector<int> cnt(MAXN);
    for (int i=0; i<2*n; i++) {
        int h;
        cin >> h;
        cnt[h]++;
    }

    fact[0] = inv[0] = power[0] = 1;
    for (int i=1; i<=2*n; i++) {
        fact[i] = fact[i-1] * i;
        inv[i] = fact[i].inv();
        power[i] = power[i-1] / 2;
    }

    priority_queue<vector<M>, vector<vector<M>>, cmp> pq;
    for (int i=1; i<MAXN; i++)
        if (cnt[i] >= 2) {
            vector<M> cur{1};
            for (int j=1; j*2<=cnt[i]; j++)
                cur.push_back(cur.back() * choose(cnt[i] - (j - 1) * 2, 2) / j);
            pq.emplace(cur);
        }

    while (pq.size() > 1) {
        vector<M> a = pq.top();
        pq.pop();
        vector<M> b = pq.top();
        pq.pop();
        pq.emplace(convolution(a, b));
    }

    M ret = 0;
    vector<M> cur = pq.top();
    for (int i=0; i<(int)cur.size(); i++)
        ret += cur[i] * (i % 2 ? -1 : 1) * fact[2 * n - 2 * i] * power[n - i] * inv[n - i];
    cout << ret.val() << "\n";

    return 0;
}