// ABC136Fwin.cpp
//#include "pch.h"
//
//  main.cpp
//  ABC136F
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

// auto mod int 自動の％
//const int mod = 1000000007;
const int mod = 998244353;
struct mint {
	ll x; // typedef long long ll;
	mint(ll x = 0) :x((x%mod + mod) % mod) {}
	mint operator-() const { return mint(-x); }
	mint& operator+=(const mint a) {
		if ((x += a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator-=(const mint a) {
		if ((x += mod - a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this; }
	mint operator+(const mint a) const { return mint(*this) += a; }
	mint operator-(const mint a) const { return mint(*this) -= a; }
	mint operator*(const mint a) const { return mint(*this) *= a; }
	mint pow(ll t) const {
		if (!t) return 1;
		mint a = pow(t >> 1);
		a *= a;
		if (t & 1) a *= *this;
		return a;
	}

	// for prime mod
	mint inv() const { return pow(mod - 2); }
	mint& operator/=(const mint a) { return *this *= a.inv(); }
	mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream& operator>>(istream& is, mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }

// Binary Indexed Tree (Fenwick Tree)
//    使い方 : BIT<int>bit
template<typename T> // T: type of cost
struct BIT {
	int n;
	vector<T> array; // ワーク用配列。BITの各要素を記録する
	BIT(int n = 0) :n(n), array(n + 1) {}
	void add(int i, T x = 1) {
		for (i++; i <= n; i += i & -i) {
			array[i] += x;
		}
	}
	T sum(int i) {
		T x = 0;
		for (i++; i; i -= i & -i) {
			x += array[i];
		}
		return x;
	}
};
mint f(int a, int b, int c, int d) {
	mint res = 0;
	vector<int> num = { a,b,c,d };
	vector<mint>o(4), ox(4);
	rep(i, 4) {
		ox.at(i) = mint(2).pow(num.at(i));
		o.at(i) = ox.at(i) - 1;
	}
	res += ox.at(0)*o.at(1)*o.at(2)*ox.at(3);
	res += o.at(0)*ox.at(1)*ox.at(2)*o.at(3);
	res -= o.at(0)*o.at(1)*o.at(2)*o.at(3);
	res += ox.at(0)*ox.at(1)*ox.at(2)*ox.at(3);
	return res;
}
mint f2(int ax, int bx, int cx, int dx) {
	mint a = mint(2).pow(ax)-1;
	mint b = mint(2).pow(bx) - 1;
	mint c = mint(2).pow(cx) - 1;
	mint d = mint(2).pow(dx) - 1;
	mint res = 0;
	res = a + b + c + d;
	res += a * b + a * c + a * d + b * c + b * d + c * d;
	res += a * b*c*2 + a * b*d*2 + b * c*d*2 + a * c*d*2;
	res += a * d + b * c;
	res += a * b*c*d * 2;
	res += 1;
	return res;
}
int main(int argc, const char * argv[]) {
	int n;
	cin >> n;
	vector<P>p(n);
	rep(i, n) cin >> p.at(i).first >> p.at(i).second;
	{ // compress x
		map<int, int>mp;
		rep(i, n) mp[p.at(i).first] = 0;
		int j = 0;
		for (auto&& x : mp) x.second = j++;
		rep(i, n) p.at(i).first = mp[p.at(i).first];
	}
	{ // compress y
		map<int, int>mp;
		rep(i, n) mp[p.at(i).second] = 0;
		int j = 0;
		for (auto&& x : mp) x.second = j++;
		rep(i, n) p.at(i).second = mp[p.at(i).second];
	}
	sort(p.begin(), p.end());
	vector<int>a(n);
	vector<int>b(n);
	vector<int>c(n);
	vector<int>d(n);

	BIT<int> bit1(n); // 領域a、領域bについて
	rep(i, n) {
		// ワーク用配列arrayにおいて累積和
		// (これまで調べた中で、yの値が小さいものの個数)を求める
		a.at(i) = bit1.sum(p.at(i).second);
		// これまで調べた中で、yの値が大きいものの個数　i-a.at(i)
		b.at(i) = i - a.at(i);
		// ワーク用配列arrayにおいて、ノードp.at(i)に１を加算する
		bit1.add(p.at(i).second, 1);
	}

	BIT<int> bit2(n); // 領域c、領域dについて
	for(int i=n-1;i>=0;i--) {
		// ワーク用配列arrayにおいて累積和
		// (これまで調べた中で、yの値が小さいものの個数)を求める
		c.at(i) = bit2.sum(p.at(i).second);
		// これまで調べた中で、yの値が大きいものの個数　n-1-i-c.at(i)
		d.at(i) = (n-1-i) - c.at(i);
		// ワーク用配列arrayにおいて、ノードp.at(i)に１を加算する
		bit2.add(p.at(i).second, 1);
	}

	//rep(i, n) {
	//	cout << "注目点=" << i << " " << a[i] << " " << b[i] << " " << c[i] << " " << d[i] << endl;
	//}cout << endl;
	mint ans = 0;
	mint all = 0;
	rep(i, n) {
		ans = f2(a.at(i), b.at(i), c.at(i), d.at(i));
		//cout << "注目点=" << i << " " << ans << endl;
		all += ans;
	}
	cout << all << endl;
	return 0;
}
/*
5
1 4
2 1
3 3
4 2
5 5
*/


Measured memory_bytes: 13828