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

int MOD(int a){
	return (a %= p) >= 0 ? a : a + p;
}

template<typename M>
struct segment_tree{
	typedef function<M(M, M)> F;
	int size;//2冪
	vector<M> val;//1-indexed
	F f;//結合関数
	M e;//単位元

	segment_tree(int N, vector<M> &data, F f, M e) : f(f), e(e){
		size = 1;
		while(size < N) size *= 2;
		val.assign(2 * size, e);
		for(int i = 0; i < N; i++) val[size + i] = data[i];
		for(int i = N; i < size; i++) val[size + i] = e;
		for(int i = size - 1; i > 0; i--) val[i] = f(val[2 * i], val[2 * i + 1]);
	}

	//k番目の要素をxに変更する
	void update(int k, M x){
		k += size;
		val[k] = x;
		while(k /= 2) val[k] = f(val[2 * k], val[2 * k + 1]);
	}

	//[l, r)の演算の結果を返す
	M query(int l, int r){
		M L = e, R = e;
		for(l += size, r += size; l < r; l /= 2, r /= 2){
			if(l & 1) L = f(L, val[l++]);
			if(r & 1) R = f(val[--r], R);
		}
		return f(L, R);
	}
};


//(int, sum, 0)
int sum(int x, int y){
	return x + y;
}

signed main(){
	int N, i;
	scanf("%lld", &N);
	vector<pair<pair<int, int>, int>> xyi(N);
	for(i = 0; i < N; i++){
		scanf("%lld%lld", &xyi[i].first.first, &xyi[i].first.second);
		xyi[i].second = i;
	}
	vector<int> pow2(N + 1, 1);
	for(i = 1; i <= N; i++){
		pow2[i] = MOD(2 * pow2[i - 1]);
//		printf("pow2[%lld] = %lld\n", i, pow2[i]);
	}
	vector<int> ans(N, pow2[N]);
	auto compx = [](pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){
		return a.first.first < b.first.first;
	};
	sort(xyi.begin(), xyi.end(), compx);
	for(i = 0; i < N; i++){
		xyi[i].first.first = i;
	}
	auto compy = [](pair<pair<int, int>, int> a, pair<pair<int, int>, int> b){
		return a.first.second < b.first.second;
	};
	sort(xyi.begin(), xyi.end(), compy);
	for(i = 0; i < N; i++){
		xyi[i].first.second = i;
	}
	sort(xyi.begin(), xyi.end(), compx);
	for(i = 0; i < N; i++){
		int x = xyi[i].first.first, y = xyi[i].first.second, j = xyi[i].second;
//		printf("(i, x, y, j) = (%lld, %lld, %lld, %lld)\n", i, x, y, j);
//		printf("ans[%lld] = %lld\n", j, ans[j]);
		ans[j] = MOD(ans[j] - pow2[i] - pow2[N - i - 1]);
//		printf("ans[%lld] = %lld\n", j, ans[j]);
	}
/*	for(i = 0; i < N; i++){
		printf("ans[%lld] = %lld\n", i, ans[i]);
	}
	printf("\n");
*/	sort(xyi.begin(), xyi.end(), compy);
	for(i = 0; i < N; i++){
		int x = xyi[i].first.first, y = xyi[i].first.second, j = xyi[i].second;
		ans[j] = MOD(ans[j] - pow2[i] - pow2[N - i - 1]);
	}
/*	for(i = 0; i < N; i++){
		printf("ans[%lld] = %lld\n", i, ans[i]);
	}
	printf("\n");
*/	sort(xyi.begin(), xyi.end(), compx);
	vector<int> data(N, 0);
	segment_tree<int> t1(N, data, sum, 0);
	segment_tree<int> t2(N, data, sum, 0);
	for(i = 0; i < N; i++){
		int x = xyi[i].first.first, y = xyi[i].first.second, j = xyi[i].second;
//		printf("t1.query(0, %lld) = %lld\n", y, t1.query(0, y));
//		printf("t1.query(%lld, N) = %lld\n", y + 1, t1.query(y + 1, N));
		ans[j] = MOD(ans[j] + pow2[t1.query(0, y)] + pow2[t1.query(y + 1, N)]);
		t1.update(y, 1);
	}
/*	for(i = 0; i < N; i++){
		printf("ans[%lld] = %lld\n", i, ans[i]);
	}
	printf("\n");
*/	for(i = N - 1; i >= 0; i--){
		int x = xyi[i].first.first, y = xyi[i].first.second, j = xyi[i].second;
		ans[j] = MOD(ans[j] + pow2[t2.query(0, y)] + pow2[t2.query(y + 1, N)]);
		t2.update(y, 1);
	}
	int s = 0;
	for(i = 0; i < N; i++){
//		printf("ans[%lld] = %lld\n", i, ans[i]);
		s = MOD(s + ans[i]);
	}
	printf("%lld\n", MOD(s - N));
	return 0;
}

Measured memory_bytes: 17792