#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-5;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

template< int mod >
struct NumberTheoreticTransform {

	vector< int > rev, rts;
	int base, max_base, root;

	NumberTheoreticTransform() : base(1), rev{ 0, 1 }, rts{ 0, 1 } {
		assert(mod >= 3 && mod % 2 == 1);
		auto tmp = mod - 1;
		max_base = 0;
		while (tmp % 2 == 0) tmp >>= 1, max_base++;
		root = 2;
		while (mod_pow(root, (mod - 1) >> 1) == 1) ++root;
		assert(mod_pow(root, mod - 1) == 1);
		root = mod_pow(root, (mod - 1) >> max_base);
	}

	inline int mod_pow(int x, int n) {
		int ret = 1;
		while (n > 0) {
			if (n & 1) ret = mul(ret, x);
			x = mul(x, x);
			n >>= 1;
		}
		return ret;
	}

	inline int inverse(int x) {
		return mod_pow(x, mod - 2);
	}

	inline unsigned add(unsigned x, unsigned y) {
		x += y;
		if (x >= mod) x -= mod;
		return x;
	}

	inline unsigned mul(unsigned a, unsigned b) {
		return 1ull * a * b % (unsigned long long) mod;
	}

	void ensure_base(int nbase) {
		if (nbase <= base) return;
		rev.resize(1 << nbase);
		rts.resize(1 << nbase);
		for (int i = 0; i < (1 << nbase); i++) {
			rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
		}
		assert(nbase <= max_base);
		while (base < nbase) {
			int z = mod_pow(root, 1 << (max_base - 1 - base));
			for (int i = 1 << (base - 1); i < (1 << base); i++) {
				rts[i << 1] = rts[i];
				rts[(i << 1) + 1] = mul(rts[i], z);
			}
			++base;
		}
	}

	void ntt(vector< int > &a) {
		const int n = (int)a.size();
		assert((n & (n - 1)) == 0);
		int zeros = __builtin_ctz(n);
		ensure_base(zeros);
		int shift = base - zeros;
		for (int i = 0; i < n; i++) {
			if (i < (rev[i] >> shift)) {
				swap(a[i], a[rev[i] >> shift]);
			}
		}
		for (int k = 1; k < n; k <<= 1) {
			for (int i = 0; i < n; i += 2 * k) {
				for (int j = 0; j < k; j++) {
					int z = mul(a[i + j + k], rts[j + k]);
					a[i + j + k] = add(a[i + j], mod - z);
					a[i + j] = add(a[i + j], z);
				}
			}
		}
	}

	vector< int > multiply(vector< int > a, vector< int > b) {
		int need = a.size() + b.size() - 1;
		int nbase = 1;
		while ((1 << nbase) < need) nbase++;
		ensure_base(nbase);
		int sz = 1 << nbase;
		a.resize(sz, 0);
		b.resize(sz, 0);
		ntt(a);
		ntt(b);
		int inv_sz = inverse(sz);
		for (int i = 0; i < sz; i++) {
			a[i] = mul(a[i], mul(b[i], inv_sz));
		}
		reverse(a.begin() + 1, a.end());
		ntt(a);
		a.resize(need);
		return a;
	}
};

long long int power(long long int x, long long int n, long long int M) {
	long long int ret = 1;
	long long int by = x;
	while (n) {
		if (n & 1) {
			ret *= by;
			ret %= M;
		}
		by *= by;
		by %= M;
		n >>= 1;
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N;
	vector<int>num(100001);
	for (int i = 0; i < 2 * N; i++) {
		cin >> M;
		num[M]++;
	}
	NumberTheoreticTransform<998244353>ntt;
	vector<vector<int>>box(100001);
	vector<long long int>by(200001, 1);
	vector<long long int>rev(200001, 1);
	for (int i = 1; i <= 200000; i++) {
		by[i] = by[i - 1] * i%MOD;
		rev[i] = power(by[i], MOD - 2, MOD);
	}
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>PQ;
	for (int i = 1; i <= 100000; i++) {
		if (num[i] / 2 == 0)continue;
		vector<int>v(num[i] / 2 + 1, 1);
		for (int j = 1; j <= num[i] / 2; j++) {
			v[j] = by[num[i]] * rev[num[i] - 2 * j] % MOD*rev[j] % MOD*power(rev[2], j, MOD) % MOD;;
		}
		box[i] = v;
		PQ.push({ num[i] / 2,i });
	}
	if (PQ.empty()) {
		cout << by[N * 2] % MOD*rev[N] % MOD*power(rev[2], N, MOD) % MOD << endl;
		return 0;
	}
	while (PQ.size() > 1) {
		auto a = PQ.top();
		PQ.pop();
		auto b = PQ.top();
		PQ.pop();
		box[a.second] = ntt.multiply(box[a.second], box[b.second]);
		PQ.push({ box[a.second].size() - 1,a.second });
	}
	long long int ans = 0;
	for (int i = 0; i <= PQ.top().first; i++) {
		if (i & 1) {
			ans += MOD - box[PQ.top().second][i] * by[N * 2 - i * 2] % MOD*rev[N - i] % MOD*power(rev[2], N - i, MOD) % MOD;
		}
		else {
			ans += box[PQ.top().second][i] * by[N * 2 - i * 2] % MOD*rev[N - i] % MOD*power(rev[2], N - i, MOD) % MOD;
		}
	}
	cout << ans % MOD << endl;
}


Measured memory_bytes: 14900