/* by Natsu Kinmoe */
#include <bits/stdc++.h>
using namespace std;
#define SZ(x)               ((int)(x).size())
#define all(x)              (x).begin(), (x).end()
#define loop(i, n)          for(int i = 0; i < (n); i++)
#define cont(i, n)          for(int i = 1; i <= (n); i++)
#define circ(i, a, b)       for(int i = (a); i <= (b); i++)
#define range(i, a, b, c)   for(int i = (a); ((c) > 0 ? i <= (b) : i >= (b)); i += (c))
#define foreach(it, v)      for(__typeof((v).begin()) it = (v).begin(); it != (v).end(); it++)
#define y0          y0O0OO00OO0OO0OO0OOO00OO0OO0O0O000OO0
#define y1          y1II11II11III11I1III11II111IIII1II1I1
#define pub         push_back
#define pob         pop_back
#define mak         make_pair
typedef long long   ll;
typedef long double lf;
const int   Inf = 0x3f3f3f3f;
const ll    INF = 0x3f3f3f3f3f3f3f3fll;
/* Source code starts here */

const int jt = 998244353, rg = 3;

int ho[20][1 << 19];

int ksmii(int a, int b) {
	if(!b) return 1;
	int x = ksmii(a, b >> 1);
	x = 1ll * x * x % jt;
	if(b & 1) x = 1ll * x * a % jt;
	return x;
}

void inline fft(vector<int> &a, int L, int l, int inv) {
	if(!ho[l][1]) {
		loop(i, L) ho[l][i] = (ho[l][i >> 1] >> 1) | ((i & 1) << (l - 1));
	}
	loop(i, L) if(ho[l][i] < i) swap(a[i], a[ho[l][i]]);
	range(i, 1, L - 1, i) {
		int omega = ksmii(rg, ~inv ? (jt - 1) / (i << 1) : (jt - 1) - (jt - 1) / (i << 1));
		range(j, 0, L - 1, i << 1) {
			int omg = 1;
			loop(k, i) {
				int x = a[j + k], y = 1ll * omg * a[j + k + i] % jt;
				a[j + k] = (x + y) % jt;
				a[j + k + i] = (x - y + jt) % jt;
				omg = 1ll * omg * omega % jt;
			}
		}
	}
	if(!~inv) {
		int fn = ksmii(L, jt - 2);
		loop(i, L) a[i] = 1ll * a[i] * fn % jt;
	}
}

int n, m, cnt[1 << 17];
int jc[1 << 17], fjc[1 << 17], mii[1 << 17], ms[1 << 17];
vector<vector<int> > v;
int vs;

int inline binom(int a, int b) {
	if(a < b || a < 0 || b < 0) return 0;
	return 1ll * jc[a] * fjc[b] % jt * fjc[a - b] % jt;
}

int inline dfs(int l, int r) {
	if(l == r) {
		v.pub(vector<int>()); int now = vs++;
		loop(i, (cnt[l] >> 1) + 1) v[now].pub(1ll * binom(cnt[l], i << 1) * jc[i << 1] % jt * mii[i] % jt * fjc[i] % jt);
		return now;
	}
	int m = (l + r) >> 1;
	int lv = dfs(l, m), rv = dfs(m + 1, r);
	int len = SZ(v[lv]), ren = SZ(v[rv]);
	int L = 1, ln = 0;
	while(L < len + ren + 5) {
		L <<= 1; ln++;
	}
	while(SZ(v[lv]) < L) v[lv].pub(0);
	while(SZ(v[rv]) < L) v[rv].pub(0);
	fft(v[lv], L, ln, 1); fft(v[rv], L, ln, 1);
	loop(i, L) v[lv][i] = 1ll * v[lv][i] * v[rv][i] % jt;
	fft(v[lv], L, ln, -1); v[rv].clear();
	while(!v[lv].back()) v[lv].pob();
	return lv;
}

int main() {
	scanf("%d", &m); n = m << 1;
	jc[0] = 1; cont(i, n) jc[i] = 1ll * jc[i - 1] * i % jt;
	fjc[n] = ksmii(jc[n], jt - 2); range(i, n, 1, -1) fjc[i - 1] = 1ll * fjc[i] * i % jt;
	mii[0] = ms[0] = 1; mii[1] = ksmii(2, jt - 2); ms[1] = 2;
	circ(i, 2, n) mii[i] = 1ll * mii[i - 1] * mii[1] % jt, ms[i] = 2ll * ms[i - 1] % jt;
	cont(i, n) {
		int h; scanf("%d", &h);
		cnt[h]++;
	}
	int id = dfs(0, (1 << 17) - 1);
	vector<int> &dp = v[id];
	int ans = 0;
	loop(i, SZ(dp)) {
		if(!(i & 1)) ans = (ans + 1ll * jc[n - 2 * i] * mii[m - i] % jt * fjc[m - i] % jt * dp[i]) % jt;
		else ans = (ans - 1ll * jc[n - 2 * i] * mii[m - i] % jt * fjc[m - i] % jt * dp[i] % jt + jt) % jt;
	}
	printf("%d\n", ans);
	return 0;
}


Measured memory_bytes: 20504