struct Scanner {
    private var elements = [String]()
    private var index = 0

    mutating func peek() -> String {
        while elements.count == index {
            elements = readLine()!.split(separator: " ").map(String.init)
            index = 0
        }
        return elements[index]
    }

    mutating func next() -> String {
        let value = peek()
        index += 1
        return value
    }

    mutating func nextInt() -> Int {
        return Int(next())!
    }

    mutating func nextDouble() -> Double {
        return Double(next())!
    }
}

let MOD = 998244353

struct Zn: CustomStringConvertible {
    let n: Int

    init(_ n: Int) {
        self.n = n
    }

    var description: String {
        String(self.n)
    }

    static var zero = Zn(0)
    static var one = Zn(1)

    static func + (lhs: Self, rhs: Self) -> Self {
        let n = lhs.n + rhs.n
        return Zn(n < MOD ? n : n - MOD)
    }

    static func + (lhs: Self, rhs: Int) -> Self {
        return lhs + Zn(rhs)
    }

    static func + (lhs: Int, rhs: Self) -> Self {
        return Zn(lhs) + rhs
    }

    static func - (lhs: Self, rhs: Self) -> Self {
        let n = lhs.n - rhs.n
        return Zn(n >= 0 ? n : n + MOD)
    }

    static func - (lhs: Self, rhs: Int) -> Self {
        return lhs - Zn(rhs)
    }

    static func - (lhs: Int, rhs: Self) -> Self {
        return Zn(lhs) - rhs
    }

    static func * (lhs: Self, rhs: Self) -> Self {
        Zn((lhs.n * rhs.n) % MOD)
    }

    static func * (lhs: Self, rhs: Int) -> Self {
        return lhs * Zn(rhs)
    }

    static func * (lhs: Int, rhs: Self) -> Self {
        return Zn(lhs) * rhs
    }

    static func += (lhs: inout Self, rhs: Self) {
        lhs = lhs + rhs
    }

    static func += (lhs: inout Self, rhs: Int) {
        lhs = lhs + Zn(rhs)
    }

    static func -= (lhs: inout Self, rhs: Self) {
        lhs = lhs - rhs
    }

    static func -= (lhs: inout Self, rhs: Int) {
        lhs = lhs - Zn(rhs)
    }

    static func *= (lhs: inout Self, rhs: Self) {
        lhs = lhs * rhs
    }

    static func *= (lhs: inout Self, rhs: Int) {
        lhs = lhs * Zn(rhs)
    }

    func pow(_ n: Int) -> Self {
        if n == 0 {
            return Zn(1)
        } else if n % 2 == 1 {
            return self * self.pow(n - 1)
        } else {
            return (self * self).pow(n / 2)
        }
    }

    var inverse: Self {
        self.pow(MOD - 2)
    }
}


func prod(_ a: [Zn], _ b: [Zn]) -> [Zn] {
    var result = [Zn](repeating: .zero, count: a.count + b.count - 1)
    for i in a.indices {
        for j in b.indices {
            result[i + j] += a[i] * b[j]
        }
    }
    return result
}

var f = [Zn](repeating: .zero, count: 50001)
f[0] = Zn(1)
for i in 1 ... 50000 {
    f[i] = f[i - 1] * (2 * i - 1)
}

var scanner = Scanner()

let N = scanner.nextInt()
let H = (0 ..< 2 * N).map{ _ in scanner.nextInt() }

var count = [Int](repeating: 0, count: 100001)
for h in H {
    count[h] += 1
}

var A = [Int]()
for i in 0 ... 100000 where count[i] > 0 {
    A.append(count[i])
}

var fact = [Zn](repeating: Zn(1), count: 100001)
for i in 1 ... 100000 {
    fact[i] = fact[i - 1] * i
}

func C(_ n: Int, _ r: Int) -> Zn {
    if n >= 0 && r >= 0 && n >= r {
        return fact[n] * fact[n - r].inverse * fact[r].inverse
    } else {
        return .zero
    }
}

var g = [[Zn]]()

for a in A {
    var h = [Zn]()
    for i in 0 ... a / 2 {
        h.append(C(a, 2 * i) * f[i] * (i % 2 == 0 ? Zn(1) : Zn(MOD - 1)))
    }
    g.append(h)
}
var h = g.sorted{ a, b in a.count < b.count }.reduce([Zn(1)], prod)

var answer = Zn(0)
for i in 0 ... N where N - i < h.count {
    answer += f[i] * h[N - i]
}
print(answer)



