#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
typedef long double ld;
const int inf=1e9+7;
const ll longinf=1LL<<60;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
#define F first
#define S second
constexpr char ln = '\n';

const int mx=100010;
//const ll mod=1e9+7;
const ll mod=998244353;

struct mint {
    ll x; // typedef long long ll;
    mint(ll x=0):x((x%mod+mod)%mod){}
    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 { mint res(*this); return res+=a; }
    mint operator-(const mint a) const { mint res(*this); return res-=a; }
    mint operator*(const mint a) const { mint res(*this); return res*=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 { mint res(*this); return res/=a; }
};

ll modpow(ll x,ll n){
  x%=mod; ll res=1;
  while(n>0){ if(n&1){res=res*x%mod;} x=x*x%mod; n>>=1; }
  return res;
}

template<typename T>
struct BinaryIndexedTree {
  int N;
  vector<T> data;
 
  BinaryIndexedTree(int sz) : N(sz), data(sz+1,0) {}
 
  T sum(int k) { // [0,k) (0-indexed) a[0] + … + a[k-1]
    T ret = 0;
    for(; k > 0; k -= k & -k) ret += data[k];
    return (ret);
  }
 
  T sum(int l, int r) { // [l,r) (0-indexed) a[l] + …　+ a[r-1]
    T vl = sum(l);
    T vr = sum(r);
    return vr - vl;
  }
 
  void add(int k, T x) { // (0-indexed) a[k] += x;
    for(++k; k <= N; k += k & -k) data[k] += x;
  }
 
  int lowerbound(T x) { // (0-indexed)
    int k = 1;
    int ret = 0;
    while ((k<<1) <= N) k <<= 1;
    while (k > 0) {
      if (ret + k <= N && data[ret+k] < x) {
        x -= data[ret+k];
        ret += k;
      }
      k >>= 1;
    }
    return ret;
  }
 
  int upperbound(T x) { // (0-indexed)
    ++x;
    int k = 1;
    int ret = 0;
    while ((k<<1) <= N) k <<= 1;
    while (k > 0) {
      if (ret + k <= N && data[ret+k] < x) {
        x -= data[ret+k];
        ret += k;
      }
      k >>= 1;
    }
    return ret;
  }
};

template<typename T>
vector<T> compress(vector<T> A){
    sort(A.begin(), A.end());
    A.erase(unique(A.begin(), A.end()), A.end());
    return A;
}
/*
  vector<int> as, comp(n);
  as = compress(a);
  int sz=as.size();
  rep(i,n){ comp[i] = lower_bound(as.begin(), as.end(), a[i]) - as.begin(); }
*/  

int main(){
  int n;
  cin >> n;
  vector<pair<ll,ll>> xs(n),ys(n);
  vector<int> x(n);
  map<int,int> mp;
  rep(i,n){
    cin >> xs[i].F >> ys[i].F;
    ys[i].S =  i;
    xs[i].S =  i;
  }
  sort(xs.begin(),xs.end());
  sort(ys.begin(),ys.end());
  rep(i,n){ 
    x[i]=xs[i].F; 
    mp[xs[i].S] = i;
  }
  vector<int> as, comp(n);
  as = compress(x);
  int sz=as.size();
  rep(i,n){ comp[i] = lower_bound(as.begin(), as.end(), x[i]) - as.begin(); }
  
  vector<vector<ll>> pn(n, vector<ll>(4,0));
  BinaryIndexedTree<ll> bt(n);
  rep(i,n){
    pn[mp[ys[i].S]][2] = bt.sum(0,comp[mp[ys[i].S]]);
    pn[mp[ys[i].S]][3] = bt.sum(comp[mp[ys[i].S]],n);
    bt.add(comp[mp[ys[i].S]],1);
  }
  BinaryIndexedTree<ll> bt2(n);
  for(int i=n-1; i>=0; i--){
    pn[mp[ys[i].S]][1] = bt2.sum(0,comp[mp[ys[i].S]]);
    pn[mp[ys[i].S]][0] = bt2.sum(comp[mp[ys[i].S]],n);
    bt2.add(comp[mp[ys[i].S]],1);
  }
  mint ans = modpow(2,n)-1;
  ans *= n;
  rep(i,n){
    ans -= (modpow(2,i)-1)*2;
    ans -= (modpow(2,n-1-i)-1)*2;
    rep(j,4){
      ans += modpow(2,pn[i][j])-1;
    }
  }
  cout << ans.x << ln;
  return 0;
}

Measured memory_bytes: 38380