Problem:
Score : 600 points

Problem Statement

There are 2N people numbered 1 through 2N.
The height of Person i is h_i.

How many ways are there to make N pairs of people such that the following conditions are satisfied?
Compute the answer modulo 998,244,353.

Each person is contained in exactly one pair.

For each pair, the heights of the two people in the pair are different.

Two ways are considered different if for some p and q, Person p and Person q are paired in one way and not in the other.

Constraints

1 \leq N \leq 50,000

1 \leq h_i \leq 100,000

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
h_1
:
h_{2N}

Output

Print the answer.

Sample Input 1

2
1
1
2
3

Sample Output 1

2

There are two ways:

Form the pair (Person 1, Person 3) and the pair (Person 2, Person 4).

Form the pair (Person 1, Person 4) and the pair (Person 2, Person 3).

Sample Input 2

5
30
10
20
40
20
10
10
30
50
60

Sample Output 2

516

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

// #include <ext/pb_ds/assoc_container.hpp>
#include <bits/stdc++.h>
using namespace std;
// using namespace __gnu_pbds;
// template <class c, class cmp = less<c> > using ordered_set = tree<c, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...) 
#endif
template<class T> ostream& operator<<(ostream &os, vector<T> V) {os << "[ "; for(auto v : V) os << v << " "; return os << "]";}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {return os << "(" << P.first << "," << P.second << ")";}
template <typename T,typename U>pair<T,U> operator+(const pair<T,U> & l,const std::pair<T,U> & r) { return {l.first+r.first,l.second+r.second};}
typedef long long int ll;
const ll mod =1e9+7;
const int maxn = 300002;
#define endl '\n'
//#define ld long double
#define int ll
#define all(x)  (x).begin(),(x).end()

const ll md = (ll) 998244353;

const int MOD = md;
#define PI_m acos(-1)
//use mul(vector<int> a,vector<int> b) to multiply two polynomials a and b
//the higher power coefficients have the higher index in the vectors
//the mul function will return a vector of long long
//If mod is different just change the above predefined mod
 
namespace FFT // taken from https://www.codechef.com/viewsolution/11939789
{
#define fore(i, a, b) for(int i = (int)(a); i <= (int)(b); ++i)
#define forn(i, n) for(int i = 0; i < (int)(n); ++i)
typedef long double ld;
struct base
{
    typedef long double T;
    T re, im;
    base() :re(0), im(0) {}
    base(T re) :re(re), im(0) {}
    base(T re, T im) :re(re), im(im) {}
    base operator + (const base& o) const
    {
        return base(re + o.re, im + o.im);
    }
    base operator - (const base& o) const
    {
        return base(re - o.re, im - o.im);
    }
    base operator * (const base& o) const
    {
        return base(re * o.re - im * o.im, re * o.im + im * o.re);
    }
    base operator * (ld k) const
    {
        return base(re * k, im * k) ;
    }
    base conj() const
    {
        return base(re, -im);
    }
};
const int N = 20;
const int MAXN = (1<<N);
base w[MAXN];
base f1[MAXN];
int rev[MAXN];
void build_rev(int k)
{
    static int rk = -1;
    if( k == rk )return ;
    rk = k;
    fore(i, 1, (1<<k) )
    {
        int j = rev[i-1], t = k-1;
        while( t >= 0 && ((j>>t)&1) )
        {
            j ^= 1 << t;
            --t;
        }
        if( t >= 0 )
        {
            j ^= 1 << t;
            --t;
        }
        rev[i] = j;
    }
}
void fft(base *a, int k)
{
    build_rev(k);
    int n = 1 << k;
    forn(i, n) if( rev[i] > i ) swap(a[i], a[rev[i]]);
    for(int l = 2, lll = 1; l <= n; l += l, lll += lll)
    {
        if( w[lll].re == 0 && w[lll].im == 0 )
        {
            ld angle = PI_m / lll;
            base ww( cosl(angle), sinl(angle) );
            if( lll > 1 ) for(int j = 0; j < lll; ++j)
                {
                    if( j & 1 ) w[lll + j] = w[(lll+j)/2] * ww;
                    else w[lll + j] = w[(lll+j)/2];
                }
            else w[lll] = base(1, 0);
        }
        for(int i = 0; i < n; i += l) forn(j, lll)
        {
            base v = a[i + j], u = a[i + j + lll] * w[lll + j];
            a[i + j] = v + u;
            a[i + j + lll] = v - u;
        }
    }
}
vector<int> mul(const vector<int>& a, const vector<int>& b)
{
    int k = 1;
    while( (1<<k) < (a.size() + b.size()) ) ++k;
    int n = (1<<k);
    forn(i, n) f1[i] = base(0,0);
    forn(i, a.size()) f1[i] = f1[i] + base(a[i], 0);
    forn(i, b.size()) f1[i] = f1[i] + base(0, b[i]);
    fft(f1, k);
    forn(i, 1 + n/2)
    {
        base p = f1[i] + f1[(n-i)%n].conj();
        base _q = f1[(n-i)%n] - f1[i].conj();
        base q(_q.im, _q.re);
        f1[i] = (p * q) * 0.25;
        if( i > 0 ) f1[(n - i)] = f1[i].conj();
    }
    forn(i, n) f1[i] = f1[i].conj();
    fft(f1, k);
    vector<int> r(a.size() + b.size());
    forn(i, r.size() )
    {
        r[i] = ll (f1[i].re / n + 0.5) % MOD;
    }
    return r;
}
}


 
inline ll add(ll a, ll b) {
  a += b;
  if (a >= md) a -= md;
  return a;
}
 
inline ll sub(ll a, ll b) {
  a -= b;
  if (a < 0) a += md;
  return a;
}
 
inline ll mul(ll a, ll b) {
  return (ll) ((long long)((a%md) * (b%md)) % md);
}
 
inline ll power(ll a, long long b) {
  ll res = 1;
  while (b > 0) {
    if (b & 1) {
      res = mul(res, a);
    }
    a = mul(a, a);
    b >>= 1;
  }
  return res;
}
 
inline ll inv(ll a) {
  a %= md;
  if (a < 0) a += md;
  ll b = md, u = 0, v = 1;
  while (a) {
    ll t = b / a;
    b -= t * a; swap(a, b);
    u -= t * v; swap(u, v);
  }
  assert(b == 1);
  if (u < 0) u += md;
  return u;
}

vector<int> fact(maxn+5);
void init (int n)
{
  fact[0] = 1;
  for(int i = 1;i<=n;i++)
  {
    fact[i] = mul(i,fact[i-1]);
  }
}
int nck(int n,int k)
{
  return mul(fact[n],mul(inv(fact[k]),inv(fact[n-k])));
}

vector<vector<int>> v;
vector<int> solve(int l, int r){
  if(l == r)
    return v[l];
  int mid = (l+r)>>1;
  vector<int> a = solve(l,mid);
  vector<int> b = solve(mid+1,r);
  return FFT::mul(a,b);
}

int32_t main(){

  IOS

  int n;
  cin >> n;
  n*=2;
  init(100001);
  vector<int> a(n);
  map<int,int> m;
  for(int i = 0;i<n;i++){
    cin >> a[i];
    m[a[i]]++;
  }

  for(auto i:m){
    if(i.second > 1){
      v.push_back({1,nck(i.second,2)});
    }
  }
  

  if(v.empty()){
    int res = mul(1,mul(fact[n],mul(inv(power(2,(n/2))),inv(fact[(n/2)]))));
    cout << res << endl;
    return 0;
  }
  auto ans = solve(0,v.size() - 1);
  int res = 0;
  for(int i = 0;i<ans.size();i++){
    if(i%2 == 0){
      res = add(res,mul(ans[i],mul(fact[n-2*i],mul(inv(power(2,(n/2) - i)),inv(fact[(n/2) - i])))));
    }
    else{
      res = sub(res,mul(ans[i],mul(fact[n-2*i],mul(inv(power(2,(n/2) - i)),inv(fact[(n/2) - i])))));
    }
  }

  cout << res << endl;
  

  
  

  

  
    
}