#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<numeric>
#include<functional>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_set>
#include<unordered_map>
#include<random>
#include<array>
#include<cassert>
using namespace std;
#define INF (1<<29)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(v) v.begin(),v.end()
#define uniq(v) v.erase(unique(all(v)),v.end())


inline int popCount(unsigned int x) {
	x = x - ((x >> 1) & 0x55555555);
	x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
	x = (x + (x >> 4)) & 0x0F0F0F0F;
	x = x + (x >> 8);
	x = x + (x >> 16);
	return x & 0x0000003F;
}
inline int kthLowestPop(unsigned int pop1, int k) {
	unsigned int pop2, pop4, pop8, pop16;
	int pos = 0;
	pop2 = (pop1 >> 1 & 0x55555555) + (pop1 & 0x55555555);
	pop4 = (pop2 >> 2 & 0x33333333) + (pop2 & 0x33333333);
	pop8 = (pop4 >> 4 & 0x0f0f0f0f) + (pop4 & 0x0f0f0f0f);
	pop16 = (pop8 >> 8 & 0x00ff00ff) + (pop8 & 0x00ff00ff);
	if ((pop16 & 0x0000ffff) <= k) {
		k -= (pop16 & 0x0000ffff);
		pos |= 16;
	}
	if ((pop8 >> pos & 0x000000ff) <= k) {
		k -= (pop8 >> pos & 0x000000ff);
		pos |= 8;
	}
	if ((pop4 >> pos & 0x0000000f) <= k) {
		k -= (pop4 >> pos & 0x0000000f);
		pos |= 4;
	}
	if ((pop2 >> pos & 0x00000003) <= k) {
		k -= (pop2 >> pos & 0x00000003);
		pos |= 2;
	}
	if ((pop1 >> pos & 0x00000001) <= k)pos |= 1;
	return pos;
}


//メモリ使用量:2nビット
class BitVector {
	int n;
	int blocks;
	vector<unsigned int> B;
	vector<int> r;
public:
	BitVector() {}
	BitVector(int size) {
		init(size);
	}
	void init(int size) {
		n = size;
		blocks = (n >> 5) + 1;
		B.assign(blocks, 0);
		r.assign(blocks, 0);
	}
	void set(int k) {
		B[k >> 5] |= 1 << (k & 31);
	}
	void build() {
		r[0] = 0;
		for (int i = 1; i < blocks; i++) {
			r[i] = popCount(B[i - 1]) + r[i - 1];
		}
	}
	bool access(int k)const {
		return B[k >> 5] & 1 << (k & 31);
	}
	//[0,k)の1の個数
	int rank(int k)const {
		return r[k >> 5] + popCount(B[k >> 5] & ((1 << (k & 31)) - 1));
	}
	//k+1番目の１の場所
	//O(log n)
	int select1(int k)const {
		int lb = 0, ub = blocks;
		if (k == -1)return -1;
		while (ub - lb > 1) {
			int m = (lb + ub) / 2;
			if (k < r[m])ub = m;
			else lb = m;
		}
		k -= r[lb];
		return lb << 5 | kthLowestPop(B[lb], k);
	}
	//O(log n)
	int select0(int k)const {
		int lb = 0, ub = blocks;
		if (k == -1)return -1;
		while (ub - lb > 1) {
			int m = (lb + ub) / 2;
			if (k < (m << 5) - r[m])ub = m;
			else lb = m;
		}
		k -= (lb << 5) - r[lb];
		return lb << 5 | kthLowestPop(~B[lb], k);
	}
};


//ウェーブレット行列
class WaveletMatrix {
	typedef int Val;
	static const Val NIL = -1;
	static const int BITLEN = 31;
	int len;
	BitVector bv[BITLEN];
	int encode(Val c)const {
		return c;
	}
	Val decode(int n)const {
		return n;
	}
	struct Node {
		int height, s, e, code;
		Node() {}
		Node(int a, int b, int c, int d) :height(a), s(b), e(c), code(d) {};
		bool operator <(Node a)const { return e - s < a.e - a.s; }
	};
public:
	int length()const {
		return len;
	}
	WaveletMatrix() {
	}
	template<class T>
	WaveletMatrix(const T& v) {
		init(v);
	}
	//O(n logσ)
	template<class T>
	void init(const T& v) {
		len = v.size();
		for (int i = 0; i < BITLEN; i++) {
			bv[i].init(v.size());
		}
		int* bucket;
		bucket = new int[2 * len];
		int* cur, * next;
		cur = bucket;
		next = bucket + len;
		int rank0[BITLEN] = { 0 };
		for (int i = 0; i < len; i++) {
			int n = encode(v[i]);
			cur[i] = n;
			for (int j = BITLEN - 1; j >= 0; j--) {
				if ((n & 1 << j) == 0)rank0[j]++;
			}
		}
		for (int i = BITLEN - 1;; i--) {
			for (int j = 0; j < len; j++) {
				if (cur[j] & 1 << i)bv[i].set(j);
			}
			bv[i].build();
			if (i == 0)break;
			int idx0 = 0, idx1 = rank0[i];
			for (int j = 0; j < len; j++) {
				if (cur[j] & 1 << i)next[idx1++] = cur[j];
				else next[idx0++] = cur[j];
			}
			swap(cur, next);
		}
		delete[] bucket;
	}
	//O(logσ)
	Val access(int k)const {
		int code = 0;
		for (int i = BITLEN - 1; i > 0; i--) {
			if (bv[i].access(k)) {
				code |= 1 << i;
				k = len - bv[i].rank(len) + bv[i].rank(k);
			}
			else {
				k = k - bv[i].rank(k);
			}
		}
		if (bv[0].access(k))code |= 1;
		return decode(code);
	}
	//[s,e)中のcの個数
	//O(logσ)
	int rank(int s, int e, Val c)const {
		int n = encode(c);
		for (int i = BITLEN - 1; i >= 0; i--) {
			int ssum = bv[i].rank(s);
			int esum = bv[i].rank(e);
			if (n & 1 << i) {
				s = len - bv[i].rank(len) + ssum;
				e = s + esum - ssum;
			}
			else {
				s = s - ssum;
				e = e - esum;
			}
		}
		return e - s;
	}
	//[s,e)中のx未満の文字の個数
	int rank_lt(int s, int e, Val x)const {
		int n = encode(x);
		int res = 0;
		for (int i = BITLEN - 1; i >= 0; i--) {
			int ssum = bv[i].rank(s);
			int esum = bv[i].rank(e);
			if (n & 1 << i) {
				res += e - s - (esum - ssum);
				s = len - bv[i].rank(len) + ssum;
				e = s + esum - ssum;
			}
			else {
				s = s - ssum;
				e = e - esum;
			}
			if (s == e)return res;
		}
		return res;
	}
	//[s,e)中の x<=c<y となる文字の個数
	//O(logσ)
	int rangefreq(int s, int e, Val x, Val y)const {
		return rank_lt(s, e, y) - rank_lt(s, e, x);
	}
};


struct WMfor2DGird {
	WaveletMatrix grid;
	vector<int> firsts;
	WMfor2DGird(vector<pair<int, int> > vp) {
		sort(vp.begin(), vp.end());
		firsts.resize(vp.size());
		vector<int> seconds(vp.size());
		for (int i = 0; i < vp.size(); i++) {
			firsts[i] = vp[i].first;
			seconds[i] = vp[i].second;
		}
		grid.init(seconds);
	}
	int count(int s, int e, int u, int v)const {//[s,e)*[u,v)内の点の個数
		int a, b;
		a = lower_bound(firsts.begin(), firsts.end(), s) - firsts.begin();
		b = lower_bound(firsts.begin(), firsts.end(), e) - firsts.begin();
		return grid.rangefreq(a, b, u, v);
	}
	int count(int s, int e, int v)const {//[s,e)*[0,v)内の点の個数
		int a, b;
		a = lower_bound(firsts.begin(), firsts.end(), s) - firsts.begin();
		b = lower_bound(firsts.begin(), firsts.end(), e) - firsts.begin();
		return grid.rank_lt(a, b, v);
	}
};


const int mod = 998244353;
const int inf = (1 << 31) - 1;
long long p2[200001];



int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int n;
	vector<pair<int, int>> vp;
	cin >> n;
	vp.resize(n);
	rep(i,n) {
		int x, y;
		cin >> x >> y;
		vp[i].first = x + 1000000000;
		vp[i].second = y + 1000000000;
	}
	WMfor2DGird wm(vp);

	p2[0] = 1;
	rep(i, n)p2[i + 1] = p2[i] * 2 % mod;


	long long ans = 0;
	rep(i,n) {
		int x, y;
		tie(x, y) = vp[i];

		long long cnta, cntb, cntab = 1;

		{
			int c1 = wm.count(0, x, 0, y);
			int c2 = wm.count(x + 1, inf, y + 1, inf);
			long long p = (p2[c1] - 1) * (p2[c2] - 1) % mod;

			cnta = p * (p2[n - 1 - c1 - c2]) % mod;
			cntab = cntab * p %mod;
		}

		{
			int c1 = wm.count(x + 1, inf, 0, y);
			int c2 = wm.count(0, x, y + 1, inf);
			long long p = (p2[c1] - 1) * (p2[c2] - 1) % mod;

			cntb = p * (p2[n - 1 - c1 - c2]) % mod;
			cntab = cntab * p % mod;
		}

		ans += cnta;
		ans += cntb;
		ans -= cntab;
		ans += p2[n - 1];
		ans %= mod;
	}


	ans += mod;
	ans %= mod;
	cout << ans << endl;



	return 0;
}

Measured memory_bytes: 8064