#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

#include <cstdint>

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

using mint = modint<998244353>;


// v[1]がルート
struct SegmentTree {
	vector<int> v;
	int n;
	SegmentTree( int n_ ){
		for ( n = 1; n < n_; n *= 2 )
			;
		v.resize( n*2 );
	}
	
	
	void update( int i, int x ){
		i += n;
		v[i] = x;
		i /= 2;
		
		while ( i ){
			v[i] = v[i*2] + v[i*2+1];
			i /= 2;
		}
	}
	
	//  begin .. end-1 の区間の合計
	int range_sum( int begin, int end ){
		return range_sum2( begin, end, 1, 0, n );
	}
	
	// v[node] は b .. b..len-1 の合計を持っている
	int range_sum2( int begin, int end, int node, int b, int len ){
		if ( end <= b || b + len <= begin )
			return 0;
		if ( begin <= b && b + len <= end )
			return v[node];
		
		return range_sum2( begin, end, node*2,   b,       len/2 )
		     + range_sum2( begin, end, node*2+1, b+len/2, len/2 );
	}
};

ll N;

struct xy {
	int x;
	int y;
};

// 解説を参考に
int main(){
	cin >> N;
	
	vector<xy> p(N);
	for ( int i = 0; i < N; i++ ){
		cin >> p[i].x >> p[i].y;
	}
	
	sort(p.begin(),p.end(),[](const xy &l, const xy &r){ return l.y < r.y; });
	for ( int i = 0; i < N; i++ )
		p[i].y = i;
	
	sort(p.begin(),p.end(),[](const xy &l, const xy &r){ return l.x < r.x; });
	for ( int i = 0; i < N; i++ )
		p[i].x = i;
	
	// 各piについて、LU LD RU RD の4方向に何個の点があるかどうか調べる
	vector<int> LU(N);
	vector<int> LD(N);
	vector<int> RU(N);
	vector<int> RD(N);
	
	SegmentTree sl(N);
	for ( int i = 0; i < N; i++ ){
		LD[i] = sl.range_sum(0, p[i].y);
		LU[i] = i - LD[i];
		sl.update(p[i].y, 1);
	}
	
	SegmentTree sr(N);
	for ( int i = N-1; i >= 0; i-- ){
		RD[i] = sr.range_sum(0, p[i].y);
		RU[i] = (N-1-i) - RD[i];
		sr.update(p[i].y,1);
	}
	
	vector<mint> pow2(N+1);
	vector<mint> pow2m(N+1);
	mint t = 1;
	for ( int i = 0; i<= N; i++ ){
		pow2[i] = t;
		pow2m[i] = t - 1;
		t = t * 2;
	}
	
	mint result = 0;
	for ( int i = 0; i < N; i++ ){
		mint t = 
			pow2[ N ] 
			- pow2m[LU[i]] * pow2m[LD[i]]
			- pow2m[LU[i]] * pow2m[RU[i]]
			- pow2m[RD[i]] * pow2m[LD[i]]
			- pow2m[RD[i]] * pow2m[RU[i]]
			- pow2m[LU[i]]
			- pow2m[LD[i]]
			- pow2m[RU[i]]
			- pow2m[RD[i]]
			- 1;
		//cout << i << ":" << t.value() << endl;
		result += t;
	}
	
	cout << result.value() << endl;
	
	return 0;
}



Measured memory_bytes: 12160