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 Rust (1.42.0) (judge verdict: Time Limit Exceeded)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use competitive::prelude::*;
use memoise::{memoise, memoise_map};

type GF = competitive::gf::GF<promote!(998_244_353)>;

#[argio(output = AtCoder)]
fn main(n: usize, mut h: [usize; n * 2]) -> GF {
    h.sort();

    let mut ret = GF::new(0);

    let mut mm = BTreeMap::<usize, usize>::new();
    for h in h.iter() {
        *mm.entry(*h).or_default() += 1;
    }

    let a = mm.values().cloned().collect::<Vec<_>>();

    for i in 0..=n {
        let t = solve(0, i, &a) * fact2(n * 2 - i * 2);
        if i % 2 == 0 {
            ret += t;
        } else {
            ret -= t;
        }
    }

    ret
}

#[memoise_map(ix, rest)]
fn solve(ix: usize, rest: usize, a: &[usize]) -> GF {
    if rest == 0 {
        return GF::new(1);
    }
    if ix >= a.len() {
        return GF::new(0);
    }

    let mut ret = GF::new(0);

    for i in 0..=min(rest, a[ix] / 2) {
        ret += solve(ix + 1, rest - i, a) * comb(a[ix], i * 2) * fact2(i * 2);
    }

    ret
}

#[memoise(i)]
fn fact2(i: usize) -> GF {
    if i == 0 {
        GF::new(1)
    } else {
        fact2(i - 2) * (i - 1)
    }
}

#[memoise(i)]
fn fact(i: usize) -> GF {
    if i == 0 {
        GF::new(1)
    } else {
        fact(i - 1) * i
    }
}

fn comb(n: usize, k: usize) -> GF {
    fact(n) / (fact(k) * fact(n - k))
}
*/

fn main() {
    let exe = "/tmp/bin60D22BB6";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";