//Author - Rahil Malhotra
#include <bits/stdc++.h>
using namespace std;
 
template <typename T> void print(T t) { cout<<t<<endl; }
template<typename T, typename... Args> void print(T t, Args... args) { cout<<t<<" "; print(args...); }
 
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl '\n'
#define int long long
#define double long double

int mod=998244353;
int md=998244353;

inline void add(int &a, int b) {
  a += b;
  if (a >= md) a -= md;
}

inline void sub(int &a, int b) {
  a -= b;
  if (a < 0) a += md;
}

inline int mul(int a) {
  return a;
}

template<typename... T>
inline int mul(int a, T... b) {
  return (int) ((long long) a * mul(b...) % md);
}

inline int power(int a, long long b) {
  int res = 1;
  while (b > 0) {
    if (b & 1) {
      res = mul(res, a);
    }
    a = mul(a, a);
    b >>= 1;
  }
  return res;
}

inline int inv(int a) {
  a %= md;
  if (a < 0) a += md;
  int b = md, u = 0, v = 1;
  while (a) {
    int 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;
}

namespace ntt {
  int base = 1;
  vector<int> roots = {0, 1};
  vector<int> rev = {0, 1};
  int max_base = -1;
  int root = -1;

  void init() {
    int tmp = md - 1;
    max_base = 0;
    while (tmp % 2 == 0) {
      tmp /= 2;
      max_base++;
    }
    root = 2;
    while (true) {
      if (power(root, 1 << max_base) == 1) {
        if (power(root, 1 << (max_base - 1)) != 1) {
          break;
        }
      }
      root++;
    }
  }

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

  void fft(vector<int> &a) {
    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 x = a[i + j];
          int y = mul(a[i + j + k], roots[j + k]);
          a[i + j] = x + y - md;
          if (a[i + j] < 0) a[i + j] += md;
          a[i + j + k] = x - y + md;
          if (a[i + j + k] >= md) a[i + j + k] -= md;
        }
      }
    }
  }

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

  vector<int> square(vector<int> a) {
    return multiply(a, a, 1);
  }
}

int n;
map<int,int>mp;
int fact[200005];
int premul[200005];
int grp;
vector<int>v[200005];
vector<int>tree[700005];
int inver(int x)
{
    int r,y;
    for(r=1,y=mod-2;y>0;x=(x*x)%mod,y/=2)
        if(y%2==1)
            r=r*x%mod;
    return r;
}
int nCr(int n, int m)
{
    if(n<m)
        return 0;
    return fact[n] *inver(fact[m])%mod *inver(fact[n-m])%mod ;
}
void mulall(int i,int l,int r)
{
    if(l==r)
    {
        tree[i]=v[l];
        return ;
    }
    int mid=(l+r)/2;
    mulall(i*2,l,mid);
    mulall(i*2+1,mid+1,r);
    tree[i]=ntt::multiply(tree[i*2],tree[i*2+1]);
}
int32_t main()
{
    IOS;
    cin>>n;
    premul[1]=1;
    for(int i=3;i<=2*n-1;i++)
        premul[i]=(i*premul[i-2])%mod;
    fact[0]=1;
    for(int i=1;i<=200001;i++)
        fact[i]=(i*fact[i-1])%mod;
    for(int i=0;i<2*n;i++)
    {
        int a;
        cin>>a;
        mp[a]++;
    }
    grp=mp.size();
    int ctr=0;
    for(auto i:mp)
    {
        v[ctr].push_back(1);
        int sz=i.second;
        int val=1;
        for(int j=1;j<=sz/2;j++)
        {
            int a=nCr(sz,2*j);
            int arrange=premul[2*j-1];
            int val=(a*arrange)%mod;
            v[ctr].push_back(val);
        }
        ctr++;
    }
    // for(int i=0;i<grp;i++)
    // {
    //     for(int j:v[i])
    //         cout<<j<<" ";
    //     cout<<endl;
    // }
    mulall(1,0,ctr-1);
    vector<int>fin=tree[1];
    int ct=n;
    int ans=0;
    int st=0;
    for(auto i:fin)
    {
        if(st%2==0)
        {
            int get=0;
            if(ct==0)
                get=i;
            else
                get=(premul[2*ct-1]*i)%mod;
            ans=(ans+get)%mod;
        }
        else
        {
            int get=0;
            if(ct==0)
                get=i;
            else
                get=(premul[2*ct-1]*i)%mod;
            ans=(ans-get+mod)%mod;
        }
        //cout<<st<<" "<<ct<<" "<<i<<" "<<ans<<endl;
        ct--;
        st++;
        //cout<<i<<" ";
    }
    cout<<ans<<endl;
}



Measured memory_bytes: 42588