#include<stdio.h>
#include<stdlib.h>

int main()
{
    int len;
    scanf("%d",&len);
    char arr[len];
    if(len>=1) arr[0] = 'a';
    if(len>=2) arr[1] = 'b';
    for(int i=2;i<len;i++)
    {
        if(arr[i-1] == 'a')
        {
            if(arr[i-2]=='a') arr[i] = 'b';
            else arr[i] = 'a';
        }
        else{
            if(arr[i-2]=='b') arr[i] = 'a';
            else arr[i] = 'b';
        }
    }
    for(int i=0;i<len;i++) printf("%c",arr[i]);
    printf("\n");
    return 0;
}


#include <stdio.h>

int main(int argc, char const *argv[])
{
  int i,n;

    while(~scanf("%d",&n))
    {
        for(i = 1; i <= n; i++)
        {
            if(i%4 == 0 || i%4 == 3)
                printf("b");
            else printf("a");
        }
        printf("\n");
    }
    return 0;
}


#include <stdio.h>

int main(int argc, char const *argv[])
{
  int i,n;

    while(~scanf("%d",&n))
    {
        for(i = 1; i <= n; i++)
        {
            if(i%5 == 0)
                printf("c");
            else if(i%5 < 3)
                    printf("a");
                else printf("b");
        }
        printf("\n");
    }
    return 0;
}


#include<stdio.h>
#include<string.h>

int main()
{
    int n,i,count=0;

    scanf("%d",&n);
    char ltr[n+1];

    for(i=0;i<n;i++){
        if((i+1)%2==1)ltr[i]='a';
        else ltr[i]='b';
    }

    for(i=0;i<n/2;i++){
        if(ltr[i]==ltr[n-i-1]){
            if(ltr[i]=='a')ltr[i]='b';
            else ltr[i]='a';
        }
    }

    printf(ltr);

    return 0;
}


#include<stdio.h>

int main()
{
    int n,i,count=0;

    scanf("%d",&n);

    for(i=0;i<n;i++){
        if((i+1)%3==0)printf("c");
        else if((i+1)%3==1)printf("a");
        else if((i+1)%3==2)printf("b");
    }

    return 0;
}


#include<stdio.h>
#include<string.h>

int main()
{
    int n,i;

    scanf("%d",&n);

    for(i=1;i<=n;i++){
        if(i%4==1 || i%4==0)printf("a");
        else printf("b");
    }

    return 0;
}


#include<stdio.h>
int main()
{
	int k,i;
	scanf("%d",&k);
	for(i=0;i<k/4;i++)
	{
		printf("aabb");
	}
	k=k%4;
	if(k==1)
		printf("a");
	else if(k==2)
		printf("aa");
	else if (k==3)
		printf("aab");
}


k = int(input())
s = ""
if k==1:
	print('a')
elif k==2:
	print('aa')
elif k==3:
	print('bba')
else:
	for i in range(k/4):
		s+="aabb"
	h = k%4
	if h==0:
		pass
	elif h==1:
		s+='a'
	elif h==2:
		s+='aa'
	elif h==3:
		s+='aab'
print(s)


#include <stdio.h>

int main()
{
	int n,i;
	char list[200000];
	scanf("%d", &n);
	if (n <= 2)
	{
		printf("aa");
	}
	else
	{
		list[0] = list[1] = 'a';
		list[2] = 'b';
		for (i = 3;i < n;i++)
		{
			if (list[i - 2] == 'a')
				list[i] = 'b';
			else
				list[i] = 'a';
		}
		for (i = 0;i < n;i++)
			printf("%c", list[i]);
	}
	return 0;
}


#include <stdio.h>

int main()
{
	int n, i;
	char list[200000];
	scanf("%d", &n);
	if (n == 2)
	{
		printf("aa");
	}
	else if (n == 1)
	{
		printf("a");
	}
	else
	{
		list[0] = list[1] = 'a';
		list[2] = 'b';
		for (i = 3;i < n;i++)
		{
			if (list[i - 2] == 'a')
				list[i] = 'b';
			else
				list[i] = 'a';
		}
		for (i = 0;i < n;i++)
			printf("%c", list[i]);
	}
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main(void) {
    int n;
    scanf("%d",&n);
    int i = 0;
    int j = 0;
    while(j<n){
        if(i%2==0){
            printf("%c",'a');
            j++;
            if(j<n)printf("%c",'a');
            j++;
        }
        else{
            printf("%c",'b');
            j++;
            if(j<n)printf("%c",'b');
            j++;
        }
        i++;
    }
	return 0;
}


#include<stdio.h>
#include<string.h>

char str[1000000];

int main()
{
    long int n, i, k;

    scanf("%ld", &n);

    for(i=0; i<n; i++)
    {
        if(i%4==0){str[i]='a';}
        else if(i%3==1){str[i]='a';}
        else if(i%3==2){str[i]='b';}
        else if(i%3==3){str[i]='b';}
    }

    puts(str);
    return 0;

}


#include<stdio.h>
#include<string.h>

char str[1000000];

int main()
{
    long int n, i, k;

    scanf("%ld", &n);

    for(i=0; i<n; i++)
    {
        if(i%4==0){str[i]='a';}
        else if(i%4==1){str[i]='a';}
        else if(i%4==2){str[i]='b';}
        else if(i%4==3){str[i]='b';}
    }

    puts(str);
    return 0;

}


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>

int main()
{
    int n,i;
    scanf("%d",&n);
    while(n>=4){
        printf("aabb");
        n=n-4;
    }
    if(n==1){
        printf("a");
    }
    else if(n==2){
        printf("aa");
    }
    else{
        if(n==3){
            printf("aab");
        }
    }
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>

int main()
{
    int n,i;
    scanf("%d",&n);
    while(n>=4){
        printf("aabc");
        n=n-4;
    }
    if(n==1){
        printf("a");
    }
    else if(n==2){
        printf("aa");
    }
    else{
        if(n==3){
            printf("aab");
        }
    }
    return 0;
}


#include<stdio.h>
int main()
{
    long long int i,r,x;
    scanf("%I64d",&x);
    if(x==1)
        printf("a");
    else if(x%2==0)
    {
        for(i=0;i<x/2;i++)
            printf("ba");

    }
    else
    {
        for(i=0;i<x/2;i++)
            printf("ba");
        printf("a");
    }

}


#include<stdio.h>
int main()
{
    long long int i,y,z,r,x;
    scanf("%I64d",&x);
    z=x/4;
    y=x%4;
    for(i=0;i<z;i++)
        printf("bbaa");
    if(y==1)
        printf("b");
    else if(y==2)
    {
        printf("bb");
    }
    else if(y==3)
    {
        printf("bba");
    }

}


#include<stdio.h>
int main()
{
    long long int i,r,x;
    scanf("%I64d",&x);
    if(x%2==0)
    {
        for(i=0;i<x/2;i++)
            printf("ab");

    }
    else
    {
        for(i=0;i<x/2;i++)
            printf("ab");
        printf("b");
    }

}


#include<stdio.h>
int main()
{
    long long int i,r,x;
    scanf("%I64d",&x);
    if(x%2==0)
    {
        for(i=0;i<x/2;i++)
            printf("aa");

    }
    else
    {
        for(i=0;i<x/2;i++)
            printf("aa");
        printf("a");
    }

}


/* Author Kh. Assaduzzaman Sohan  */

#include<stdio.h>
#include<string.h>
#include<math.h>
#define mod 100000007
char x[4]= {'a','a','b','b'};
int main()
{
    int i,n,r,d;
    scanf("%d",&n);
    for(i=0; i<n; i++)
    {
        if(i%4<2) printf("a");
        else printf("b");
    }

    return 0;
}


#include <stdio.h>

int main() {
	int n, i;

	scanf("%d", &n);
	for (i = 0; i < n; i++)
		printf("%c", 'a' + (i / 2) % 2);
	printf("\n");
	return 0;
}


#include <stdio.h>

int main() {
	int n, i;

	scanf("%d", &n);
	for (i = 0; i < n; i++)
		printf("%c", 'a' + i % 3);
	printf("\n");
	return 0;
}


#include <stdio.h>

int main ()
{
    int n, i;
    char ch = 'a';

    scanf("%d", &n);

    for(i = 0; i < n; i++)
        printf("%c", ch);

    return 0;
}


#include<stdio.h>
#include<stdlib.h>
void main()
{
long long n,i;
scanf("%lld",&n);

if(n%4==0)
for(i=0;i<n/4;i++)
printf("bbaa");

else
{
for(i=0;i<n/4;i++)
printf("bbaa");
if(n%4==1)
printf("b");
else if(n%4==2)
printf("bb");
else
printf("bba");
}

exit(0);
}


#include<stdio.h>
int main()
{
	int i,n;
	char s[5]="aabb";
	scanf("%d",&n);
	for(i=0;i<n;i++){
		putchar(s[i%4]);
	}
	return 0;
}


#include <stdio.h>
int main()
{
	int n,k,i;
	scanf("%d", &n);
	k = 1;
	for (i = 1; i <= n; i++)
	{
		if (k%2 == 0)
			printf("a");
		else
			printf("b");
		if (i%2 == 0)
			k++;
	}
	printf("\n");
	return 0;
}


#include<stdio.h>
int main()
{
  int n;
  int ptr = 0;
  scanf("%d",&n);
  char arr[n];
  arr[0] = 'a';
  if( n > 1)
  {
    arr[1] = 'b';
    int i = 2;
    while(  i != n)
    {
      if( arr[ptr] == 'a') arr[i] = 'b';
      if( arr[ptr] == 'b') arr[i] = 'a';
      ptr++;
      i++;
    }
  }
  for( int i = 0 ; i < n ; i++)
  {
    printf("%c",arr[i]);
  }
  return 0;

}


#include<stdio.h>

int main(void)
{
	int n;
	int i;
	for (i = 0; i < n; i++)
	{
		if (i % 4 == 0 || i % 4 == 1)
			printf("a");
		else
			printf("b");
	}

}


#include<stdio.h>

int main(void)
{
	int n;
	int i;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		if (i % 4 == 0 || i % 4 == 1)
			printf("a");
		else
			printf("b");
	}

}


#include <stdio.h>
int main()
{
    int n, i, j, a;
    scanf("%d", &n);
    a=n%4;
    for(i=0; i<n/4; i++)
    {
        printf("aa");
        printf("bb");
    }
    if(a==1)
        printf("a");
    else if(a==2)
        printf("aa");
    else if(a==3)
        printf("aab");

    return 0;
}


#include <stdio.h>
int main()
{
    int n, i, j, a;
    scanf("%d", &n);
    a=n%4;
    for(i=0; i<n/4; i++)
    {
        printf("aa");
        printf("bb");
    }
    if(a==1)
        printf("a");
    else if(a==2)
        printf("aa");
    else
        printf("aab");

    return 0;
}


#include<stdio.h>
int main()
{
	int n;
	int k;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		k=i%4;
		if(k<2)
			printf("a");
		else
			printf("b");
	}
	return 0;
}


#include<stdio.h>

int main()
{
    int n,i;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        if(i%4==1||i%4==2)
        printf("a");
    else if(i%4==0||i%4==3)
        printf("b");
    }
    printf("\n");
    return 0;
}


#include <stdio.h>

int main()
{
    int number_of_letters, i;
    scanf("%d", &number_of_letters);

    //No letter must have the same neighbour on both the left and the right. aabbaabbaabb.... satisfies this condition
    for(i = 1; i <= number_of_letters; i = i+2)
    {
        if(i%4 == 1)
        {
            printf(i == number_of_letters ? "a\n" : "aa");
        }
        else
        {
            printf(i == number_of_letters ? "b\n" : "bb");
        }
    }
    return 0;
}


#include <stdio.h>

int main()
{
    int number_of_letters, i;
    scanf("%d", &number_of_letters);

    //No letter must have the same neighbour on both the left and the right. aabbaabbaabb.... satisfies this condition
    for(i = 1; i <= number_of_letters; i = i+2)
    {
        if(i%4 == 1) printf("aa");

        else printf("bb");
    }
    if(number_of_letters%2 == 1) printf("\b \n"); //If it's odd, delete the last character

    return 0;
}


#include <stdio.h>
#include <math.h>

int main () {
    int n;
    scanf("%d", &n);
    char str[n+1];

    int i;
    int j = 0;
    for(i = 0; i < n; i+=2) {
        if(j == 0) {
            str[i] = 'a';
            str[i+1] = 'a';
            j = 1;
        }
        else {
            str[i] = 'b';
            str[i+1] = 'b';
            j = 0;
        }
    }
    str[n] = '\0';
    printf("%s", str);

    return 0;
}


#include <stdio.h>
#include <math.h>

int main () {
    int n;
    scanf("%d", &n);
    char str[n+1];

    int i;
    int j = 0;
    for(i = 0; i < n; i++) {
        if(i%4 == 0) {
            str[i] = 'a';
        }
        else if(i%4 == 1 || i%4 == 2) {
            str[i] = 'b';
        }
        else {
            str[i] = 'c';
        }
    }
    str[n] = '\0';
    printf("%s", str);

    return 0;
}


#include <stdio.h>

int main(void) {
	long int n,i,d;

	scanf("%ld",&n);
	char arr[n+1];
	for(i=0;i<n;i++)
	{ d=(i%4);

	  if((d==0)||(d==1))
	  arr[i]='a';
	  else
	  {
	    if(d==2)
	    arr[i]='b';
	    else
	    arr[i]='c';
	  }

	}
	arr[n]='\0';
	printf("%s",arr);
	return 0;
}


#include <stdio.h>

int main(void) {
	long int n,i,d;

	scanf("%ld",&n);
	char arr[n+1];
	for(i=0;i<n;i++)
	{ d=(i%4);

	  if((d==0)||(d==1))
	  arr[i]='a';
	  else
	  {
	    if(d==2)
	    arr[i]='b';
	    else
	    arr[i]='b';
	  }

	}
	arr[n]='\0';
	printf("%s",arr);
	return 0;
}


#include <stdio.h>

int main()
{
    int n;
    char str[4] = "aabb";
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) {
        putchar(str[i & 3]);
    }
    putchar('\n');
    return 0;
}


#include<stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int i;
    for(i=0;i<n;i++){
        if(i%4==0 || i%4==1)printf("a");
        else printf("b");
    }
    printf("\n");
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
    int a,n,b,c,i,j,k;
    char str[200000];
    scanf("%d",&n);
    if(n==1)
    {
        printf("a");
    }
   else if(n==2)
    {
        printf("ab");
    }
    else if(n==3)
    {
        printf("aab");
    }
    else if(n==4)
    {
        printf("aabb");
    }
    else
    {
    for(i=0;i<n;)
    {
        if(i<=n-1)
        {
        str[i]='a';
        i++;
        }
        if(i<=n-1)
        {
        str[i]='a';
        i++;
        }
        if(i<=n-1)
        {
        str[i]='b';
        i++;
        }
        if(i<=n-1)
        {
        str[i]='b';
        i++;
        }
       // if(i==n-1)
        //{

          //  break;
        //}
}
    printf("%s",str);
   }
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
    int a,n,b,c,i,j,k;
    char str[200000];
    scanf("%d",&n);
    if(n==1)
    {
        printf("a");
    }
   else if(n==2)
    {
        printf("ab");
    }
    else if(n==3)
    {
        printf("aab");
    }
    else if(n==4)
    {
        printf("aabb");
    }
    else
    {
    for(i=0;i<n;)
    {
        if(i<n-1)
        {
        str[i]='a';
        i++;
        }
        if(i<n-1)
        {
        str[i]='a';
        i++;
        }
        if(i<n-1)
        {
        str[i]='b';
        i++;
        }
        if(i<n-1)
        {
        str[i]='b';
        i++;
        }

      if(i==n-1)
     {
        str[i]='c';
        break;
     }

    }
    printf("%s",str);
   }
}


#include <stdio.h>

int main()
{
	int n; scanf("%d", &n);
	int i;
	for(i = 1; i <= n; i++)
	{
		if(i%4 == 1 || i%4 == 2) printf("a");
		else printf("b");
	}
	printf("\n");
	return 0;
}


#include<stdio.h>
#include<stdlib.h>

int main()
{
	long int i,n;
	int count=0;
	scanf("%ld",&n);
	for(i=0;i<n;i++){
		count++;
		if(count==1)
			printf("a");
		else if(count==2)
			printf("a");
		else if(count==3)
			printf("b");
		else if(count==4){
			printf("b");
			count=0;
		}
	}
	return 0;
}


#include<stdio.h>
#include<stdlib.h>

int main()
{
	long long int i,n;
	int count=0;
	scanf("%l64d",&n);
	for(i=0;i<n;i++){
		count++;
		if(count==1)
			printf("a");
		else if(count==2)
			printf("a");
		else if(count==3)
			printf("b");
		if(count==4){
			printf("b");
			count=0;
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#define int uint64_t
using namespace std;

const int m = 3e5 + 5, MOD = 998244353;
int n;
int fact[m];
vector<pair<int, int> > vec;
map<int, int> mpf, mps;
map<pair<int, int>, int> mpfs;

int32_t main()
{
	fact[0] = 0LL;
	fact[1] = 1LL;
	for (int i = 2; i <= m; ++i)
		fact[i] = (fact[i - 1] * i) % MOD;

	cin >> n;
	int x, y;
	for (int i = 0; i < n; ++i)
	{
		cin >> x >> y;
		mpf[x]++;
		mps[y]++;
		vec.push_back({x, y});
		mpfs[{x, y}]++;
	}

	int cnt1 = 1, cnt2 = 1, cnt12 = 1;

	for (auto i : mpf)
		cnt1 = (cnt1 % MOD * fact[i.second] % MOD) % MOD;

	for (auto i : mps)
		cnt2 = (cnt2 % MOD * fact[i.second] % MOD) % MOD;

	sort(vec.begin(), vec.end());
	bool flag = true;

	for (int i = 0; i < n - 1; ++i)
		if (vec[i].second > vec[i + 1].second)
		{
			cnt12 = 0;
			flag = false;
			break;
		}

	if (flag)
		for (auto i : mpfs)
			cnt12 = (cnt12 % MOD * fact[i.second] % MOD) % MOD;

	cout << fact[n] - cnt1 - cnt2 + cnt12 << "\n";
}


#include <bits/stdc++.h>
#define int int64_t
using namespace std;

const int m = 3e5 + 5, MOD = 998244353;
int n;
int fact[m];
vector<pair<int, int> > vec;
map<int, int> mpf, mps;
map<pair<int, int>, int> mpfs;

int32_t main()
{
	fact[0] = 0;
	fact[1] = 1;
	for (int i = 2; i <= m; ++i)
		fact[i] = (fact[i - 1] % MOD * i % MOD) % MOD;

	cin >> n;
	int x, y;
	for (int i = 0; i < n; ++i)
	{
		cin >> x >> y;
		mpf[x]++;
		mps[y]++;
		vec.push_back({x, y});
		mpfs[{x, y}]++;
	}

	int cnt1 = 1, cnt2 = 1, cnt12 = 1;

	for (auto i : mpf)
		cnt1 = (cnt1 % MOD * fact[i.second] % MOD) % MOD;

	for (auto i : mps)
		cnt2 = (cnt2 % MOD * fact[i.second] % MOD) % MOD;

	sort(vec.begin(), vec.end());
	bool flag = true;

	for (int i = 0; i < n - 1; ++i)
		if (vec[i].second > vec[i + 1].second)
		{
			cnt12 = 0;
			flag = false;
			break;
		}

	if (flag)
		for (auto i : mpfs)
			cnt12 = (cnt12 % MOD * fact[i.second] % MOD) % MOD;

	cout << fact[n] - cnt1 - cnt2 + cnt12 << "\n";
}


#include <bits/stdc++.h>
#define int int64_t
using namespace std;

const int m = 3e5 + 5, MOD = 998244353;
int n;
int fact[m];
vector<pair<int, int> > vec;
map<int, int> mpf, mps;
map<pair<int, int>, int> mpfs;

int32_t main()
{
	fact[0] = 0;
	fact[1] = 1;
	for (int i = 2; i < m; ++i)
		fact[i] = (fact[i - 1] * i) % MOD;

	cin >> n;
	int x, y;
	for (int i = 0; i < n; ++i)
	{
		cin >> x >> y;
		mpf[x]++;
		mps[y]++;
		vec.push_back({x, y});
		mpfs[{x, y}]++;
	}

	int cnt1 = 1, cnt2 = 1, cnt12 = 1;

	for (auto i : mpf)
		cnt1 = (cnt1 * fact[i.second]) % MOD;

	for (auto i : mps)
		cnt2 = (cnt2 * fact[i.second]) % MOD;

	sort(vec.begin(), vec.end());
	bool flag = true;

	for (int i = 0; i < n - 1; ++i)
		if (vec[i].second > vec[i + 1].second)
			cnt12 = 0;

	for (auto i : mpfs)
		cnt12 = (cnt12 * fact[i.second]) % MOD;

	cout << (fact[n] % MOD - cnt1 % MOD - cnt2 % MOD + cnt12 % MOD) % MOD << "\n";
}


#include <bits/stdc++.h>
#define ll  long long
using namespace std;
#define mod 998244353
ll fact[300005];

int main()
{
    fact[0]=1;
    for(ll i=1;i<=300000;i++)
        fact[i]=(fact[i-1]*i)%mod;

    ll n; cin>>n;
    vector<pair<ll,ll> >v;
    for(ll i=0;i<n;i++)
    {
        ll x,y; cin>>x>>y;
        v.push_back({x,y});
    }
    sort(v.begin(),v.end());
    ll i=0,temp=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp=(temp*fact[j-i])%mod;
        i=j;
    }

    for(ll i=0;i<n;i++)
        swap(v[i].first,v[i].second);
    i=0;
    ll temp1=1;
    sort(v.begin(),v.end());
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp1=(temp1*fact[j-i])%mod;
        i=j;
    }

    ll ans=(fact[n]-temp1)%mod;
    ans= ans+mod;
    ans=ans%mod;
    ans = ((ans-temp)%mod+mod)%mod;
    bool ch=true;
    for(ll i=1;i<n;i++)
    {
        if(v[i].second<v[i-1].second)
          {
              ch=false;
          }
    }
    if(!ch)
       return cout<<ans<<endl,0;
     i=0;
     ll temp2=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
            j++;
        map<ll,ll>mp;
        for(ll k=i;k<j;k++)
        {
            mp[v[k].first]++;
        }
        for(auto m : mp)
        {
            temp2=(temp2*fact[m.second])%mod;
        }
        i=j;
    }
    ans= ans+temp2;
    ans=ans%mod;
   // cout<<temp<<" "<<temp1<<" "<<temp2<<endl;
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll  long long
using namespace std;
#define mod 998244353
ll fact[300005];

int main()
{
    fact[0]=1;
    for(ll i=1;i<=300000;i++)
        fact[i]=(fact[i-1]*i)%mod;

    ll n; cin>>n;
    vector<pair<ll,ll> >v;
    for(ll i=0;i<n;i++)
    {
        ll x,y; cin>>x>>y;
        v.push_back({x,y});
    }
    sort(v.begin(),v.end());
    ll i=0,temp=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp=(temp*fact[j-i])%mod;
        i=j;
    }

    for(ll i=0;i<n;i++)
        swap(v[i].first,v[i].second);
    i=0;
    ll temp1=1;
    sort(v.begin(),v.end());
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
      //  cout<<i<<" "<<j<<endl;
        temp1=(temp1*fact[j-i])%mod;
        i=j;
    }
 //   cout<<"DSA DD A D  "<<temp1<<" "<<temp<<endl;
    ll ans=(fact[n]-temp1-temp)%mod;
    ans+=mod;
    ans%=mod;
    bool ch=true;
    for(ll i=1;i<n;i++)
    {
        if(v[i].second<v[i-1].second)
          {
              ch=false;
          }
    }
    if(!ch)
       return cout<<ans<<endl,0;
     i=0;ll temp2=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
            j++;
        map<ll,ll>mp;
        for(ll k=i;k<j;k++)
        {
            mp[v[k].second]++;
        }
        for(auto m : mp)
        {
            temp2=(temp2*fact[m.second])%mod;
        }
        i=j;
    }
    ans+=temp2;
    ans%=mod;
   // cout<<temp<<" "<<temp1<<" "<<temp2<<endl;
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll  long long
using namespace std;
#define mod 998244353
ll fact[300005];

int main()
{
    fact[0]=1;
    for(ll i=1;i<=300002;i++)
        fact[i]=(fact[i-1]*i)%mod;

    ll n; cin>>n;
    vector<pair<ll,ll> >v;
    for(ll i=0;i<n;i++)
    {
        ll x,y; cin>>x>>y;
        v.push_back({x,y});
    }
    sort(v.begin(),v.end());
    ll i=0,temp=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp=(temp*fact[j-i])%mod;
        i=j;
    }

    for(ll i=0;i<n;i++)
        swap(v[i].first,v[i].second);
    i=0;
    ll temp1=1;
    sort(v.begin(),v.end());
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp1=(temp1*fact[j-i])%mod;
        i=j;
    }

    ll ans=(fact[n]-temp1)%mod;
    ans= ans+mod;
    ans=ans%mod;
    ans = ((ans-temp)%mod+mod)%mod;
    bool ch=true;
    for(ll i=1;i<n;i++)
    {
        if(v[i].second<v[i-1].second)
          {
              ch=false;
          }
    }
    if(!ch)
       return cout<<ans<<endl,0;
     i=0;
     ll temp2=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
            j++;
        map<ll,ll>mp;
        for(ll k=i;k<j;k++)
        {
            mp[v[k].second]++;
        }
        for(auto m : mp)
        {
            temp2=(temp2*fact[m.second])%mod;
        }
        i=j;
    }
    ans= ans+temp2;
    ans=ans%mod;
   // cout<<temp<<" "<<temp1<<" "<<temp2<<endl;
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll  long long
using namespace std;
#define mod 998244353
ll fact[300005];

int main()
{
    fact[0]=1;
    for(ll i=1;i<=300000;i++)
        fact[i]=(fact[i-1]*i)%mod;

    ll n; cin>>n;
    vector<pair<ll,ll> >v;
    for(ll i=0;i<n;i++)
    {
        ll x,y; cin>>x>>y;
        v.push_back({x,y});
    }
    sort(v.begin(),v.end());
    ll i=0,temp=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp=(temp*fact[j-i])%mod;
        i=j;
    }

    for(ll i=0;i<n;i++)
        swap(v[i].first,v[i].second);
    i=0;
    ll temp1=1;
    sort(v.begin(),v.end());
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp1=(temp1*fact[j-i])%mod;
        i=j;
    }

    ll ans=(fact[n]-temp1)%mod;
    ans= ans+mod;
    ans=ans%mod;
    ans = ((ans-temp)%mod+mod)%mod;
    bool ch=true;
    for(ll i=1;i<n;i++)
    {
        if(v[i].second<v[i-1].second)
          {
              ch=false;
          }
    }
    if(!ch)
       return cout<<ans<<endl,0;
     i=0;
     ll temp2=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
            j++;
        map<ll,ll>mp;
        for(ll k=i;k<j;k++)
        {
            mp[v[k].second]++;
        }
        for(auto m : mp)
        {
            temp2=(temp2*fact[m.second])%mod;
        }
        i=j;
    }
    ans= ans+temp2;
    ans=ans%mod;
   // cout<<temp<<" "<<temp1<<" "<<temp2<<endl;
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll  long long
using namespace std;
#define mod 998244353
ll fact[300005];

int main()
{
    fact[0]=1;
    for(ll i=1;i<=300000;i++)
        fact[i]=(fact[i-1]*i)%mod;

    ll n; cin>>n;
    vector<pair<ll,ll> >v;
    for(ll i=0;i<n;i++)
    {
        ll x,y; cin>>x>>y;
        v.push_back({x,y});
    }
    sort(v.begin(),v.end());
    ll i=0,temp=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp=(temp*fact[j-i])%mod;
        i=j;
    }

    for(ll i=0;i<n;i++)
        swap(v[i].first,v[i].second);
    i=0;
    ll temp1=1;
    sort(v.begin(),v.end());
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        cout<<i<<" "<<j<<endl;
        temp1=(temp1*fact[j-i])%mod;
        i=j;
    }
 //   cout<<"DSA DD A D  "<<temp1<<" "<<temp<<endl;
    ll ans=(fact[n]-temp1-temp)%mod;
    ans+=mod;
    ans%=mod;
    bool ch=true;
    for(ll i=1;i<n;i++)
    {
        if(v[i].second<v[i-1].second)
          {
              ch=false;
          }
    }
    if(!ch)
       return cout<<ans<<endl,0;
     i=0;ll temp2=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
            j++;
        map<ll,ll>mp;
        for(ll k=i;k<j;k++)
        {
            mp[v[k].first]++;
        }
        for(auto m : mp)
        {
            temp2=(temp2*fact[m.second])%mod;
        }
        i=j;
    }
    ans+=temp2;
    ans%=mod;
   // cout<<temp<<" "<<temp1<<" "<<temp2<<endl;
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll  long long
using namespace std;
#define mod 998244353
ll fact[300005];

int main()
{
    fact[0]=1;
    for(ll i=1;i<=300000;i++)
        fact[i]=(fact[i-1]*i)%mod;

    ll n; cin>>n;
    vector<pair<ll,ll> >v;
    for(ll i=0;i<n;i++)
    {
        ll x,y; cin>>x>>y;
        v.push_back({x,y});
    }
    sort(v.begin(),v.end());
    ll i=0,temp=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp=(temp*fact[j-i])%mod;
        i=j;
    }

    for(ll i=0;i<n;i++)
        swap(v[i].first,v[i].second);
    i=0;
    ll temp1=1;
    sort(v.begin(),v.end());
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
      //  cout<<i<<" "<<j<<endl;
        temp1=(temp1*fact[j-i])%mod;
        i=j;
    }
 //   cout<<"DSA DD A D  "<<temp1<<" "<<temp<<endl;
    ll ans=(fact[n]-temp1-temp)%mod;
    ans+=mod;
    ans%=mod;
    bool ch=true;
    for(ll i=1;i<n;i++)
    {
        if(v[i].second<v[i-1].second)
          {
              ch=false;
          }
    }
    if(!ch)
       return cout<<ans<<endl,0;
     i=0;ll temp2=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
            j++;
        map<ll,ll>mp;
        for(ll k=i;k<j;k++)
        {
            mp[v[k].first]++;
        }
        for(auto m : mp)
        {
            temp2=(temp2*fact[m.second])%mod;
        }
        i=j;
    }
    ans+=temp2;
    ans%=mod;
   // cout<<temp<<" "<<temp1<<" "<<temp2<<endl;
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll  long long
using namespace std;
#define mod 998244353
ll fact[300005];

int main()
{
    fact[0]=1;
    for(ll i=1;i<=300000;i++)
        fact[i]=(fact[i-1]*i)%mod;

    ll n; cin>>n;
    vector<pair<ll,ll> >v;
    for(ll i=0;i<n;i++)
    {
        ll x,y; cin>>x>>y;
        v.push_back({x,y});
    }
    sort(v.begin(),v.end());
    ll i=0,temp=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp=(temp*fact[j-i])%mod;
        i=j;
    }

    for(ll i=0;i<n;i++)
        swap(v[i].first,v[i].second);
    i=0;
    ll temp1=1;
    sort(v.begin(),v.end());
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
        {
            j++;
        }
        temp1=(temp1*fact[j-i])%mod;
        i=j;
    }

    ll ans=(fact[n]-temp1-temp)%mod;
    ans= ans+mod;
    ans=ans%mod;
    bool ch=true;
    for(ll i=1;i<n;i++)
    {
        if(v[i].second<v[i-1].second)
          {
              ch=false;
          }
    }
    if(!ch)
       return cout<<ans<<endl,0;
     i=0;
     ll temp2=1;
    while(i<n)
    {
        ll j=i+1;
        while(j<n and v[j].first==v[j-1].first)
            j++;
        map<ll,ll>mp;
        for(ll k=i;k<j;k++)
        {
            mp[v[k].first]++;
        }
        for(auto m : mp)
        {
            temp2=(temp2*fact[m.second])%mod;
        }
        i=j;
    }
    ans= ans+temp2;
    ans=ans%mod;
   // cout<<temp<<" "<<temp1<<" "<<temp2<<endl;
    cout<<ans<<endl;
}


// In His Name

#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define gcd __gcd
#define int long long
#define ull unsigned long long

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

const int MAX = 3e5 + 10, MOD = 998244353;
int n;
pii a[MAX];

main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 0 ; i < n ; i++){
		cin >> a[i].F >> a[i].S;
	}
	int all = 1;
	for (int i = 2 ; i <= n ; i++){
		all *= i;
		all %= MOD;
	}
	sort (a, a + n, [] (pii x, pii y){
		return x.S < y.S;
	});
	int ans = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].S == a[i + 1].S){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans *= cnt;
		ans %= MOD;
	}
	sort (a, a + n, [] (pii x, pii y){
		return x.F < y.F;
	});
	all = (all - ans) % MOD;
	ans = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans *= cnt;
		ans %= MOD;
	}
	all = (all - ans) % MOD;
	ans = 1;
	bool F = 0;
	for (int i = 0 ; i < n - 1 ; i++){
		if (a[i].F > a[i + 1].F || a[i].S > a[i + 1].S){
			F = 1;
		}
	}
	if (F){
		return cout << (all + MOD) % MOD, 0;
	}
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans *= cnt;
		ans %= MOD;
	}
	all += ans, all %= MOD;
	cout << (all + MOD) % MOD;
}


    // In His Name

    #include <bits/stdc++.h>

    #define pb push_back
    #define F first
    #define S second
    #define gcd __gcd
    #define int long long
    #define ull unsigned long long

    using namespace std;

    typedef pair<int, int> pii;
    typedef long long ll;

    const int MAX = 3e5 + 10, MOD = 998244353;
    int n;
    pii a[MAX];

    main(){
    	ios_base::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	cin >> n;
    	for (int i = 0 ; i < n ; i++){
    		cin >> a[i].F >> a[i].S;
    	}
    	sort (a, a + n, [] (pii x, pii y){
    		return x.S < y.S;
    	});
    	int ans = 1;
    	for (int i = 0 ; i < n - 1 ; i++){
    		int cnt = 1, j = 1;
    		while (a[i].S == a[i + 1].S){
    			j++;
    			i++;
    			cnt *= j;
    			cnt %= MOD;
    		}
    		ans *= cnt;
    		ans %= MOD;
    	}
    	sort (a, a + n, [] (pii x, pii y){
    		if (x.F == y.F){
			return x.S < y.S;
    		}
    		return x.F < y.F;
    	});
    	int ans2 = 1;
    	for (int i = 0 ; i < n - 1 ; i++){
    		int cnt = 1, j = 1;
    		while (a[i].F == a[i + 1].F){
    			j++;
    			i++;
    			cnt *= j;
    			cnt %= MOD;
    		}
    		ans2 *= cnt;
    		ans2 %= MOD;
    	}
    	int ans3 = 1;
    	bool F = 0;
    	for (int i = 0 ; i < n - 1 ; i++){
    		int cnt = 1, j = 1;
    		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
    			j++;
    			i++;
    			cnt *= j;
    			cnt %= MOD;
    		}
    		ans3 *= cnt;
    		ans3 %= MOD;
    	}
    	for (int i = 0 ; i < n - 1 ; i++){
    		if (a[i].F > a[i + 1].F || a[i].S > a[i + 1].S){
    			F = 1;
    		}
    	}
    	if (F){
    		ans3 = 0;
    	}
    	ans += ans2;
    	ans %= MOD;
    	if (ans < ans3){
    		ans += MOD;
    	}
    	ans -= ans3;
    	ans %= MOD;
    	int all = 1;
    	for (int i = 2 ; i <= n ; i++){
    		all *= i;
    		all %= MOD;
    	}
    	if (all < ans){
    		all += MOD;
    	}
    	all -= ans;
    	cout << (all + MOD) % MOD;
    }


// In His Name

#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define gcd __gcd
#define int long long
#define ull unsigned long long

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

const int MAX = 3e5 + 10, MOD = 998244353;
int n, Factorial[MAX];
pii a[MAX];

main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 0 ; i < n ; i++){
		cin >> a[i].F >> a[i].S;
	}
	int all = 1, ans = 1;
	Factorial[0] = 1;
	for (int i = 1 ; i <= n ; i++){
		Factorial[i] = (Factorial[i - 1] * i) % MOD;
	}
	all = Factorial[n];
	sort (a, a + n, [] (pii x, pii y){
		return x.S < y.S;
	});
	for (int i = 0 ; i < n - 1 ; i++){
		int j = 1;
		while (a[i].S == a[i + 1].S){
			j++, i++;
		}
		ans = (ans * Factorial[j]) % MOD;
	}
	all = (all - ans) % MOD, ans = 1;
	sort (a, a + n, [] (pii x, pii y){
		return x.F < y.F;
	});
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F){
			j++, i++;
		}
		ans = (ans * Factorial[j]) % MOD;
	}
	all = (all - ans) % MOD, ans = 1;
	bool F = 0;
	for (int i = 0 ; i < n - 1 ; i++){
		if (a[i].S > a[i + 1].S){
			F = 1;
		}
	}
	if (F){
		return cout << (all + MOD) % MOD, 0;
	}
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
			j++, i++;
		}
		ans = (ans * Factorial[j]) % MOD;
	}
	all = (all + ans) % MOD;
	cout << (all + MOD) % MOD;
}


// In His Name

#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define gcd __gcd
#define int long long
#define ull unsigned long long

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

const int MAX = 3e5 + 10, MOD = 998244353;
int n;
pii a[MAX];

main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	int all = 1;
	for (int i = 2 ; i <= n ; i++){
		all *= i;
		all %= MOD;
	}
	for (int i = 0 ; i < n ; i++){
		cin >> a[i].F >> a[i].S;
	}
	sort (a, a + n, [] (pii x, pii y){
		return x.S < y.S;
	});
	int ans = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].S == a[i + 1].S){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans *= cnt;
		ans %= MOD;
	}
	sort (a, a + n, [] (pii x, pii y){
		return x.F < y.F;
	});
	int ans2 = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans2 *= cnt;
		ans2 %= MOD;
	}
	bool F = 0;
	for (int i = 0 ; i < n - 1 ; i++){
		if (a[i].F > a[i + 1].F || a[i].S > a[i + 1].S){
			F = 1;
		}
	}
	if (F){
    	return cout << all - ans, 0;
	}
	int ans3 = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i] == a[i + 1]){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans3 *= cnt;
		ans3 %= MOD;
	}
	ans += ans2;
	ans %= MOD;
	if (ans < ans3){
		ans += MOD;
	}
	ans -= ans3;
	ans %= MOD;
	if (all < ans){
		all += MOD;
	}
	all -= ans;
	all %= MOD;
	cout << (all + MOD) % MOD;
}


// In His Name

#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define gcd __gcd
#define int long long
#define ull unsigned long long

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

const int MAX = 3e5 + 10, MOD = 998244353;
int n, Factorial[MAX];
pii a[MAX];

main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 0 ; i < n ; i++){
		cin >> a[i].F >> a[i].S;
	}
	int all = 1, ans = 1;
	Factorial[0] = 1;
	for (int i = 1 ; i <= n ; i++){
		Factorial[i] = (Factorial[i - 1] * i) % MOD;
	}
	all = Factorial[n];
	sort (a, a + n, [] (pii x, pii y){
		return x.S < y.S;
	});
	for (int i = 0 ; i < n - 1 ; i++){
		int j = 1;
		while (a[i].S == a[i + 1].S){
			j++, i++;
		}
		ans = (ans * Factorial[j]) % MOD;
	}
	all = (all - ans) % MOD, ans = 1;
	sort (a, a + n, [] (pii x, pii y){
		if (x.F == y.F){
			return x.S < y.S;
		}
		return x.F < y.F;
	});
	for (int i = 0 ; i < n - 1 ; i++){
		int j = 1;
		while (a[i].F == a[i + 1].F){
			j++, i++;
		}
		ans = (ans * Factorial[j]) % MOD;
	}
	all = (all - ans) % MOD, ans = 1;
	bool F = 0;
	for (int i = 0 ; i < n - 1 ; i++){
		if (a[i].S > a[i + 1].S){
			F = 1;
		}
	}
	if (F){
		return cout << (all + MOD) % MOD, 0;
	}
	for (int i = 0 ; i < n - 1 ; i++){
		int j = 1;
		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
			j++, i++;
		}
		ans = (ans * Factorial[j]) % MOD;
	}
	all = (all + ans) % MOD;
	cout << (all + MOD) % MOD;
}


        // In His Name

        #include <bits/stdc++.h>

        #define pb push_back
        #define F first
        #define S second
        #define gcd __gcd
        #define int long long
        #define ull unsigned long long

        using namespace std;

        typedef pair<int, int> pii;
        typedef long long ll;

        const int MAX = 3e5 + 10, MOD = 998244353;
        int n;
        pii a[MAX];

        main(){
        	ios_base::sync_with_stdio(0);
        	cin.tie(0);
        	cout.tie(0);
        	cin >> n;
        	for (int i = 0 ; i < n ; i++){
        		cin >> a[i].F >> a[i].S;
        	}
        	sort (a, a + n, [] (pii x, pii y){
        		return x.S < y.S;
        	});
        	int ans = 1;
        	for (int i = 0 ; i < n - 1 ; i++){
        		int cnt = 1, j = 1;
        		while (a[i].S == a[i + 1].S){
        			j++;
        			i++;
        			cnt *= j;
        			cnt %= MOD;
        		}
        		ans *= cnt;
        		ans %= MOD;
        	}
        	//cout << "ans " << ans << endl;
        	sort (a, a + n, [] (pii x, pii y){
        		if (x.F == y.F){
        		    return x.S < y.S;
        		}
        		    return x.F < y.F;
        	});
        	int ans2 = 1;
        	for (int i = 0 ; i < n - 1 ; i++){
        		int cnt = 1, j = 1;
        		while (a[i].F == a[i + 1].F){
        			j++;
        			i++;
        			cnt *= j;
        			cnt %= MOD;
        		}
        		ans2 *= cnt;
        		ans2 %= MOD;
        	}
        	//cout << "ans2 " << ans2 << endl;
        	int ans3 = 1;
        	bool F = 0;
        	for (int i = 0 ; i < n - 1 ; i++){
        		int cnt = 1, j = 1;
        		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
        			j++;
        			i++;
        			cnt *= j;
        			cnt %= MOD;
        		}
        		ans3 *= cnt;
        		ans3 %= MOD;
        	}
        	for (int i = 0 ; i < n - 1 ; i++){
        		if (a[i].F > a[i + 1].F || a[i].S > a[i + 1].S){
        			F = 1;
        		}
        	}
        	if (F){
        		ans3 = 0;
        	}
        	//cout << "ans3 " << ans3 << endl;
        	ans += ans2;
        	ans %= MOD;
        	if (ans < ans3){
        		ans += MOD;
        	}
        	/*for (int i = 0 ; i < n ; i++){
        		cout << a[i].F << " " << a[i].S << endl;
        	}*/
        	ans -= ans3;
        	ans %= MOD;
        	int all = 1;
        	for (int i = 2 ; i <= n ; i++){
        		all *= i;
        		all %= MOD;
        	}
        	//cout << "all " << all << endl;
        	if (all < ans){
        		all += MOD;
        	}
        	all -= ans;
        	cout << (all + MOD) % MOD;
    }


// In His Name

#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define gcd __gcd
#define int long long
#define ull unsigned long long

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

const int MAX = 3e5 + 10, MOD = 998244353;
int n;
pii a[MAX];

main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 0 ; i < n ; i++){
		cin >> a[i].F >> a[i].S;
	}
	sort (a, a + n, [] (pii x, pii y){
		return x.S < y.S;
	});
	int ans = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].S == a[i + 1].S){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans *= cnt;
		ans %= MOD;
	}
	//cout << "ans " << ans << endl;
	sort (a, a + n, [] (pii x, pii y){
		return x.F < y.F;
	});
	int ans2 = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans2 *= cnt;
		ans2 %= MOD;
	}
	//cout << "ans2 " << ans2 << endl;
	int ans3 = 1;
	bool F = 0;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans3 *= cnt;
		ans3 %= MOD;
	}
	for (int i = 0 ; i < n - 1 ; i++){
		if (a[i].F > a[i + 1].F || a[i].S > a[i + 1].S){
			F = 1;
		}
	}
	if (F){
		ans3 = 0;
	}
	//cout << "ans3 " << ans3 << endl;
	ans += ans2;
	ans %= MOD;
	if (ans < ans3){
		ans += MOD;
	}
	/*for (int i = 0 ; i < n ; i++){
		cout << a[i].F << " " << a[i].S << endl;
	}*/
	ans -= ans3;
	ans %= MOD;
	int all = 1;
	for (int i = 2 ; i <= n ; i++){
		all *= i;
		all %= MOD;
	}
	//cout << "all " << all << endl;
	if (all < ans){
		all += MOD;
	}
	all -= ans;
	cout << all;
}


    // In His Name

    #include <bits/stdc++.h>

    #define pb push_back
    #define F first
    #define S second
    #define gcd __gcd
    #define int long long
    #define ull unsigned long long

    using namespace std;

    typedef pair<int, int> pii;
    typedef long long ll;

    const int MAX = 3e5 + 10, MOD = 998244353;
    int n;
    pii a[MAX];

    main(){
    	ios_base::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	cin >> n;
    	for (int i = 0 ; i < n ; i++){
    		cin >> a[i].F >> a[i].S;
    	}
    	sort (a, a + n, [] (pii x, pii y){
    		return x.S < y.S;
    	});
    	int ans = 1;
    	for (int i = 0 ; i < n - 1 ; i++){
    		int cnt = 1, j = 1;
    		while (a[i].S == a[i + 1].S){
    			j++;
    			i++;
    			cnt *= j;
    			cnt %= MOD;
    		}
    		ans *= cnt;
    		ans %= MOD;
    	}
    	//cout << "ans " << ans << endl;
    	sort (a, a + n, [] (pii x, pii y){
    		return x.F < y.F;
    	});
    	int ans2 = 1;
    	for (int i = 0 ; i < n - 1 ; i++){
    		int cnt = 1, j = 1;
    		while (a[i].F == a[i + 1].F){
    			j++;
    			i++;
    			cnt *= j;
    			cnt %= MOD;
    		}
    		ans2 *= cnt;
    		ans2 %= MOD;
    	}
    	//cout << "ans2 " << ans2 << endl;
    	int ans3 = 1;
    	bool F = 0;
    	for (int i = 0 ; i < n - 1 ; i++){
    		int cnt = 1, j = 1;
    		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
    			j++;
    			i++;
    			cnt *= j;
    			cnt %= MOD;
    		}
    		ans3 *= cnt;
    		ans3 %= MOD;
    	}
    	for (int i = 0 ; i < n - 1 ; i++){
    		if (a[i].F > a[i + 1].F || a[i].S > a[i + 1].S){
    			F = 1;
    		}
    	}
    	if (F){
    		ans3 = 0;
    	}
    	//cout << "ans3 " << ans3 << endl;
    	ans += ans2;
    	ans %= MOD;
    	if (ans < ans3){
    		ans += MOD;
    	}
    	/*for (int i = 0 ; i < n ; i++){
    		cout << a[i].F << " " << a[i].S << endl;
    	}*/
    	ans -= ans3;
    	ans %= MOD;
    	int all = 1;
    	for (int i = 2 ; i <= n ; i++){
    		all *= i;
    		all %= MOD;
    	}
    	//cout << "all " << all << endl;
    	if (all < ans){
    		all += MOD;
    	}
    	all -= ans;
    	cout << (all + MOD) % MOD;
}


// In His Name

#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define gcd __gcd
#define int long long
#define ull unsigned long long

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

const int MAX = 3e5 + 10, MOD = 998244353;
int n;
pii a[MAX];

main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 0 ; i < n ; i++){
		cin >> a[i].F >> a[i].S;
	}
	sort (a, a + n, [] (pii x, pii y){
		return x.S < y.S;
	});
	int ans = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].S == a[i + 1].S){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans *= cnt;
		ans %= MOD;
	}
	sort (a, a + n, [] (pii x, pii y){
		return x.F < y.F;
	});
	int ans2 = 1;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans2 *= cnt;
		ans2 %= MOD;
	}
	int ans3 = 1;
	bool F = 0;
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
			j++;
			i++;
			cnt *= j;
			cnt %= MOD;
		}
		ans3 *= cnt;
		ans3 %= MOD;
	}
	for (int i = 0 ; i < n - 1 ; i++){
		if (a[i].F > a[i + 1].F || a[i].S > a[i + 1].S){
			F = 1;
		}
	}
	if (F){
		ans3 = 0;
	}
	ans += ans2;
	ans %= MOD;
	if (ans < ans3){
		ans += MOD;
	}
	ans -= ans3;
	ans %= MOD;
	int all = 1;
	for (int i = 2 ; i <= n ; i++){
		all *= i;
		all %= MOD;
	}
	if (all < ans){
		all += MOD;
	}
	all -= ans;
	cout << (all + MOD) % MOD;
}


// In His Name

#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define gcd __gcd
#define int long long
#define ull unsigned long long

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

const int MAX = 3e5 + 10, MOD = 998244353;
int n;
pii a[MAX];

main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 0 ; i < n ; i++){
		cin >> a[i].F >> a[i].S;
	}
	int all = 1, ans = 1;
	for (int i = 2 ; i <= n ; i++){
		all *= i, all %= MOD;
	}
	sort (a, a + n, [] (pii x, pii y){
		return x.S < y.S;
	});
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].S == a[i + 1].S){
			j++, i++;
			cnt *= j, cnt %= MOD;
		}
		ans *= cnt, ans %= MOD;
	}
	all = (all - ans) % MOD, ans = 1;
	sort (a, a + n, [] (pii x, pii y){
		return x.F < y.F;
	});
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F){
			j++, i++;
			cnt *= j, cnt %= MOD;
		}
		ans *= cnt, ans %= MOD;
	}
	all = (all - ans) % MOD, ans = 1;
	bool F = 0;
	for (int i = 0 ; i < n - 1 ; i++){
		if (a[i].S > a[i + 1].S){
			F = 1;
		}
	}
	if (F){
		return cout << (all + MOD) % MOD, 0;
	}
	for (int i = 0 ; i < n - 1 ; i++){
		int cnt = 1, j = 1;
		while (a[i].F == a[i + 1].F && a[i].S == a[i + 1].S){
			j++, i++;
			cnt *= j, cnt %= MOD;
		}
		ans *= cnt, ans %= MOD;
	}
	all += ans, all %= MOD;
	cout << (all + MOD) % MOD;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    if(a.s <= b.s) return true;
    else return false;
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    scanf("%lld",&n);
    pll a[n+1];bool mk = false;
    for(int i =1;i<=n;i++)scanf("%lld",&a[i].f),scanf("%lld",&a[i].s);
    if(a[1].f == 1 && a[1].s == 2) mk=true;
    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
         j--;

        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    if(mk)cout<<ans<<endl;
    cnt1 = (cnt1+cnt2)%MOD;
 //   if(n>10)
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    cnt1-=cnt12;
    if(cnt1 < 0) cnt1+=MOD;
    ans-=cnt1;
    if(ans<0)ans+=MOD;
   // if(n>10) cout<<cnt12<<endl;

    printf("%lld\n",ans);
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(ll n){
    fact[0] = 1;
    for(ll i = 1;i<=n;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
ll cool[N];
ll cool2[N];
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);

    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    scanf("%lld",&n);
    ini(n);
    pll a[n+1];bool mk = false;
    for(int i =1;i<=n;i++){scanf("%lld",&a[i].f),scanf("%lld",&a[i].s);cool[a[i].f]++;cool2[a[i].s]++;}

    ll cnt1 = 1;
   for(int i =1;i<=n;i++){
        if(cool[i] == 0) continue;
        cnt1 = (cnt1 * fact[cool[i]])%MOD;

   }

    ll cnt2 = 1;
    for(int i =1;i<=n;i++){
        if(cool2[i]==0)continue;
        cnt2 = (cnt2 * fact[cool2[i]])%MOD;
    }

    ll ans = fact[n];ans%=MOD;

    ans-=(cnt1);
    if(ans<0)ans+=MOD;
    ans-=cnt2;
    if(ans<0)ans+=MOD;

    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans = (ans + cnt12)%MOD;

    printf("%lld\n",ans);
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(j>n || (a[j].f != a[i].f)) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(j>n || (a[j].f != a[i].f)) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    ans-=cnt1;
    ans-=cnt2;
  // cout<<cnt1<<" "<<cnt2<<endl;
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;i++){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(j>n || (a[j].f != a[i].f || a[j].s != a[i].s)) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans+=cnt12;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    if(a.s <= b.s) return true;
    else return false;
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    scanf("%lld",&n);
    pll a[n+1];
    for(int i =1;i<=n;i++)scanf("%lld",&a[i].f),scanf("%lld",&a[i].s);

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
         j--;

        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    //if(n>10)cout<<ans<<endl;
    ans-=cnt1;
    if(ans<0)ans+=MOD;
    ans-=cnt2;
    if(ans<0)ans+=MOD;
 //   if(n>10)
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
   // if(n>10) cout<<cnt12<<endl;
    ans=(ans+cnt12)%MOD;
    printf("%lld\n",ans);
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
ll cool[N];
ll cool2[N];
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    scanf("%lld",&n);
    pll a[n+1];bool mk = false;
    for(int i =1;i<=n;i++){scanf("%lld",&a[i].f),scanf("%lld",&a[i].s);cool[a[i].f]++;cool2[a[i].s]++;}

    ll cnt1 = 1;
   for(int i =1;i<=n;i++){
        if(cool[i] == 0) continue;
        cnt1 = (cnt1 * fact[cool[i]])%MOD;

   }

    ll cnt2 = 1;
    for(int i =1;i<=n;i++){
        if(cool2[i]==0)continue;
        cnt2 = (cnt2 * fact[cool2[i]])%MOD;
    }
 //   cout<<cnt1<<" "<<cnt2<<endl;

    ll ans = fact[n];ans%=MOD;

    ans-=(cnt1);
    if(ans<0)ans+=MOD;
    ans-=cnt2;
    if(ans<0)ans+=MOD;

    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans = (ans + cnt12)%MOD;

    printf("%lld\n",ans);
}


#include <iostream>
#include<algorithm>
#define ll long long
#define f first
#define s second
#define pll pair<ll,ll>
#define int ll
using namespace std;

const ll N =(3e5+5);
const ll MOD = 998244353;

ll fact[N];
void ini(ll n){
    fact[0] = 1;
    for(ll i = 1;i<=n;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
ll cool[N];
ll cool2[N];
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);

    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    scanf("%lld",&n);
    ini(n);
    pll a[n+1];bool mk = false;
    for(int i =1;i<=n;i++){scanf("%lld",&a[i].f),scanf("%lld",&a[i].s);cool[a[i].f]++;cool2[a[i].s]++;}

    ll cnt1 = 1;
   for(int i =1;i<=n;i++){
        if(cool[i] == 0) continue;
        cnt1 = (cnt1 * fact[cool[i]])%MOD;

   }

    ll cnt2 = 1;
    for(int i =1;i<=n;i++){
        if(cool2[i]==0)continue;
        cnt2 = (cnt2 * fact[cool2[i]])%MOD;
    }

    ll ans = fact[n];ans%=MOD;

    ans-=(cnt1);
    if(ans<0)ans+=MOD;
    ans-=cnt2;
    if(ans<0)ans+=MOD;

    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans = (ans + cnt12)%MOD;

    printf("%lld\n",ans);
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(j > n)j--;
        if(a[j].s != a[i].s) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    cout<<ans<<endl;
    ans-=cnt1;
    ans-=cnt2;
    if(n>10)
  cout<<cnt1<<" "<<cnt2<<endl;
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f || a[j].s != a[i].s) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans+=cnt12;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(j > n)j--;
        if(a[j].s != a[i].s) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    ans-=cnt1;
    ans-=cnt2;
    if(n>10)
  cout<<cnt1<<" "<<cnt2<<endl;
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f || a[j].s != a[i].s) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans+=cnt12;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(a[j].f != a[i].f) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(a[j].s != a[i].s) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    ans-=cnt1;
    ans-=cnt2;
  // cout<<cnt1<<" "<<cnt2<<endl;
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;i++){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(a[j].f != a[i].f || a[j].s != a[i].s) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans+=cnt12;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    if(a.s <= b.s) return true;
    else return false;
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    scanf("%lld",&n);
    pll a[n+1];
    for(int i =1;i<=n;i++)scanf("%lld",&a[i].f),scanf("%lld",&a[i].s);

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
         j--;

        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    //if(n>10)cout<<ans<<endl;
    cnt1 = (cnt1+cnt2)%MOD;
 //   if(n>10)
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    cnt1-=cnt12;
    if(cnt1 < 0) cnt1+=MOD;
    ans-=cnt1;
    if(ans<0)ans+=MOD;
   // if(n>10) cout<<cnt12<<endl;

    printf("%lld\n",ans);
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(j > n)j--;
        if(a[j].s != a[i].s) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    ans-=cnt1;
    ans-=cnt2;
  // cout<<cnt1<<" "<<cnt2<<endl;
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;i++){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f || a[j].s != a[i].s) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans+=cnt12;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(j > n)j--;
        if(a[j].s != a[i].s) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    ans-=cnt1;
    ans-=cnt2;
  // cout<<cnt1<<" "<<cnt2<<endl;
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f || a[j].s != a[i].s) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans+=cnt12;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(j > n)j--;
        if(a[j].s != a[i].s) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    //if(n>10)cout<<ans<<endl;
    ans-=cnt1;
    if(ans<0)ans+=MOD;
    ans-=cnt2;
    if(ans<0)ans+=MOD;
 //   if(n>10)
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f || a[j].s != a[i].s) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
   // if(n>10) cout<<cnt12<<endl;
    ans=(ans+cnt12)%MOD;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(j > n)j--;
        if(a[j].s != a[i].s) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    if(n>10)cout<<ans<<endl;
    ans-=cnt1;
    if(ans<0)ans+=MOD;
    ans-=cnt2;
    if(ans<0)ans+=MOD;
    if(n>10)
  cout<<cnt1<<" "<<cnt2<<endl;
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f || a[j].s != a[i].s) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    if(n>10) cout<<cnt12<<endl;
    ans=(ans+cnt12)%MOD;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(ll n){
    fact[0] = 1;
    for(ll i = 1;i<=n;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
ll cool[N];
ll cool2[N];
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s < b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);

    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    scanf("%lld",&n);
    ini(n);
    pll a[n+1];bool mk = false;
    for(int i =1;i<=n;i++){scanf("%lld",&a[i].f),scanf("%lld",&a[i].s);cool[a[i].f]++;cool2[a[i].s]++;}

    ll cnt1 = 1;
   for(int i =1;i<=n;i++){
        if(cool[i] == 0) continue;
        cnt1 = (cnt1 * fact[cool[i]])%MOD;

   }

    ll cnt2 = 1;
    for(int i =1;i<=n;i++){
        if(cool2[i]==0)continue;
        cnt2 = (cnt2 * fact[cool2[i]])%MOD;
    }

    ll ans = fact[n];ans%=MOD;

    ans-=(cnt1);
    if(ans<0)ans+=MOD;
    ans-=cnt2;
    if(ans<0)ans+=MOD;

    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans = (ans + cnt12)%MOD;

    printf("%lld\n",ans);
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    return (a.s <= b.s);
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f) j--;
        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
        if(j > n)j--;
        if(a[j].s != a[i].s) j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    if(n>10)cout<<ans<<endl;
    ans-=cnt1;
    ans-=cnt2;
    if(n>10)
  cout<<cnt1<<" "<<cnt2<<endl;
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
        if(j > n) j--;
        if(a[j].f != a[i].f || a[j].s != a[i].s) j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
    ans+=cnt12;
    cout<<ans<<endl;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define endl "\n"
#define pll pair<ll,ll>
#define all(x) (x).begin() , (x).end()
#define in insert
#define int ll
using namespace std;
using namespace __gnu_pbds;

const ll N =(3e5+5);
const ll MOD = 998244353;
const ll INF = 1e16;
const ll LOG = 25;

long long binpow(long long a, long long b) {
    // a %= m;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a ;
        a = a * a ;
        b >>= 1;
    }
    return res;
}
ll fact[N];
void ini(){
    fact[0] = 1;
    for(ll i = 1;i<N;i++){
        fact[i] = (fact[i-1] * i)%MOD;
    }
}
bool cmp(pll a,pll b){
    if(a.s <= b.s) return true;
    else return false;
}
bool cmp2(pll a,pll b){
    if(a.f == b.f) {
        if(a.s <= b.s) return true;
        else return false;
    }
    if(a.f < b.f) return true;
    else return false;
}
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    ini();
    //n! - (cnt1 + cnt2 - cnt12)

    //n1 - cnt1 - cnt2 + cnt12

    ll n;
    cin >>n;
    pll a[n+1];
    for(int i =1;i<=n;i++)cin >> a[i].f >> a[i].s;

    sort(a+1,a+n+1);
    ll cnt1 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].f == a[i].f){
            j++;
        }
         j--;

        cnt1 = (cnt1 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }//cout<<endl;
    sort(a+1,a+n+1,cmp);
   // for(int i = 1;i<=n;i++) cout<<a[i].f<<" "<<a[i].s<<endl;
    ll cnt2 = 1;
    for(int i =1;i<=n;){
        int j = i;
        while(j<=n && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt2 = (cnt2 * fact[(j-i+1ll)])%MOD;
        i=j+1;
    }
    ll ans = fact[n];ans%=MOD;
    //if(n>10)cout<<ans<<endl;
    ans-=cnt1;
    if(ans<0)ans+=MOD;
    ans-=cnt2;
    if(ans<0)ans+=MOD;
 //   if(n>10)
   // cout<<ans<<endl;
    sort(a+1,a+n+1,cmp2);
    ll cnt12=1;
    bool poss=true;
    for(int i =1;i<n;i++)
    {
        if(a[i].f > a[i+1].f){
            poss=false;break;
        }
        if(a[i].s > a[i+1].s)
        {
            poss=false;
            break;
        }
    }
    if(!poss)cnt12=0;
    for(int i =1;i<=n&&poss;){
        int j = i;
        while(j<=n && a[j].f == a[i].f && a[j].s == a[i].s){
            j++;
        }
       j--;
        cnt12 = (cnt12 * fact[j-i+1ll])%MOD;
        i=j+1;
    }
   // if(n>10) cout<<cnt12<<endl;
    ans=(ans+cnt12)%MOD;
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define FOR(i, x, n) for(ll i = x; i < n; i++)
#define pb push_back
#define ll long long
#define hii cout << "hii" << endl
#define pii pair<int, int>
#define pll pair<ll, ll>
#define int ll
#define mpp make_pair
#define endl '\n'
#define ff first
#define ss second
#define all(s) s.begin(), s.end()
#define fuck_you_scanf ios_base:: sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define si size()

const int N = 1e6 + 5;
pii arr[N];
pii brr[N];
int fact[N];
const int mod = 998244353;

void precompute()
{
    fact[0] = 1;
    for(int i = 1; i < N; i++)
    {
        fact[i] = fact[i - 1] * i;
        fact[i] %= mod;
    }
}

int32_t main()
{
    precompute();
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        int a, b;
        cin >> a >> b;
        arr[i].ff = a;
        arr[i].ss = b;
        brr[i].ff = a;
        brr[i].ss = b;
    }
    sort(arr, arr + n, [&](pii & a, pii & b) -> bool{return a.ff < b.ff;});
    sort(brr, brr + n, [&](pii & a, pii & b) -> bool{return a.ss < b.ss;});
    int ret = fact[n];
    int a = 0, b = 0, c = 0;
    int cnt = 1;
    for(int i = 0; i < n;)
    {
        int j = i;
        while(i < n and arr[i].ff == arr[j].ff)
        {
            i++;
        }
        cnt = (cnt * fact[i - j]) % mod;
    }
    a = cnt;
    ret = (ret - cnt + mod) % mod;
    cnt = 1;
    for(int i = 0; i < n;)
    {
        int j = i;
        while(i < n and brr[i].ss == brr[j].ss)
        {
            i++;
        }
        cnt = (cnt * fact[i - j]) % mod;
    }
    b = cnt;
    if(n == 300000) cout << a << " " << b << endl;
    ret = (ret - cnt + mod) % mod;
    for(int i = 1; i < n; i++)
    {
        if(brr[i - 1].ff > brr[i].ff)
        {
            cout << ret << endl;
            return 0;
        }
    }
    cnt = 1;
    for(int i = 0; i < n;)
    {
        int j = i;
        while(i < n and brr[j].ff == brr[i].ff and brr[j].ss == brr[i].ss)
        {
            i++;
        }
        cnt *= fact[i - j];
        cnt %= mod;
    }
    ret += cnt;
    ret %= mod;
    cout << ret << endl;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#include <functional> // for less
#define pb push_back
#define For(i,s,e) for (ll i=(s); i<(e); i++)
#define Debug_array(a,n) for (ll i=(0); i<(n); i++) cout<<a[i]<<" "
#define Foe(i,s,e) for (ll i=(s); i<=(e); i++)
#define Fod(i,s,e) for (ll i=(s)-1; i>=(e); i--)
#define pii pair<ll,ll>
#define fi first
#define se second
#define endl "\n"
#define mp make_pair
#define big_prime 15486277
#define bigger_prime 179424697
#define biggest_prime 32416188691
//#define random_shuffle(indices.begin(), indices.end());
//std::random_device rd;
//std::mt19937 g(rd());
//std::shuffle(v.begin(), v.end(), g);
using namespace __gnu_pbds;
using namespace std;
template <class T> ostream& operator << (ostream &os, const vector<T> &v) { for (T i : v) os << i << ' '; return os; }
template <class T> ostream& operator << (ostream &os, const set<T> &v) { for (T i : v) os << i << ' '; return os; }
template <class T, class S> ostream& operator << (ostream &os, const pair<T, S> &v) { os << v.first << ' ' << v.second; return os; }
// template <class T, class S> ostream& operator << (ostream &os, const unordered_map<T, S> &v) { for (auto i : v) os << '(' << i.first << "=>" << i.second << ')' << ' '; return os; }

#ifndef ONLINE_JUDGE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <class Arg1> void __f(const char* name, Arg1&& arg1) { cerr << name << " : " << arg1 << endl; }
    template <class Arg1, class... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args) {
        const char* sep = strchr(names + 1, ',');
        cerr.write(names, sep - names) << " : " << arg1 << "  ";
        __f(sep + 1, args...);
    }
#else
#define trace(...) 0
#define _CRT_SECURE_NO_WARNINGS
#endif // ifndef ONLINE_JUDGE

typedef long long ll;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;

#define Mod 998244353
#define MAX 300100

ll fact[MAX];
ll n;
ll a[MAX],b[MAX];
pii c[MAX];

ll count_a(ll n){
	sort(a,a+n);
	ll ans = 1;
	ll i = 0;
	while(i<n){
		ll j = i;
		while(j<n && a[i]==a[j]) j++;
		j--;
		ans = (ans*fact[j-i+1])%Mod;
		i = j+1;
	}
	return ans;
}

ll count_b(ll n){
	sort(b,b+n);
	ll ans = 1;
	ll i = 0;
	while(i<n){
		ll j = i;
		while(j<n && b[i]==b[j]) j++;
		j--;
		ans = (ans*fact[j-i+1])%Mod;
		i = j+1;
	}
	return ans;
}

ll count_c(ll n){
	sort(c,c+n);

	bool ok = 1;
	For(i,1,n){
		if(c[i].fi<c[i-1].fi || c[i].se<c[i-1].se) ok=0;
	}
	if(!ok) return 0;

	ll ans = 1;
	ll i = 0;
	while(i<n){
		ll j = i;
		while(j<n && c[i].fi==c[j].fi && c[i].se==c[j].se) j++;
		j--;
		ans = (ans*fact[j-i+1])%Mod;
		i = j+1;
	}
	return ans;
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	fact[0]=1;
	For(i,1,MAX) fact[i]=(i*fact[i-1])%Mod;
	cin>>n;
	For(i,0,n){
		cin>>a[i]>>b[i];
		c[i] = {a[i],b[i]};
	}

	ll ans = (fact[n] - count_a(n)+Mod)%Mod;
	ans = (ans-count_b(n)+Mod)%Mod;
	ans = (ans+count_c(n)+Mod)%Mod;

	if(n == 300000)cout<<count_a(n)<<" "<<count_b(n)<<" "<<count_c(n)<<endl;

	cout<<ans<<endl;

}


#include <bits/stdc++.h>
using namespace std;
#define FOR(i, x, n) for(ll i = x; i < n; i++)
#define pb push_back
#define ll long long
#define hii cout << "hii" << endl
#define pii pair<int, int>
#define pll pair<ll, ll>
#define int ll
#define mpp make_pair
#define endl '\n'
#define ff first
#define ss second
#define all(s) s.begin(), s.end()
#define fuck_you_scanf ios_base:: sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define si size()

const int N = 1e6 + 5;
pii arr[N];
pii brr[N];
int fact[N];
const int mod = 998244353;

void precompute()
{
    fact[0] = 1;
    for(int i = 1; i < N; i++)
    {
        fact[i] = fact[i - 1] * i;
        fact[i] %= mod;
    }
}

int32_t main()
{
    precompute();
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        int a, b;
        cin >> a >> b;
        arr[i].ff = a;
        arr[i].ss = b;
        brr[i].ff = a;
        brr[i].ss = b;
    }
    sort(arr, arr + n, [](pii a, pii b) -> bool{return a.ff < b.ff;});
    sort(brr, brr + n, [](pii a, pii b) -> bool{return a.ss < b.ss;});
    int ret = fact[n];
    int cnt = 1;
    for(int i = 0; i < n;)
    {
        int j = i;
        while(i < n and arr[i].ff == arr[j].ff)
        {
            i++;
        }
        cnt *= fact[i - j];
        cnt %= mod;
    }
    // cerr << cnt << endl;
    ret -= cnt;
    ret += mod;
    ret %= mod;
    cnt = 1;
    for(int i = 0; i < n;)
    {
        int j = i;
        while(i < n and brr[i].ss == brr[j].ss)
        {
            i++;
        }
        cnt *= fact[i - j];
        cnt %= mod;
    }

    // cerr << cnt << endl;

    ret -= cnt;
    ret += mod;
    ret %= mod;
    for(int i = 1; i < n; i++)
    {
        if(brr[i - 1].ff > brr[i].ff or brr[i - 1].ss > brr[i].ss)
        {
            cout << ret << endl;
            return 0;
        }
    }
    cnt = 1;
    for(int i = 0; i < n;)
    {
        int j = i;
        while(i < n and brr[j].ff == brr[i].ff and brr[j].ss == brr[i].ss)
        {
            i++;
        }
        cnt *= fact[i - j];
        cnt %= mod;
    }
    // cerr << cnt << endl;
    ret += cnt;
    ret %= mod;
    cout << ret << endl;
}