You are given a sequence of $n$ pairs of integers: $(a_1, b_1), (a_2, b_2), \dots , (a_n, b_n)$. This sequence is called bad if it is sorted in non-descending order by first elements or if it is sorted in non-descending order by second elements. Otherwise the sequence is good. There are examples of good and bad sequences:  $s = [(1, 2), (3, 2), (3, 1)]$ is bad because the sequence of first elements is sorted: $[1, 3, 3]$;  $s = [(1, 2), (3, 2), (1, 2)]$ is bad because the sequence of second elements is sorted: $[2, 2, 2]$;  $s = [(1, 1), (2, 2), (3, 3)]$ is bad because both sequences (the sequence of first elements and the sequence of second elements) are sorted;  $s = [(1, 3), (3, 3), (2, 2)]$ is good because neither the sequence of first elements $([1, 3, 2])$ nor the sequence of second elements $([3, 3, 2])$ is sorted. 

Calculate the number of permutations of size $n$ such that after applying this permutation to the sequence $s$ it turns into a good sequence. 

A permutation $p$ of size $n$ is a sequence $p_1, p_2, \dots , p_n$ consisting of $n$ distinct integers from $1$ to $n$ ($1 \le p_i \le n$). If you apply permutation $p_1, p_2, \dots , p_n$ to the sequence $s_1, s_2, \dots , s_n$ you get the sequence $s_{p_1}, s_{p_2}, \dots , s_{p_n}$. For example, if $s = [(1, 2), (1, 3), (2, 3)]$ and $p = [2, 3, 1]$ then $s$ turns into $[(1, 3), (2, 3), (1, 2)]$.


-----Input-----

The first line contains one integer $n$ ($1 \le n \le 3 \cdot 10^5$).

The next $n$ lines contains description of sequence $s$. The $i$-th line contains two integers $a_i$ and $b_i$ ($1 \le a_i, b_i \le n$) — the first and second elements of $i$-th pair in the sequence.

The sequence $s$ may contain equal elements.


-----Output-----

Print the number of permutations of size $n$ such that after applying this permutation to the sequence $s$ it turns into a good sequence. Print the answer modulo $998244353$ (a prime number).


-----Examples-----
Input
3
1 1
2 2
3 1

Output
3

Input
4
2 3
2 2
2 1
2 4

Output
0

Input
3
1 1
1 1
2 3

Output
4



-----Note-----

In first test case there are six permutations of size $3$:   if $p = [1, 2, 3]$, then $s = [(1, 1), (2, 2), (3, 1)]$ — bad sequence (sorted by first elements);  if $p = [1, 3, 2]$, then $s = [(1, 1), (3, 1), (2, 2)]$ — bad sequence (sorted by second elements);  if $p = [2, 1, 3]$, then $s = [(2, 2), (1, 1), (3, 1)]$ — good sequence;  if $p = [2, 3, 1]$, then $s = [(2, 2), (3, 1), (1, 1)]$ — good sequence;  if $p = [3, 1, 2]$, then $s = [(3, 1), (1, 1), (2, 2)]$ — bad sequence (sorted by second elements);  if $p = [3, 2, 1]$, then $s = [(3, 1), (2, 2), (1, 1)]$ — good sequence.

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Combinatorics


Solutions:
from sys import stdin, stdout
from collections import defaultdict
import math
import copy
N = int(input())
permu = [0] * N
permu[0] = 1
for i in range(1, N):
	permu[i] = permu[i - 1] * (i + 1) % 998244353
data = []
pair = {}
for i in range(N):
	(a, b) = [int(x) for x in stdin.readline().split()]
	data.append((a, b))
	if a not in pair:
		pair[a] = []
	pair[a].append(b)
freq_one = {}
for i in range(N):
	a = data[i][0]
	if a not in freq_one:
		freq_one[a] = 1
	else:
		freq_one[a] += 1
all = permu[-1]
p1 = 1
for key in freq_one:
	f = freq_one[key]
	p1 *= permu[f - 1]
	p1 = p1 % 998244353
freq_two = {}
for i in range(N):
	a = data[i][1]
	if a not in freq_two:
		freq_two[a] = 1
	else:
		freq_two[a] += 1
p2 = 1
for key in freq_two:
	f = freq_two[key]
	p2 *= permu[f - 1]
	p2 = p2 % 998244353
max_second = 0
P = list(pair.keys())
P.sort()
p3 = 1
for key in P:
	mini = min(pair[key])
	if mini < max_second:
		p3 = 0
		break
	f = {}
	for a in pair[key]:
		if a not in f:
			f[a] = 1
		else:
			f[a] += 1
	p = 1
	for num in f:
		fr = f[num]
		p *= permu[fr - 1]
		p = p % 998244353
	p3 *= p
	p3 = p3 % 998244353
	max_second = max(pair[key])
ans = (all - p1 - p2 + p3) % 998244353
print(ans)


from operator import itemgetter
import sys

class Combination:

	def __init__(self, n, MOD):
		self.fact = [1]
		for i in range(1, n + 1):
			self.fact.append(self.fact[-1] * i % MOD)
input = sys.stdin.readline
n = int(input())
p = [list(map(int, input().split())) for i in range(n)]
MOD = 998244353
comb = Combination(n, MOD)
memo1 = {}
memo2 = {}
for i in range(n):
	(tmp1, tmp2) = p[i]
	if tmp1 not in memo1:
		memo1[tmp1] = 1
	else:
		memo1[tmp1] += 1
	if tmp2 not in memo2:
		memo2[tmp2] = 1
	else:
		memo2[tmp2] += 1
ans = 0
tmp = 1
for i in memo1:
	tmp *= comb.fact[memo1[i]]
	tmp %= MOD
ans += tmp
ans %= MOD
tmp = 1
for i in memo2:
	tmp *= comb.fact[memo2[i]]
	tmp %= MOD
ans += tmp
ans %= MOD
p = sorted(p, key=itemgetter(1))
p = sorted(p, key=itemgetter(0))
for i in range(n - 1):
	if p[i][1] > p[i + 1][1]:
		ans = comb.fact[n] - ans
		ans %= MOD
		print(ans)
		return
cnt = 1
tmp = 1
for i in range(n - 1):
	if p[i][0] == p[i + 1][0] and p[i][1] == p[i + 1][1]:
		cnt += 1
	else:
		tmp *= comb.fact[cnt]
		tmp %= MOD
		cnt = 1
tmp *= comb.fact[cnt]
tmp %= MOD
ans -= tmp
ans = comb.fact[n] - ans
ans %= MOD
print(ans)


import sys
input = sys.stdin.readline
n = int(input())
s = [list(map(int, input().split())) for y in range(n)]
MOD = 998244353
fact = [1] * (n + 1)
for i in range(1, n + 1):
	fact[i] = fact[i - 1] * i % MOD
(a, b) = ([0] * n, [0] * n)
for (x, y) in s:
	a[x - 1] += 1
	b[y - 1] += 1
a_count = 1
b_count = 1
for i in range(n):
	a_count *= fact[a[i]]
	a_count %= MOD
	b_count *= fact[b[i]]
	b_count %= MOD
ab_count = 1
count = 1
s.sort()
for i in range(1, n):
	if s[i][1] < s[i - 1][1]:
		ab_count = 0
		break
	if s[i] == s[i - 1]:
		count += 1
	else:
		ab_count *= fact[count]
		ab_count %= MOD
		count = 1
ab_count *= fact[count]
ab_count %= MOD
print((fact[n] - a_count - b_count + ab_count) % MOD)


import collections
n = int(input())
arr_ab = []
arr_a = []
arr_b = []
for _ in range(n):
	(a, b) = map(int, input().split())
	arr_a.append(a)
	arr_b.append(b)
	arr_ab.append((a, b))
mod = 998244353
tmp = 1
facts = [1]
for val in range(1, n + 1):
	tmp *= val
	tmp %= mod
	facts.append(tmp)
alls = facts[n]
tmp = 1
for value in collections.Counter(arr_a).values():
	tmp *= facts[value]
	tmp %= mod
bads_a = tmp
tmp = 1
for value in collections.Counter(arr_b).values():
	tmp *= facts[value]
	tmp %= mod
bads_b = tmp
arr_ab = sorted(arr_ab)
flag = True
for i in range(n - 1):
	if arr_ab[i][1] <= arr_ab[i + 1][1]:
		continue
	else:
		flag = False
		break
if flag == False:
	print((alls - (bads_a + bads_b) + mod) % mod)
else:
	tmp = 1
	for val in collections.Counter(arr_ab).values():
		tmp *= facts[val]
		tmp %= mod
	bads_ab = tmp
	print((alls - (bads_a + bads_b - bads_ab) + mod) % mod)


import sys
input = sys.stdin.readline

def solve(a: list):
	ret = 1
	cnt = 1
	for i in range(1, n + 1):
		if i == n or a[i] != a[i - 1]:
			ret = ret * factor[cnt] % mod
			cnt = 1
		else:
			cnt += 1
	return ret
M = 1000000
n = int(input())
(a, x, y) = ([], [], [])
for i in range(n):
	(l, r) = map(int, input().split())
	x.append(l)
	y.append(r)
	a.append(M * l + r)
mod = 998244353
factor = [1] * (n + 1)
for i in range(2, n + 1):
	factor[i] = factor[i - 1] * i % mod
x.sort()
y.sort()
bad = solve(x)
bad += solve(y)
d = 1
cnt = 1
a.sort()
for i in range(1, n + 1):
	if i < n:
		(pl, pr) = (a[i - 1] // M, a[i - 1] % M)
		(l, r) = (a[i] // M, a[i] % M)
		if r < pr:
			d = 0
			break
	if i == n or a[i] != a[i - 1]:
		d = d * factor[cnt] % mod
		cnt = 1
	else:
		cnt += 1
bad = (bad - d + mod) % mod
tot = factor[n]
ans = (tot - bad + mod) % mod
print(ans)


import io, sys, atexit, os
import math as ma
from decimal import Decimal as dec
from itertools import permutations
from itertools import combinations

def li():
	return list(map(int, sys.stdin.readline().split()))

def num():
	return map(int, sys.stdin.readline().split())

def nu():
	return int(input())

def find_gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

def lcm(x, y):
	gg = find_gcd(x, y)
	return x * y // gg
mm = 998244353
yp = 0

def solve():
	t = 1
	for tt in range(t):
		n = nu()
		a = []
		p = []
		q = []
		fact = [0] * (n + 1)
		fact[0] = 1
		for i in range(1, n + 1):
			fact[i] = fact[i - 1] * i % mm
		for i in range(n):
			(x, y) = num()
			p.append(x)
			q.append(y)
			a.append((x, y))
		a.sort()
		p.sort()
		q.sort()
		cc = 1
		last = p[0]
		ans1 = 1
		for i in range(1, n):
			if last == p[i]:
				cc += 1
			else:
				ans1 = ans1 * fact[cc] % mm
				cc = 1
				last = p[i]
		ans1 = ans1 * fact[cc] % mm
		cc = 1
		last = q[0]
		ans2 = 1
		for i in range(1, n):
			if last == q[i]:
				cc += 1
			else:
				ans2 = ans2 * fact[cc] % mm
				cc = 1
				last = q[i]
		ans2 = ans2 * fact[cc] % mm
		ans3 = 1
		cc = 1
		last = a[0]
		for i in range(1, n):
			if last == a[i]:
				cc += 1
			elif last[0] > a[i][0] or last[1] > a[i][1]:
				ans3 = 0
			else:
				ans3 = ans3 * fact[cc] % mm
				cc = 1
				last = a[i]
		ans3 = ans3 * fact[cc] % mm
		print((fact[n] - ans1 - ans2 + ans3 + mm) % mm)

def __starting_point():
	solve()
__starting_point()


import sys
import itertools
input = sys.stdin.readline

def main():
	n = int(input())
	s = []
	A = []
	B = []
	for _ in range(n):
		(a, b) = map(int, input().split())
		s.append([a, b])
		A.append(a)
		B.append(b)
	A.sort()
	B.sort()
	s.sort()
	ansA = 1
	ansB = 1
	anss = 1
	for (key, val) in itertools.groupby(A):
		f = len(list(val))
		for i in range(1, f + 1):
			ansA *= i
			ansA %= 998244353
	for (key, val) in itertools.groupby(B):
		f = len(list(val))
		for i in range(1, f + 1):
			ansB *= i
			ansB %= 998244353
	for (key, val) in itertools.groupby(s):
		f = len(list(val))
		for i in range(1, f + 1):
			anss *= i
			anss %= 998244353
	flag = 1
	for i in range(n - 1):
		if s[i + 1][1] < s[i][1] or s[i + 1][0] < s[i][0]:
			flag = 0
			break
	if flag == 0:
		anss = 0
	ansn = 1
	for i in range(1, n + 1):
		ansn *= i
		ansn %= 998244353
	print((ansn - ansA - ansB + anss) % 998244353)
main()


from collections import Counter
import sys
input = sys.stdin.readline
MOD = 998244353
n = int(input())
s = sorted([tuple(map(int, input().split())) for _ in range(n)])
fact = [1]
for i in range(1, n + 1):
	fact.append(fact[-1] * i % MOD)

def ways(l):
	count = Counter(l)
	res = 1
	for x in count.values():
		res *= fact[x]
		res %= MOD
	return res
a = ways([x for (x, _) in s])
b = ways([y for (_, y) in s])
c = ways(s) if all((s[i - 1][1] <= s[i][1] for i in range(1, n))) else 0
print((fact[n] - a - b + c) % MOD)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import factorial
from collections import Counter, defaultdict
from heapq import heapify, heappop, heappush

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

def comb(n, m):
	return factorial(n) / (factorial(m) * factorial(n - m)) if n >= m else 0

def perm(n, m):
	return factorial(n) // factorial(n - m) if n >= m else 0

def mdis(x1, y1, x2, y2):
	return abs(x1 - x2) + abs(y1 - y2)
mod = 998244353
INF = float('inf')

def main():
	n = N()
	arr = []
	for _ in range(n):
		arr.append(RLL())
	fc = [0, 1]
	for i in range(2, n + 1):
		fc.append(fc[-1] * i % mod)
	res = fc[n]
	arra = [i[0] for i in arr]
	arrb = [i[1] for i in arr]
	sm = 1
	sub = 1
	arra.sort()
	arrb.sort()
	for i in range(1, n):
		if arra[i] == arra[i - 1]:
			sm += 1
		else:
			sub = sub * fc[sm] % mod
			sm = 1
	sub = sub * fc[sm] % mod
	res -= sub
	sm = 1
	sub = 1
	for i in range(1, n):
		if arrb[i] == arrb[i - 1]:
			sm += 1
		else:
			sub = sub * fc[sm] % mod
			sm = 1
	sub = sub * fc[sm] % mod
	res -= sub
	sm = 1
	sub = 1
	arr.sort()
	for i in range(1, n):
		(na, nb) = (arr[i][0], arr[i][1])
		if arr[i][1] < arr[i - 1][1]:
			break
		if arr[i] == arr[i - 1]:
			sm += 1
		else:
			sub = sub * fc[sm] % mod
			sm = 1
	else:
		sub = sub * fc[sm] % mod
		res += sub
	print(res % mod)
main()


def increasing(arr):
	n = len(arr)
	for i in range(n - 1):
		if arr[i + 1][0] < arr[i][0] or arr[i + 1][1] < arr[i][1]:
			return False
	return True

def getFacts(n, mod):
	facts = [1] * n
	for i in range(1, n):
		facts[i] = facts[i - 1] * i
		facts[i] %= mod
	return facts

def solve(arr1, arr2, n, mod):
	facts = getFacts(4 * 10 ** 5 + 1, mod)
	total = facts[n]
	dist1 = {}
	for i in arr1:
		if i[0] not in list(dist1.keys()):
			dist1[i[0]] = 1
		else:
			dist1[i[0]] += 1
	dist2 = {}
	for i in arr2:
		if i[0] not in list(dist2.keys()):
			dist2[i[0]] = 1
		else:
			dist2[i[0]] += 1
	count = 1
	for i in dist1:
		count *= facts[dist1[i]]
		count = count % mod
	total -= count
	count = 1
	for i in dist2:
		count *= facts[dist2[i]]
		count = count % mod
	total -= count
	arr1.sort()
	if increasing(arr1):
		count = 1
	else:
		count = 0
	dist3 = {}
	for i in arr1:
		if i not in list(dist3.keys()):
			dist3[i] = 1
		else:
			dist3[i] += 1
	for i in dist3:
		count *= facts[dist3[i]]
		count = count % mod
	total += count
	total = total % mod
	print(total)

def main():
	mod = 998244353
	n = int(input())
	first = []
	second = []
	for i in range(n):
		(a, b) = list(map(int, input().split()))
		first.append((a, b))
		second.append((b, a))
	solve(first, second, n, mod)
main()


from sys import stdin
from collections import Counter
sin = iter(stdin)

def input():
	return next(sin)
M = 998244353
facts = [1]

def fact(n):
	if n < len(facts):
		return facts[n]
	res = facts[-1]
	for i in range(len(facts), n + 1):
		res = res * i % M
		facts.append(res)
	return res

def main():
	n = int(input())
	ab = []
	for _ in range(n):
		ab.append(tuple(map(int, input().split())))
	(a, b) = zip(*ab)
	ac = Counter(a)
	bc = Counter(b)
	pa = 1
	pb = 1
	for (_, c) in ac.items():
		pa = pa * fact(c) % M
	for (_, c) in bc.items():
		pb = pb * fact(c) % M
	pab = 1
	abc = Counter(ab)
	abs = sorted(abc.keys())
	for i in range(1, len(abs)):
		if abs[i][1] < abs[i - 1][1]:
			pab = 0
			break
	else:
		for (_, c) in abc.items():
			pab = pab * fact(c) % M
	p = (pa + pb - pab) % M
	print((fact(n) - p) % M)
main()


import sys
input = sys.stdin.readline
mod = 998244353
n = int(input())
S = [list(map(int, input().split())) for i in range(n)]
FACT = [1]
for i in range(1, 3 * 10 ** 5 + 10):
	FACT.append(FACT[-1] * i % mod)
X = [x for (x, y) in S]
Y = [y for (x, y) in S]
ANS = 1
for i in range(1, n + 1):
	ANS = ANS * i % mod
X.sort()
XA = 1
count = 1
for i in range(1, n):
	if X[i] == X[i - 1]:
		count += 1
	else:
		XA = XA * FACT[count] % mod
		count = 1
XA = XA * FACT[count] % mod
Y.sort()
YA = 1
count = 1
for i in range(1, n):
	if Y[i] == Y[i - 1]:
		count += 1
	else:
		YA = YA * FACT[count] % mod
		count = 1
YA = YA * FACT[count] % mod
S.sort()
SA = 1
count = 1
for i in range(1, n):
	if S[i][1] < S[i - 1][1]:
		SA = 0
		break
	if S[i] == S[i - 1]:
		count += 1
	else:
		SA = SA * FACT[count] % mod
		count = 1
SA = SA * FACT[count] % mod
print((ANS - XA - YA + SA) % mod)


import sys
from collections import Counter

def input():
	return sys.stdin.readline()[:-1]
MOD = 998244353
n = int(input())
fact = [1]
for i in range(1, n + 1):
	fact.append(fact[-1] * i % MOD)
seq = []
(ca, cb) = (Counter(), Counter())
for _ in range(n):
	(a, b) = map(int, input().split())
	ca[a] += 1
	cb[b] += 1
	seq.append((a, b))
ans = fact[n]
ans %= MOD
res = 1
for v in ca.values():
	res *= fact[v]
	res %= MOD
ans -= res
ans %= MOD
res = 1
for v in cb.values():
	res *= fact[v]
	res %= MOD
ans -= res
seq.sort(key=lambda x: (x[0], x[1]))
cur = seq[0][0]
res = 1
M = 1
ctmp = Counter()
for i in range(n):
	if seq[i][0] == cur:
		ctmp[seq[i][1]] += 1
		M = max(M, seq[i][1])
	else:
		if seq[i][1] < M:
			res = 0
			break
		tmp = 1
		for v in ctmp.values():
			tmp *= fact[v]
			tmp %= MOD
		res *= tmp
		res %= MOD
		ctmp = Counter()
		ctmp[seq[i][1]] += 1
		cur = seq[i][0]
		M = max(M, seq[i][1])
tmp = 1
for v in ctmp.values():
	tmp *= fact[v]
	tmp %= MOD
res *= tmp
res %= MOD
ans += res
ans %= MOD
print(ans)


import math
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]
n = int(input())
mod = 998244353
f = Factorial(mod)
d = dict()
d1 = dict()
d12 = dict()
for i in range(n):
	(a, b) = map(int, input().split())
	if a not in d:
		d.update({a: 1})
	else:
		d[a] += 1
	if b not in d1:
		d1.update({b: 1})
	else:
		d1[b] += 1
	if a not in d12:
		d12.update({a: [b]})
	else:
		d12[a].append(b)
for i in d12:
	d12[i].sort()
s = []
for i in sorted(d12):
	for j in d12[i]:
		s.append(j)
c = 1
c1 = 1
c2 = 1
if s != sorted(s):
	c = 0
else:
	for i in d12:
		e = dict()
		for j in d12[i]:
			if j not in e:
				e.update({j: 1})
			else:
				e[j] += 1
		for j in e:
			c *= f.calc(e[j])
			c %= mod
for j in d:
	c1 = c1 * f.calc(d[j])
	c1 %= mod
for j in d1:
	c2 = c2 * f.calc(d1[j])
	c2 %= mod
print((f.calc(n) - c1 - c2 + c) % mod)


import sys
input = sys.stdin.readline

def solve(a: list):
	ret = 1
	cnt = 1
	for i in range(1, n + 1):
		if i == n or a[i] != a[i - 1]:
			ret = ret * factor[cnt] % mod
			cnt = 1
		else:
			cnt += 1
	return ret
n = int(input())
a = [()] * n
for i in range(n):
	a[i] = tuple(map(int, input().split()))
mod = 998244353
factor = [1] * (n + 1)
for i in range(2, n + 1):
	factor[i] = factor[i - 1] * i % mod
x = [0] * n
y = [0] * n
for i in range(n):
	x[i] = a[i][0]
	y[i] = a[i][1]
x.sort()
y.sort()
bad = solve(x)
bad += solve(y)
d = 1
cnt = 1
a.sort()
for i in range(1, n + 1):
	if i < n and a[i][1] < a[i - 1][1]:
		d = 0
		break
	if i == n or a[i] != a[i - 1]:
		d = d * factor[cnt] % mod
		cnt = 1
	else:
		cnt += 1
bad = (bad - d + mod) % mod
tot = factor[n]
ans = (tot - bad + mod) % mod
print(ans)


from functools import reduce
from collections import Counter

def fact(n):
	return memo[n]

def f(arr):
	e = list(map(fact, Counter(arr).values()))
	w = reduce(lambda x, y: x * y % MOD, e)
	return w
n = int(input())
l = []
for i in range(n):
	l.append(tuple(map(int, input().strip().split())))
MOD = 998244353
memo = {0: 1}
for i in range(1, n + 1):
	memo[i] = memo[i - 1] * i % MOD
l.sort()
m = f(l)
(l1, l2) = zip(*l)
s = f(l1)
s1 = f(sorted(l2))
hc = 1 if all((l2[i] <= l2[i + 1] for i in range(n - 1))) else 0
ans = fact(n) - s - s1 + m * hc
print(ans % MOD)


import sys
from collections import Counter
readline = sys.stdin.readline
readlines = sys.stdin.readlines
ns = lambda : readline().rstrip()
ni = lambda : int(readline().rstrip())
nm = lambda : map(int, readline().split())
nl = lambda : list(map(int, readline().split()))
prn = lambda x: print(*x, sep='\n')
n_ = 4 * 10 ** 5
mod = 998244353
fun = [1] * (n_ + 1)
for i in range(1, n_ + 1):
	fun[i] = fun[i - 1] * i % mod
rev = [1] * (n_ + 1)
rev[n_] = pow(fun[n_], mod - 2, mod)
for i in range(n_ - 1, 0, -1):
	rev[i] = rev[i + 1] * (i + 1) % mod

def nCr(n, r):
	if r > n:
		return 0
	return fun[n] * rev[r] % mod * rev[n - r] % mod

def solve():
	n = ni()
	l = [tuple(nm()) for _ in range(n)]
	l.sort()
	ans = fun[n]
	sortab = sorta = sortb = 1
	for i in range(n - 1):
		if l[i + 1][1] < l[i][1]:
			sortab = 0
			break
	if sortab:
		for x in Counter(l).values():
			sortab = sortab * fun[x] % mod
	for x in Counter([x[0] for x in l]).values():
		sorta = sorta * fun[x] % mod
	for x in Counter([x[1] for x in l]).values():
		sortb = sortb * fun[x] % mod
	print((ans - sorta - sortb + sortab) % mod)
solve()


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD
n = int(input())
s = [list(map(int, input().split())) for y in range(n)]
MOD = 998244353
fact = [1] * (n + 1)
for i in range(1, n + 1):
	fact[i] = fact[i - 1] * i % MOD
(a, b) = ([0] * n, [0] * n)
for (x, y) in s:
	a[x - 1] += 1
	b[y - 1] += 1
a_count = 1
b_count = 1
for i in range(n):
	a_count *= fact[a[i]]
	a_count %= MOD
	b_count *= fact[b[i]]
	b_count %= MOD
ab_count = 1
count = 1
s.sort()
for i in range(1, n):
	if s[i][1] < s[i - 1][1]:
		ab_count = 0
		break
	if s[i] == s[i - 1]:
		count += 1
	else:
		ab_count *= fact[count]
		ab_count %= MOD
		count = 1
ab_count *= fact[count]
ab_count %= MOD
print((fact[n] - a_count - b_count + ab_count) % MOD)


from sys import stdin
input = stdin.readline
mod = 998244353
fact = [1, 1]
dictf = [0, 0]
dicts = [0, 0]
dictb = [0, 0]
for i in range(2, 3 * pow(10, 5) + 99):
	fact.append(fact[-1] * i % mod)
	dicts.append(0)
	dictf.append(0)
	dictb.append(0)
n = int(input())
answer = fact[n]
pairs = []
for _ in range(n):
	pairs.append([int(x) for x in input().split()])
	dictf[pairs[_][0]] += 1
	dicts[pairs[_][1]] += 1
first = 1
second = 1
both = 0
pairs.sort()
for di in dictf:
	if di == 0:
		continue
	first *= fact[di]
	first %= mod
answer -= first
answer %= mod
for di in dicts:
	if di == 0:
		continue
	second *= fact[di]
	second %= mod
answer -= second
answer %= mod
checkSorting = True
(premiere, douxieme) = pairs[0]
for (fi, se) in pairs:
	checkSorting = checkSorting and fi >= premiere and (se >= douxieme)
	premiere = fi
	douxieme = se
if checkSorting:
	both = 1
	j = 0
	for _ in range(len(pairs)):
		i = pairs[_]
		if i != pairs[j]:
			both *= fact[_ - j]
			both %= mod
			j = _
		if _ == len(pairs) - 1:
			both *= fact[1 + _ - j]
			both %= mod
answer += both
answer %= mod
print(answer)


import sys
from collections import defaultdict
n = int(sys.stdin.readline())
fact = [0 for _ in range(n + 3)]
mod = 998244353
fact[0] = 1
for i in range(1, n + 3):
	fact[i] = fact[i - 1] * i % mod
arr = [[0, 0] for _ in range(n)]
b = [0 for _ in range(n)]
for _ in range(n):
	(u, v) = map(int, sys.stdin.readline().split())
	(arr[_][0], arr[_][1]) = (u, v)
	b[_] = v
b.sort()
arr.sort()
z = True
for i in range(n):
	if b[i] != arr[i][1]:
		z = False
(lasta, lastb) = (arr[0][0], arr[0][1])
(counta, countc) = (1, 1)
(la, lb, lc) = ([], [], [])
bl = b[0]
cb = 1
for i in range(1, n):
	if z:
		if arr[i][0] == lasta and arr[i][1] == lastb:
			countc += 1
		else:
			lc.append(countc)
			countc = 1
	if arr[i][0] == lasta:
		counta += 1
	else:
		la.append(counta)
		counta = 1
		lasta = arr[i][0]
	if b[i] == bl:
		cb += 1
	else:
		lb.append(cb)
		cb = 1
		bl = b[i]
	if arr[i][1] == lastb:
		pass
	else:
		lastb = arr[i][1]
la.append(counta)
lb.append(cb)
if z:
	lc.append(countc)
ans = fact[n]
(suba, subb, addc) = (0, 0, 0)
if len(la) > 0:
	suba = 1
if len(lb) > 0:
	subb = 1
if len(lc) > 0:
	addc = 1
for i in range(len(la)):
	suba = suba * fact[la[i]] % mod
for i in range(len(lb)):
	subb = subb * fact[lb[i]] % mod
for i in range(len(lc)):
	addc = addc * fact[lc[i]] % mod
ans = ans % mod - suba % mod - subb % mod + addc % mod
print(ans % mod)


import os
import sys
from io import BytesIO, IOBase
from collections import Counter
mod = 998244353

def solve(arr, f):
	(a, ans) = (Counter(arr), 1)
	for i in a:
		ans = ans * f[a[i]] % mod
	return ans

def main():
	n = int(input())
	(a, b) = ([], [])
	for i in range(n):
		(x, y) = map(int, input().split())
		a.append(x)
		b.append(y)
	f = [1]
	for i in range(1, n + 1):
		f.append(f[-1] * i % mod)
	(ans1, ans2, ans3) = (solve(a, f), solve(b, f), 1)
	ans = (f[n] - ans1 - ans2) % mod
	c = sorted(range(n), key=lambda x: a[x])
	(i, f1, ma) = (0, 1, 0)
	while i < n:
		j = i + 1
		while j < n and a[c[i]] == a[c[j]]:
			j += 1
		g = Counter()
		for k in range(i, j):
			g[b[c[k]]] += 1
		if min(g) < ma:
			f1 = 0
			break
		ma = max(g)
		for k in g:
			ans3 = ans3 * f[g[k]] % mod
		i = j
	print((ans + f1 * ans3) % mod)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


def naiveSolve():
	return
MOD = 998244353
MAX = int(300000.0) + 5
fact = [1]
for zz in range(1, MAX + 1):
	fact.append(fact[-1] % MOD * zz % MOD % MOD)

def nCr(n, r):
	num = fact[n]
	den = fact[r] % MOD * (fact[n - r] % MOD) % MOD
	return num % MOD * pow(den, MOD - 2, MOD) % MOD

def nPr(n, r):
	num = fact[n]
	den = fact[n - r]
	return num % MOD * pow(den, MOD - 2, MOD) % MOD
from collections import Counter

def main():
	MOD = 998244353
	n = int(input())
	arr = []
	for _ in range(n):
		arr.append(readIntArr())
	totalP = fact[n]
	arr.sort()
	fs = 0
	ok = True
	for i in range(1, n):
		if arr[i][1] < arr[i - 1][1]:
			ok = False
	if ok:
		fs = 1
	pf = ps = -1
	cnt = 1
	for i in range(n):
		if arr[i] == [pf, ps]:
			cnt += 1
		else:
			fs *= fact[cnt]
			fs %= MOD
			cnt = 1
		(pf, ps) = arr[i]
	fs *= fact[cnt]
	fs %= MOD
	f = 1
	pf = -1
	cnt = 1
	for i in range(n):
		if arr[i][0] == pf:
			cnt += 1
		else:
			f *= fact[cnt]
			f %= MOD
			cnt = 1
		pf = arr[i][0]
	f *= fact[cnt]
	f %= MOD
	arr.sort(key=lambda x: x[1])
	s = 1
	ps = -1
	cnt = 1
	for i in range(n):
		if arr[i][1] == ps:
			cnt += 1
		else:
			s *= fact[cnt]
			s %= MOD
			cnt = 1
		ps = arr[i][1]
	s *= fact[cnt]
	s %= MOD
	badCnts = (f + s - fs + MOD) % MOD
	ans = (totalP - badCnts + MOD) % MOD
	print(ans)
	return
import sys
input = sys.stdin.buffer.readline

def oneLineArrayPrint(arr):
	print(' '.join([str(x) for x in arr]))

def multiLineArrayPrint(arr):
	print('\n'.join([str(x) for x in arr]))

def multiLineArrayOfArraysPrint(arr):
	print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))

def readIntArr():
	return [int(x) for x in input().split()]

def makeArr(defaultValFactory, dimensionArr):
	dv = defaultValFactory
	da = dimensionArr
	if len(da) == 1:
		return [dv() for _ in range(da[0])]
	else:
		return [makeArr(dv, da[1:]) for _ in range(da[0])]

def queryInteractive(i, j):
	print('? {} {}'.format(i, j))
	sys.stdout.flush()
	return int(input())

def answerInteractive(ans):
	print('! {}'.format(' '.join([str(x) for x in ans])))
	sys.stdout.flush()
inf = float('inf')
MOD = 10 ** 9 + 7
from math import gcd, floor, ceil
for _abc in range(1):
	main()


import itertools

def Runs(a, key=lambda k: k):
	i = 0
	while i < len(a):
		j = i
		while j < len(a) and key(a[i]) == key(a[j]):
			j += 1
		if i != j - 1:
			yield (i, j - 1)
		i = j

def Intersection(x, y):
	result = []
	ai = 0
	bi = 0
	while ai < len(x) and bi < len(y):
		a = x[ai]
		b = y[bi]
		if a[1] < b[0]:
			ai += 1
		elif b[1] < a[0]:
			bi += 1
		elif a[0] <= b[0]:
			if a[1] <= b[1]:
				result.append((b[0], a[1]))
				ai += 1
			else:
				result.append((b[0], b[1]))
				bi += 1
		elif b[1] <= a[1]:
			result.append((a[0], b[1]))
			bi += 1
		else:
			result.append((a[0], a[1]))
			ai += 1
	return result
m1 = 998244353

def IsNonDecreasing(a):
	a = list(a)
	for i in range(len(a) - 1):
		if a[i] > a[i + 1]:
			return False
	return True

def Factorial(n):
	result = 1
	for i in range(n):
		result *= i + 1
		result = result % m1
	return result

def Solve(a):
	n = len(a)
	a = list(sorted(a))
	do = IsNonDecreasing((x[1] for x in a))
	r1 = 1
	x = list(Runs(a, lambda x: x[0]))
	for (i, j) in x:
		f = Factorial(j - i + 1)
		r1 *= f
		r1 = r1 % m1
	r2 = 1
	if not do:
		a = sorted(a, key=lambda x: x[1])
	y = list(Runs(a, lambda x: x[1]))
	for (i, j) in y:
		f = Factorial(j - i + 1)
		r2 *= f
		r2 = r2 % m1
	d1 = 0
	if do:
		d1 = 1
		z = Intersection(x, y)
		for (i, j) in z:
			f = Factorial(j - i + 1)
			d1 *= f
			d1 = d1 % m1
	return (Factorial(n) - r1 - r2 + d1) % m1

def Classify(a):
	bad1 = True
	bad2 = True
	for i in range(len(a) - 1):
		if a[i][0] > a[i + 1][0]:
			bad1 = False
		if a[i][1] > a[i + 1][1]:
			bad2 = False
	if bad1 or bad2:
		return ('BAD', bad1, bad2)
	else:
		return ('GOOD',)
import collections

def SolveBrute(a):
	count = collections.Counter()
	for x in itertools.permutations(a):
		c = Classify(x)
		count[c[0]] += 1
		if c[0] == 'BAD':
			if c[1]:
				count['b1'] += 1
			if c[2]:
				count['b2'] += 1
			if c[1] and c[2]:
				count['b12'] += 1
	return count['GOOD']
import random

def Generate(n):
	k = 25000
	return [(random.randint(1, k), random.randint(1, k)) for _ in range(n)]
import sys

def Run():
	f = sys.stdin
	(t,) = next(f).split()
	t = int(t)
	r = []
	for _ in range(t):
		(i, j) = next(f).split()
		r.append((int(i), int(j)))
	print(Solve(r))
Run()


from collections import defaultdict
import math
MOD = 998244353

def facmod(n):
	fac = 1
	for i in range(2, n + 1):
		fac *= i
		fac %= MOD
	return fac

def main():
	n = int(input())
	s = [tuple((int(s) for s in input().split())) for _ in range(n)]
	count = defaultdict(int)
	for (a, _) in s:
		count[a] += 1
	first = 1
	for c in count.values():
		first *= facmod(c)
		first %= MOD
	count = defaultdict(int)
	for (_, b) in s:
		count[b] += 1
	second = 1
	for c in count.values():
		second *= facmod(c)
		second %= MOD
	count = defaultdict(int)
	for t in s:
		count[t] += 1
	both = 1
	for c in count.values():
		both *= facmod(c)
		both %= MOD
	s.sort()
	for (i, (_, b)) in enumerate(s[:-1]):
		if b > s[i + 1][1]:
			both = 0
			break
	print((facmod(n) - (first + second - both)) % MOD)
main()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import gcd, ceil

def pre(s):
	n = len(s)
	pi = [0] * n
	for i in range(1, n):
		j = pi[i - 1]
		while j and s[i] != s[j]:
			j = pi[j - 1]
		if s[i] == s[j]:
			j += 1
		pi[i] = j
	return pi

def prod(a):
	ans = 1
	for each in a:
		ans = ans * each
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y
for _ in range(int(input()) if not True else 1):
	n = int(input())
	mod = 998244353
	facts = [1] * (n + 69)
	for i in range(1, n + 69):
		facts[i] = facts[i - 1] * i % mod
	x = [0] * n
	y = [0] * n
	for i in range(n):
		(x[i], y[i]) = map(int, input().split())
	di = {}
	di2 = {}
	for i in range(n):
		if x[i] not in di:
			di[x[i]] = [i]
		else:
			di[x[i]] += [i]
		if y[i] not in di2:
			di2[y[i]] = [i]
		else:
			di2[y[i]] += [i]
	xvals = sorted((k for k in di))
	yvals = sorted((k for k in di2))
	ans = 1
	for v in xvals:
		ans = ans * facts[len(di[v])] % mod
	anss = 1
	for v in yvals:
		anss = anss * facts[len(di2[v])] % mod
	ans += anss
	ans2 = 1
	p = []
	for xx in xvals:
		indices = di[xx]
		yy = sorted([y[k] for k in indices])
		for pp in yy:
			p += [[xx, pp]]
	p2 = [p[i][1] for i in range(n)]
	if p2 == sorted(p2):
		cur = p[0]
		count = 1
		for i in range(1, n):
			if p[i] == cur:
				count += 1
			else:
				ans2 = ans2 * facts[count] % mod
				count = 1
				cur = p[i]
		ans2 = ans2 * facts[count] % mod
	else:
		ans2 = 0
	bad = ans - ans2
	good = (facts[n] - bad) % mod
	print(good)


from sys import stdin
input = stdin.readline
n = int(input())
p = 998244353
sil = [0] * 400000
sil[1] = 1
for i in range(2, 400000):
	sil[i] = sil[i - 1] * i % p

def fun(l):
	wyn = 1
	l.sort()
	count = 1
	for i in range(1, len(l)):
		if l[i] != l[i - 1]:
			wyn = wyn * sil[count] % p
			count = 1
		else:
			count += 1
	wyn = wyn * sil[count] % p
	return wyn
dupa = [list(map(int, input().split())) for i in range(n)]
xx = [i[0] for i in dupa]
yy = [i[1] for i in dupa]
dupa.sort()
x = [i[0] for i in dupa]
y = [i[1] for i in dupa]
dolne = []
pyk = 1
left = 0
for i in range(1, n):
	if x[i] != x[i - 1]:
		dolne.append(y[left:i])
		left = i
if left == n - 1:
	dolne.append([y[n - 1]])
else:
	dolne.append(y[left:n])
c = 1
for i in range(1, len(dolne)):
	if min(dolne[i]) < max(dolne[i - 1]):
		c = 0
		break
wyn = fun(xx) + fun(yy)
if c == 1:
	dupa = 1
	for i in range(len(dolne)):
		dupa = dupa * fun(dolne[i]) % p
	wyn -= dupa
print((sil[n] - wyn) % p)


import sys
p = 998244353
n = int(sys.stdin.readline())
S1 = []
S2 = []
A = []
for i in range(0, n):
	(x, y) = list(map(int, sys.stdin.readline().strip().split()))
	S1.append(x)
	S2.append(y)
	A.append(x * 1000000 + y)
S1.sort()
S2.sort()
A.sort()
x = S1[0]
c = 1
ans1 = 1
for i in range(1, n):
	if S1[i] == x:
		c = c + 1
		ans1 = ans1 * c % p
	else:
		x = S1[i]
		c = 1
c = 1
ans2 = 1
x = S2[0]
for i in range(1, n):
	if S2[i] == x:
		c = c + 1
		ans2 = ans2 * c % p
	else:
		x = S2[i]
		c = 1
c = 1
ans3 = 1
x = A[0]
for i in range(1, n):
	if A[i] == x:
		c = c + 1
		ans3 = ans3 * c % p
	else:
		x = A[i]
		c = 1
	if A[i] % 1000000 < A[i - 1] % 1000000:
		ans3 = 0
ans4 = 1
for i in range(1, n + 1):
	ans4 = ans4 * i % p
print((ans4 - ans1 - ans2 + ans3) % p)


from sys import stdin
n = int(input())
p = [list(map(int, stdin.readline().split())) for _ in range(n)]
mod = 998244353
da = {}
db = {}

def normal(x):
	while x < mod:
		x += mod
	return x % mod
gt = [1] * (n + 1)
for i in range(1, n + 1):
	gt[i] = gt[i - 1] * i % mod
for (i, [a, b]) in enumerate(p):
	if a not in da:
		da[a] = []
	da[a].append(b)
	if b not in db:
		db[b] = 0
	db[b] += 1
ans = 0
temp = 1
for v in da.values():
	temp = temp * gt[len(v)] % mod
ans += temp
temp = 1
for v in db.values():
	temp = temp * gt[v] % mod
ans = (ans + temp) % mod
pre_max = 0
minus = 1
for (k, v) in sorted(da.items(), key=lambda x: x[0]):
	d = {}
	min_ = n + 1
	max_ = 0
	for b in v:
		if b < min_:
			min_ = b
		if b > max_:
			max_ = b
		if b not in d:
			d[b] = 0
		d[b] += 1
	if min_ < pre_max:
		minus = 0
		break
	pre_max = max_
	for v in d.values():
		minus = minus * gt[v] % mod
ans -= minus
print(normal(gt[n] - ans))


import sys
in_file = sys.stdin
n = int(in_file.readline().strip())
Al = []
Ar = []
A = []
for _ in range(n):
	(x, y) = map(int, in_file.readline().strip().split())
	Al.append(x)
	Ar.append(y)
	A.append((x, y))
Al.sort()
Ar.sort()
A.sort()

def groups(L):
	p = L[0]
	G = [1]
	for i in range(1, len(L)):
		if p == L[i]:
			G[-1] += 1
		else:
			p = L[i]
			G.append(1)
	return G

def bin_exp(x, a, p):
	r = 1
	while a > 0:
		if a % 2 == 1:
			r = r * x % p
		x = x * x % p
		a = a // 2
	return r

def mod_fact(x, p):
	r = 1
	for i in range(1, x + 1):
		r = r * i % p
	return r
p = 998244353
Gl = groups(Al)
rl = 1
for i in Gl:
	rl = rl * mod_fact(i, p) % p
Gr = groups(Ar)
rr = 1
for i in Gr:
	rr = rr * mod_fact(i, p) % p
G = groups(A)
r = 1
for i in G:
	r = r * mod_fact(i, p) % p
if list(zip(Al, Ar)) != A:
	r = 0
res = (mod_fact(len(A), p) + r) % p
res = (p + res - rl) % p
res = (p + res - rr) % p
sys.stdout.write(str(res))
sys.stdout.flush()


import sys
MOD = 998244353
f = [1]
cur = 1
for i in range(1, 3 * 10 ** 5 + 3):
	cur *= i
	cur %= MOD
	f.append(cur)

def perm(l):
	map = {}
	for x in l:
		if x in map:
			map[x] += 1
		else:
			map[x] = 1
	ans = 1
	for x in map.values():
		ans *= f[x]
		ans %= MOD
	return ans

def is_sorted(l, b_s):
	b2_s = [b for (a, b) in l]
	return b2_s == b_s
data = []
a_s = []
b_s = []
sys.stdin.readline().strip()
for line in sys.stdin:
	(a, b) = map(int, line.strip().split())
	data.append((a, b))
	a_s.append(a)
	b_s.append(b)
ans = f[len(data)]
a_s = sorted(a_s)
ans -= perm(a_s)
b_s = sorted(b_s)
ans -= perm(b_s)
data = sorted(data)
if is_sorted(data, b_s):
	ans += perm(data)
print(ans % MOD)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from collections import defaultdict
n = int(input())
vals = []
mod = 998244353
dict1 = defaultdict(list)
dict2 = defaultdict(list)
for s in range(n):
	(a, b) = map(int, input().split())
	vals.append((a, b))
	dict1[a].append(b)
	dict2[b].append(a)
fact = [1]
broke = False
for s in range(1, n + 1):
	fact.append(fact[-1] * s % mod)
one = 1
key1 = [x for x in dict1.keys()]
for key in key1:
	one *= fact[len(dict1[key])]
	one = one % mod
	if len(dict1[key]) == n:
		broke = True
two = 1
key2 = [x for x in dict2.keys()]
for key in key2:
	two *= fact[len(dict2[key])]
	two = two % mod
	if len(dict2[key]) == n:
		broke = True
onetwo = 1
last = 0
found = False
key1.sort()
for key in key1:
	dict3 = {}
	maxsofar = 0
	broke1 = False
	for s in dict1[key]:
		if s >= last:
			if not s in dict3:
				dict3[s] = 1
			else:
				dict3[s] += 1
			maxsofar = max(maxsofar, s)
		else:
			broke1 = True
			break
	if broke1 == True:
		found = False
		break
	for s in dict3:
		onetwo *= fact[dict3[s]]
		onetwo = onetwo % mod
		if dict3[s] > 1:
			found = True
	last = maxsofar
if broke == True:
	print(0)
elif found == True:
	print((fact[n] - (one + two - onetwo)) % mod)
else:
	print((fact[n] - (one + two)) % mod)


import sys
mod = 998244353
fact = [1]
for i in range(1, 300001):
	fact.append(fact[-1] * i % mod)
data = []
num = int(sys.stdin.readline())
l = []
for _ in range(num):
	temp = [int(i) for i in sys.stdin.readline().split()]
	data.append((temp[0] << 20) + temp[1])
	l.append(temp[1])
ans = 0
l.sort()
last = -1
tot = 1
run = 0
for p in l:
	if p == last:
		run += 1
	else:
		tot = tot * fact[run] % mod
		run = 1
		last = p
tot = tot * fact[run] % mod
ans += tot
data.sort()
f = [i >> 20 for i in data]
last = -1
tot = 1
run = 0
for p in f:
	if p == last:
		run += 1
	else:
		tot = tot * fact[run] % mod
		run = 1
		last = p
tot = tot * fact[run] % mod
ans += tot
pow2m1 = (1 << 20) - 1
sor = True
for i in range(num - 1):
	if data[i] & pow2m1 > data[i + 1] & pow2m1:
		sor = False
		break
if sor:
	last = -1
	tot = 1
	run = 0
	for p in data:
		if p == last:
			run += 1
		else:
			tot = tot * fact[run] % mod
			run = 1
			last = p
	tot = tot * fact[run] % mod
	ans -= tot
q = fact[num]
print((q - ans) % 998244353)


from collections import Counter
from functools import reduce
a = []
MOD = 998244353
for i in range(int(input())):
	a.append(tuple(map(int, input().split())))
is_sorted = lambda l: all((l[i] <= l[i + 1] for i in range(len(l) - 1)))
prod = lambda l: reduce(lambda x, y: x * y % MOD, l)
b = sorted(a)
(c1, c2) = zip(*b)
mx = max(max(max(c1), max(c2)), len(b))
fact = {0: 1}
for i in range(1, mx + 1):
	fact[i] = fact[i - 1] * i % MOD
c12 = 1 if is_sorted(c2) else 0
C12 = map(lambda x: fact[x], Counter(b).values())
C1 = map(lambda x: fact[x], Counter(c1).values())
C2 = map(lambda x: fact[x], Counter(c2).values())
ans = fact[len(b)] - (prod(C1) + prod(C2) - c12 * prod(C12))
ans %= MOD
print(ans)


from sys import stdin
input = stdin.readline
mod = 998244353
MAX_N = 3 * 10 ** 5 + 1
fact = [1 for i in range(MAX_N)]
for i in range(1, MAX_N):
	fact[i] = fact[i - 1] * i % mod
n = int(input())
a = [0 for i in range(n)]
b = [0 for i in range(n)]
for i in range(n):
	(a[i], b[i]) = [int(i) for i in input().split()]
s = sorted([(a[i], b[i]) for i in range(n)])
a = sorted(a)
b = sorted(b)
A = 1
B = 1
S = 1
count_A = 1
count_B = 1
count_S = 1
for i in range(1, n):
	if a[i] == a[i - 1]:
		count_A += 1
	else:
		A = A * fact[count_A] % mod
		count_A = 1
	if b[i] == b[i - 1]:
		count_B += 1
	else:
		B = B * fact[count_B] % mod
		count_B = 1
	if s[i][0] == s[i - 1][0]:
		if s[i][1] == s[i - 1][1]:
			count_S += 1
		else:
			S = S * fact[count_S] % mod
			count_S = 1
	elif s[i][1] < s[i - 1][1]:
		S = 0
	else:
		S = S * fact[count_S] % mod
		count_S = 1
A = A * fact[count_A] % mod
B = B * fact[count_B] % mod
S = S * fact[count_S] % mod
print((fact[n] % mod - A - B + S) % mod)


from sys import stdin
from collections import Counter
input = stdin.readline
(a, b, c) = (Counter(), Counter(), Counter())
n = int(input())
(mod, f, arr) = (998244353, [1], [])
p = q = r = 1
for i in range(1, n + 1):
	(x, y) = map(int, input().split())
	a[x] += 1
	b[y] += 1
	c[x, y] += 1
	arr.append((x, y))
	f.append(f[-1] * i % mod)
for i in a.values():
	p *= f[i]
	p %= mod
for i in b.values():
	q *= f[i]
	q %= mod
arr.sort()
if all((arr[i][0] <= arr[i + 1][0] and arr[i][1] <= arr[i + 1][1] for i in range(n - 1))):
	for i in c.values():
		r *= f[i]
		r %= mod
else:
	r = 0
print((f[n] - p - q + r) % mod)


import sys
input = sys.stdin.readline
n = int(input())
arr = []
f = [1] * (n + 1)
for i in range(1, n + 1):
	(a, b) = map(int, input().split())
	arr.append([a, b])
	f[i] = f[i - 1] * i % 998244353
(a1, a2, a3) = (sorted((i for (i, j) in arr)), sorted((j for (i, j) in arr)), sorted(arr))
ans = f[n]
t1 = t2 = t3 = 1
cnt1 = cnt2 = cnt3 = 1
for i in range(1, n):
	if a1[i] == a1[i - 1]:
		cnt1 += 1
	else:
		t1 *= f[cnt1]
		cnt1 = 1
	if a2[i] == a2[i - 1]:
		cnt2 += 1
	else:
		t2 *= f[cnt2]
		cnt2 = 1
	if a3[i] == a3[i - 1]:
		cnt3 += 1
	else:
		t3 *= f[cnt3]
		cnt3 = 1
	if a3[i][0] < a3[i - 1][0] or a3[i][1] < a3[i - 1][1]:
		t3 = 0
	t1 %= 998244353
	t2 %= 998244353
	t3 %= 998244353
t1 *= f[cnt1]
t2 *= f[cnt2]
t3 *= f[cnt3]
print((ans - t1 - t2 + t3) % 998244353)


from collections import defaultdict, Counter
import sys

def input():
	return sys.stdin.readline().rstrip()
MAX = 3 * 10 ** 5 + 10
mod = 998244353
n = int(input())
(a, b) = ([0] * (MAX + 10), [0] * (MAX + 10))
d = []
e = [[] for i in range(MAX + 10)]
for i in range(n):
	(x, y) = map(int, input().split())
	a[x] += 1
	b[y] += 1
	d.append((x, y))
	e[x].append(y)
pows = [1] * MAX
for i in range(1, MAX):
	pows[i] = pows[i - 1] * i % mod
d.sort(key=lambda x: (x[0], x[1]))
ans = pows[n]
if all((d[i][1] <= d[i + 1][1] for i in range(n - 1))):
	rev = 1
	for (i, v) in enumerate(e):
		dic = dict(Counter(v))
		for value in dic.values():
			rev *= pows[value]
			rev %= mod
	ans += rev
(rem1, rem2) = (1, 1)
for i in range(MAX):
	rem1 *= pows[a[i]]
	rem2 *= pows[b[i]]
	rem1 %= mod
	rem2 %= mod
ans -= rem1 + rem2
ans %= mod
print(ans)


MOD = 998244353
n = int(input())
a = []
b = []
fact = [1]
for i in range(n):
	(x_a, x_b) = input().strip().split(' ')
	a.append(int(x_a))
	b.append(int(x_b))
for i in range(1, n + 1):
	fact.append(fact[i - 1] * i % MOD)

def count_permutations(arr):
	f = dict()
	for x in arr:
		try:
			f[x] += 1
		except:
			f[x] = 1
	res = 1
	for (_, v) in f.items():
		res *= fact[v]
		res %= MOD
	return res
bad_a = count_permutations(a)
bad_b = count_permutations(b)
bad_common = 0
pairs = [(a[i], b[i]) for i in range(n)]
pairs = sorted(pairs, key=lambda x: (x[0], x[1]))
second = [x[1] for x in pairs]
if second == sorted(second):
	bad_common = count_permutations(pairs)
res = fact[n] - bad_a - bad_b + bad_common
print(res % MOD)


import sys
input = sys.stdin.readline
n = int(input())
arr = []
f = [1] * (n + 1)
m = 998244353
for i in range(1, n + 1):
	arr.append(list(map(int, input().split())))
	f[i] = f[i - 1] * i % m
(a1, a2, a3) = (sorted((i for (i, j) in arr)), sorted((j for (i, j) in arr)), sorted(arr))
ans = f[n]
t1 = t2 = t3 = c1 = c2 = c3 = 1
for i in range(1, n):
	if a1[i] == a1[i - 1]:
		c1 += 1
	else:
		t1 *= f[c1]
		c1 = 1
	if a2[i] == a2[i - 1]:
		c2 += 1
	else:
		t2 *= f[c2]
		c2 = 1
	if a3[i] == a3[i - 1]:
		c3 += 1
	else:
		t3 *= f[c3]
		c3 = 1
	if a3[i][0] < a3[i - 1][0] or a3[i][1] < a3[i - 1][1]:
		t3 = 0
	t1 %= m
	t2 %= m
	t3 %= m
t1 *= f[c1]
t2 *= f[c2]
t3 *= f[c3]
print((ans - t1 - t2 + t3) % m)


from sys import stdin
n = int(stdin.readline().strip())
s = [list(map(int, stdin.readline().strip().split())) for i in range(n)]
s1 = [s[i][1] for i in range(n)]
s.sort()
s1.sort()
mod = 998244353
x = 1
ans = 1
fact = [0 for i in range(n + 1)]
fact[1] = 1
for i in range(2, n + 1):
	fact[i] = i * fact[i - 1] % mod
for i in range(1, n):
	if s[i][0] == s[i - 1][0]:
		x += 1
	else:
		ans = ans * fact[x] % mod
		x = 1
ans = ans * fact[x] % mod
t = True
for i in range(1, n):
	if s[i][1] < s[i - 1][1]:
		t = False
		break
x = 1
ans1 = 1
for i in range(1, n):
	if s1[i] == s1[i - 1]:
		x += 1
	else:
		ans1 = ans1 * fact[x] % mod
		x = 1
ans1 = ans1 * fact[x] % mod
if t:
	ans2 = 1
	x = 1
	for i in range(1, n):
		if s[i] == s[i - 1]:
			x += 1
		else:
			ans2 = ans2 * fact[x] % mod
			x = 1
	ans2 = ans2 * fact[x] % mod
	ans = ans + ans1 - ans2
else:
	ans += ans1
print((fact[n] - ans) % mod)


import os
import sys
from math import *
from collections import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
ALPHA = 'abcdefghijklmnopqrstuvwxyz/'
M = 998244353
EPS = 1e-06

def Ceil(a, b):
	return a // b + int(a % b > 0)

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]

def GetSorted(a):
	a.sort()
	c = 1
	ans = 1
	for i in range(1, len(a)):
		if a[i] != a[i - 1]:
			ans = ans * fact[c] % M
			c = 0
		c += 1
	ans = ans * fact[c] % M
	return ans

def Common(a):
	pass
n = Int()
fact = [1, 1]
for i in range(2, n + 5):
	fact.append(fact[-1] * i % M)
a = []
for i in range(n):
	a.append(value())
ans1 = GetSorted([i[0] for i in a])
ans2 = GetSorted([i[1] for i in a])
ans3 = GetSorted(a)
a.sort()
ok = True
for i in range(1, n):
	if a[i][1] < a[i - 1][1]:
		ok = False
if not ok:
	ans3 = 0
need = (ans1 + ans2) % M
print((fact[n] - (need - ans3 + M) % M + M) % M)


import sys
from collections import defaultdict as dd
mod = 998244353

def ri(flag=0):
	if flag == 0:
		return [int(i) for i in sys.stdin.readline().split()]
	else:
		return int(sys.stdin.readline())
n = ri(1)
one = []
sec = []
take = []
for i in range(n):
	(a, b) = ri()
	one.append(a)
	sec.append(b)
	take.append((a, b))
ans = 1
temp = 1
for i in range(1, n + 1):
	ans = ans * i % mod
take.sort()
cnt1 = 0
cnt2 = 0
c1 = dd(int)
c2 = dd(int)
c3 = dd(int)
status = 1
for i in range(1, n):
	if take[i][1] < take[i - 1][1]:
		status = 0
for i in one:
	c1[i] += 1
for i in sec:
	c2[i] += 1
for i in take:
	c3[i] += 1
ok1 = 1
ok2 = 1
ok3 = 1
fac = [1 for i in range(3 * 10 ** 5 + 1)]
for i in range(1, 3 * 10 ** 5 + 1):
	fac[i] = fac[i - 1] * i % mod
for i in c1:
	ok1 = ok1 * fac[c1[i]] % mod
for i in c2:
	ok2 = ok2 * fac[c2[i]] % mod
for i in c3:
	ok3 = ok3 * fac[c3[i]] % mod
if status == 0:
	ok3 = 0
print((ans - ok1 - ok2 + ok3) % mod)


import sys
from collections import Counter
readline = sys.stdin.readline
readlines = sys.stdin.readlines
mod = 998244353
n = int(input())
ab = [tuple(map(int, readline().split())) for _ in range(n)]
ab.sort()
fun = [1] * (n + 1)
for i in range(1, n + 1):
	fun[i] = fun[i - 1] * i % mod
U = fun[n]
s_ab = 1
s_a = 1
s_b = 1
for i in range(n - 1):
	if ab[i + 1][1] < ab[i][1]:
		s_ab = 0
		break
if s_ab:
	for x in Counter(ab).values():
		s_ab = s_ab * fun[x] % mod
for x in Counter([x[0] for x in ab]).values():
	s_a = s_a * fun[x] % mod
for x in Counter([x[1] for x in ab]).values():
	s_b = s_b * fun[x] % mod
print((U - s_a - s_b + s_ab) % mod)


import sys

def main():
	input = sys.stdin.readline
	n = int(input())
	dg = 10 ** 9
	mod = 998244353
	f = [1]
	for i in range(1, n + 10):
		f.append(f[-1] * i % mod)
	p = []
	q = []
	r = []
	for _ in [0] * n:
		(x, y) = map(int, input().split())
		p.append(x)
		q.append(y)
		r.append(x * dg + y)
	p.sort()
	q.sort()
	r.sort()
	a = 1
	cnt = 1
	for i in range(1, n):
		if p[i] == p[i - 1]:
			cnt += 1
		else:
			a = a * f[cnt] % mod
			cnt = 1
	a = a * f[cnt] % mod
	b = 1
	cnt = 1
	for i in range(1, n):
		if q[i] == q[i - 1]:
			cnt += 1
		else:
			b = b * f[cnt] % mod
			cnt = 1
	b = b * f[cnt] % mod
	judge = True
	for i in range(n):
		if q[i] != r[i] % dg:
			judge = False
	if not judge:
		print((f[n] - a - b) % mod)
		return
	c = 1
	cnt = 1
	for i in range(1, n):
		if r[i] == r[i - 1]:
			cnt += 1
		else:
			c = c * f[cnt] % mod
			cnt = 1
	c = c * f[cnt] % mod
	print((f[n] - a - b + c) % mod)
main()


from collections import Counter
import sys
input = sys.stdin.readline
MOD = 998244353
INF = 10 ** 10
n = int(input())
s = []
a_s = []
b_s = []
for i in range(n):
	(a, b) = [int(item) for item in input().split()]
	s.append((a, b))
	a_s.append(a)
	b_s.append(b)
s.sort()
s.append((INF, INF))
facs = [1] * (n + 1)
ans = 1
for i in range(1, n + 1):
	facs[i] = facs[i - 1] * i % MOD
ans = facs[n]
pa = 0
pb = 0
both_cnt = 1
same = 1
for (a, b) in s:
	if a == pa and b == pb:
		same += 1
	else:
		if b < pb:
			both_cnt = 0
			break
		both_cnt *= facs[same]
		both_cnt %= MOD
		same = 1
	pa = a
	pb = b
acnt = Counter(a_s)
first_cnt = 1
for key in acnt.keys():
	first_cnt *= facs[acnt[key]]
	first_cnt %= MOD
bcnt = Counter(b_s)
second_cnt = 1
for key in bcnt.keys():
	second_cnt *= facs[bcnt[key]]
	second_cnt %= MOD
print((ans - (first_cnt + second_cnt - both_cnt) + MOD) % MOD)


import os
input = os.read(0, 10000000)
MOD = 998244353
MAX = 3 * 100001
pre_fact = [1 for i in range(MAX)]
for i in range(1, MAX):
	pre_fact[i] = pre_fact[i - 1] * i % MOD
spl = list(map(int, input.split()))
n = spl[0]
A = [(spl[i], spl[i + 1]) for i in range(1, 2 * n + 1, 2)]
C = [y for (x, y) in A]
C.sort()
(left, cnt) = (1, 1)
for i in range(1, n):
	if C[i - 1] == C[i]:
		cnt += 1
	else:
		left = left * pre_fact[cnt] % MOD
		cnt = 1
left = left * pre_fact[cnt] % MOD
B = [x for (x, y) in A]
B.sort()
(right, cnt) = (1, 1)
for i in range(1, n):
	if B[i - 1] == B[i]:
		cnt += 1
	else:
		right = right * pre_fact[cnt] % MOD
		cnt = 1
right = right * pre_fact[cnt] % MOD
A.sort()
(both, cnt) = (1, 1)
for i in range(1, n):
	if A[i - 1][1] > A[i][1]:
		both = 0
		break
	if A[i - 1] == A[i]:
		cnt += 1
	else:
		both = both * pre_fact[cnt] % MOD
		cnt = 1
both = both * pre_fact[cnt] % MOD
ans = (pre_fact[n] + MOD - left + MOD - right + both) % MOD
print(ans)


n = int(input())
(s, s2) = ([], [])
mod = 998244353
for i in range(n):
	s.append(tuple(map(int, input().split())))
s.sort()
fact_memo = [1]

def fact(x):
	if len(fact_memo) <= x:
		while len(fact_memo) <= x:
			fact_memo.append(fact_memo[-1] * len(fact_memo) % mod)
	return fact_memo[x]

def calc(seq):
	ans = count = 1
	for i in range(1, n):
		if seq[i - 1] == seq[i]:
			count += 1
		else:
			(count, ans) = (1, ans * (fact(count) % mod) % mod)
	ans = fact(count) * ans % mod
	return ans
s2 = sorted([i[1] for i in s])
ans = calc([i[0] for i in s]) + calc(s2) % mod
if [x[1] for x in s] == s2:
	ans = ans - calc(s) % mod
print((fact(n) - ans) % mod)


import collections
import time
import os
import sys
import bisect
import heapq
from typing import List
MAXN = 3 * 10 ** 5 + 5
F = [1 for _ in range(MAXN)]
MOD = 998244353
for i in range(2, MAXN):
	F[i] = i * F[i - 1] % MOD

def solve(N, A):
	va = [a for (a, b) in A]
	wa = collections.Counter(va)
	bada = 1
	for c in wa.values():
		bada *= F[c]
		bada %= MOD
	vb = [b for (a, b) in A]
	wb = collections.Counter(vb)
	badb = 1
	for c in wb.values():
		badb *= F[c]
		badb %= MOD
	badab = 0
	A.sort()
	if all([A[i][0] <= A[i + 1][0] and A[i][1] <= A[i + 1][1] for i in range(N - 1)]):
		badab = 1
		wab = collections.Counter(A)
		for c in wab.values():
			badab *= F[c]
			badab %= MOD
	total = F[N]
	ans = (2 * MOD + total - bada - badb + badab) % MOD
	print(ans)
N = int(input())
A = []
for i in range(N):
	(a, b) = map(int, input().split())
	A.append((a, b))
solve(N, A)


import io, sys
input = lambda f=io.StringIO(sys.stdin.buffer.read().decode()).readline: f().rstrip()
MAX = 3 * 10 ** 5 + 5
MOD = 998244353
fac = [1] * MAX
for i in range(2, MAX):
	fac[i] = fac[i - 1] * i % MOD

def count(z):
	r = 1
	i = 0
	while i < len(z):
		j = i + 1
		while j < len(z) and z[i] == z[j]:
			j += 1
		r = r * fac[j - i] % MOD
		i = j
	return r
n = int(input())
a = [tuple(map(int, input().split())) for _ in range(n)]
b = sorted(a)
f = sorted((x for (x, _) in a))
s = sorted((y for (_, y) in a))
cnt = count(f) + count(s) - (count(b) if all((b[i][0] <= b[i + 1][0] and b[i][1] <= b[i + 1][1] for i in range(n - 1))) else 0)
print((fac[n] - cnt) % MOD)


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from itertools import *
import bisect
from heapq import *
from math import *
from copy import *
from collections import deque
from collections import Counter as counter
from itertools import combinations as comb
from itertools import permutations as permutate
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
mod = 1000000007

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def zerolist(n):
	return [0] * n

def nextline():
	out('\n')

def testcase(t):
	for p in range(t):
		solve()

def printlist(a):
	for p in range(0, len(a)):
		out(str(a[p]) + ' ')

def lcm(a, b):
	return a * b // gcd(a, b)

def power(a, b):
	ans = 1
	while b > 0:
		if b % 2 == 1:
			ans *= a
		a *= a
		b //= 2
	return ans

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True

def solve():
	n = int(inp())
	a = []
	b = []
	for i in range(n):
		(x, y) = sep()
		a.append(x)
		b.append(y)
	cnta = [0] * (n + 1)
	cntb = [0] * (n + 1)
	for i in range(n):
		cnta[a[i]] += 1
		cntb[b[i]] += 1
	ans = 1
	for i in range(2, n + 1):
		ans *= i
		ans %= 998244353
	temp = 1
	for i in range(n + 1):
		if cnta[i] > 0:
			aisehi = 1
			for j in range(1, cnta[i] + 1):
				aisehi *= j
				aisehi %= 998244353
			temp *= aisehi
			temp %= 998244353
	ans -= temp
	ans %= 998244353
	temp = 1
	for i in range(n + 1):
		if cntb[i] > 0:
			aisehi = 1
			for j in range(1, cntb[i] + 1):
				aisehi *= j
				aisehi %= 998244353
			temp *= aisehi
			temp %= 998244353
	ans -= temp
	ans %= 998244353
	new = []
	for i in range(n):
		new.append([a[i], b[i]])
	new = sorted(new)
	lol = []
	for i in range(n):
		lol.append(new[i][1])
	if lol == sorted(lol):
		cnt = {}
		for i in range(n):
			s = str(new[i][0]) + ' ' + str(new[i][1])
			if s in cnt:
				cnt[s] += 1
			else:
				cnt[s] = 1
		temp = 1
		for i in cnt:
			aisehi = 1
			for j in range(2, cnt[i] + 1):
				aisehi *= j
				aisehi %= 998244353
			temp *= aisehi
			temp %= 998244353
		ans += temp
		ans %= 998244353
	print(ans)
testcase(1)