#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define rint register int
#define rep(i,l,r) for(rint i=l;i<=r;i++)
#define per(i,l,r) for(rint i=l;i>=r;i--)
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pb push_back
#define fir first
#define sec second
#define mset(s,t) memset(s,t,sizeof(s))
template<typename T1,typename T2>void ckmin(T1 &a,T2 b){if(a>b)a=b;}
template<typename T1,typename T2>void ckmax(T1 &a,T2 b){if(a<b)a=b;}
template<typename T>T gcd(T a,T b){return b?gcd(b,a%b):a;}
int read(){
  int x=0,f=0;
  char ch=getchar();
  while(!isdigit(ch))f|=ch=='-',ch=getchar();
  while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
  return f?-x:x;
}
const int N=200005;
const int mod=998244353;
const int G=3;
const int Gi=332748118;
const int inv2=499122177;

int aa[N],b[N],n,m;

int fac[N],ifac[N];
int qpow(int a,int b=mod-2){
  int res=1;
  while(b>0){
    if(b&1)res=1ll*res*a%mod;
    a=1ll*a*a%mod;
    b>>=1;
  }
  return res;
}
int ipw[N<<1];
void init(int n){
  fac[0]=ifac[0]=ipw[0]=1;
  for(int i=1;i<=n;i++)ipw[i]=1ll*ipw[i-1]*inv2%mod;
  for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod;
  ifac[n]=qpow(fac[n],mod-2);
  for(int i=n-1;i>=1;i--)ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
}
int C(int n,int m){
  return 1ll*fac[n]*ifac[n-m]%mod*ifac[m]%mod;
}
vector<int>a[N<<3];
int tot=0;
int r[N<<1],lim=1,L=0;
void getR(int n){
  lim=1,L=0;
  while(lim<=n)lim<<=1,L++;
  for(int i=0;i<lim;i++)r[i]=(r[i>>1]>>1)|((i&1)<<L-1); 
} 
void NTT(vector<int>&a,int opt){
  for(int i=0;i<lim;i++)if(i<r[i])swap(a[i],a[r[i]]);
  for(int mid=1;mid<lim;mid<<=1){
    int Wn=qpow(opt==1?G:Gi,(mod-1)/(mid<<1));
    for(int j=0;j<lim;j+=mid<<1){
      int W=1;
      for(int k=0;k<mid;k++,W=1ll*W*Wn%mod){
        int x=a[j+k],y=1ll*W*a[j+k+mid]%mod;
        a[j+k]=(x+y)%mod;
        a[j+k+mid]=(x-y+mod)%mod;
      }
    }
  }
  if(opt==-1){
    int linv=qpow(lim,mod-2);
    for(int i=0;i<lim;i++)a[i]=1ll*a[i]*linv%mod;
  }
}
vector<int>mul(vector<int>a,vector<int>b){
  int len=a.size()+b.size()-1;
  getR(len);
  a.resize(lim+1),b.resize(lim+1);
  NTT(a,1),NTT(b,1);
  for(register int i=0;i<lim;i++)a[i]=1ll*a[i]*b[i]%mod;
  NTT(a,-1);
  a.resize(len);
  return a;
}
vector<int> solve(int l,int r){
  if(l==r){
    ++tot;
    a[tot].resize(b[l]/2+1);
    for(register int i=0;i<=b[l]/2;i++){
      /*
      if(i==0)a[tot][i]=1;
      else a[tot][i]=1ll*C(b[l],i)*C(b[l]-i,i)%mod*fac[i]%mod;
      */
      a[tot][i]=1ll*fac[b[l]]*ifac[b[l]-2*i]%mod*ifac[i]%mod*ipw[i]%mod;
      //printf("pre     id=%d\n",l);
      //printf("a[%d][%d]=%d\n",tot,i,a[tot][i]);
      //a[tot][i]=1ll*a[tot][i]*ifac[i]%mod;
      //printf("suf     id=%d\n",l);
      //printf("a[%d][%d]=%d\n",tot,i,a[tot][i]);
    }
    return a[tot];
  }
  int mid=l+r>>1;
  vector<int>ls=solve(l,mid),rs=solve(mid+1,r);
  ++tot;
  a[tot]=mul(ls,rs);
  return a[tot];
}
int main(){
  init(2e5);
  n=read()*2;
  for(int i=1;i<=n;i++)aa[i]=read();
  sort(aa+1,aa+n+1);
  for(int i=1;i<=n;i++){
    int j=i;
    while(j<=n&&aa[i]==aa[j])j++;
    int len=j-i;
    b[++m]=len;
    i=j-1;
  }
  vector<int>ans=solve(1,m);
  //assert(ans.size()==n+1);
  n/=2;
  int Ans=0;
  for(register int k=0;k<=n&&k<ans.size();k++){
    //printf("ans[%d]=%d\n",k,ans[k]);
    if(k&1){
      Ans=(Ans-1ll*ans[k]*fac[2*n-2*k]%mod*ifac[n-k]%mod*ipw[n-k]%mod)%mod;
    }else{
      Ans=(Ans+1ll*ans[k]*fac[2*n-2*k]%mod*ifac[n-k]%mod*ipw[n-k]%mod)%mod;
    }
    //printf("Ans=%d\n",Ans);
  }
  Ans=(Ans%mod+mod)%mod; 
  printf("%lld\n",Ans);
  return 0; 
}

Measured memory_bytes: 50452