#include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
#include <assert.h>
#include <unordered_map>
#include <fstream>
#include <ctime>
#include <complex>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 510000;
ll dy[8] = {1,-1,0,0,1,-1,1,-1};
ll dx[8] = {0,0,1,-1,1,-1,-1,1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << "debug: " << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << "debug: " << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

vector<ll> fac(MAX), finv(MAX), inv(MAX);

void comInit(){
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for(ll i=2; i<MAX; i++){
        fac[i] = fac[i-1]*i % mod;
        inv[i] = mod - inv[mod%i] * (mod/i) % mod;
        finv[i] = finv[i-1] * inv[i] % mod;
    }
}


ll com(ll n, ll k){
    if(n < k) return 0;
    if(n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n-k] % mod) % mod;
}

using mint = modint998244353;

int main(){
    int n; cin >> n;
    int N = 2*n;
    vl cnt(101010,0);
    rep(i,N){
        int h; cin >> h;
        cnt[h]++;
    }
    sort(rall(cnt));
    comInit();
    mint dfact[101010];
    dfact[0] = dfact[1] = 1;
    for(int i=2; i<=N; i++){
        dfact[i] = dfact[i-2] * com(i,2);
        dfact[i] *= inv[i/2];
    }
    vector<vector<mint>> v(202020);
    int id = 0;
    set<P> se;
    if(cnt[0] > n){
        cout << 0 << "\n";
        return 0;
    }
    rep(i,101010){
        if(cnt[i] <= 1) break;
        v[id].push_back(1);
        mint now = com(cnt[i], 2);
        for(int j=1; j*2<=cnt[i]; j++){
            v[id].push_back(now);
            now *= com(cnt[i]-j*2,2);
            now *= inv[j+1];
        }
        se.emplace(P(v[id].size(), id));
        id++;
    }
    while(se.size() > 1){
        int f = (*se.begin()).second;
        se.erase(se.begin());
        int s = (*se.begin()).second;
        se.erase(se.begin());
        v[id] = convolution(v[f], v[s]);
        int sz = v[id].size();
        se.emplace(sz, id);
        id++;
    }
    id--;
    mint ans = dfact[N];
    if(id >= 0){
        REP(i,1,v[id].size()){
            if(i & 1) ans -= dfact[N-i*2] * v[id][i];
            else ans += dfact[N-i*2] * v[id][i];
        }
    }
    cout << ans.val() << "\n";
}

Measured memory_bytes: 27044