#include<bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define INF 1000000000
#define mod 998244353
using ll=long long;
const ll LINF=1001002003004005006ll;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}

#define db(v) cout<<#v<<" : "<<v<<endl;

template<typename Monoid>
struct SegmentTree{
    using F=function<Monoid(Monoid,Monoid)>;
    int sz;
    vector<Monoid> seg;
    const F f;
    const Monoid gen;
    SegmentTree(int n,const F f,const Monoid &gen):f(f),gen(gen){
        sz=1;
        while(sz<n)sz<<=1;
        seg.assign(2*sz,gen);
    }
    void set(int k,const Monoid &x){
        seg[k+sz]=x;
    }
    void build(){
        for(int k=sz-1;k>0;k--) seg[k]=f(seg[2*k],seg[2*k+1]);
    }
    void update(int k,const Monoid &x){
        k+=sz;
        seg[k]=x;
        while(k>>=1) seg[k]=f(seg[2*k],seg[2*k+1]);
    }
   // [a,b)
    Monoid query(int a,int b){
        Monoid L=gen,R=gen;
        for(a+=sz,b+=sz;a<b;a>>=1,b>>=1){
            if(a&1) L=f(L,seg[a++]);
            if(b&1) R=f(seg[--b],R);
        }
        return f(L,R);
    }
    Monoid operator[](const int &k)const {
       return seg[k+sz];
    }
};

ll fact_mod(ll n) {
    ll ret=1; 
    for(ll i=2;i<=n;i++) ret=ret*(i%mod)%mod;
    return ret;
} 
ll pow_mod(ll x, ll n){
    if(n==0) return 1;
    ll ret=pow_mod((x*x) % mod, n/2);
    if(n&1) ret=(ret*x)%mod;
    return ret;
}
//O(r)
ll combination_mod(ll n, ll r) {
    if(r>n-r) r=n-r;
    if(r==0) return 1;
    ll a=1;
    for(ll i=0;i<r;i++) a=a*((n-i)%mod)%mod;
    ll b=pow_mod(fact_mod(r), mod-2);
    return (a%mod)*(b%mod)%mod;
}
ll inv_mod(ll n){
    return pow_mod(n,mod-2);
}

struct point{
    ll x,y;int id;
    point(ll x,ll y,int id):x(x),y(y){}
    point(){}
};

ll f(ll a){
    return pow_mod(2,a)-1;
}

// xで座圧してy下から処理
signed main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    int n;cin>>n;
    vector<point> v;
    rep(i,n){
        ll x,y;cin>>x>>y;
        v.push_back(point(x,y,i));
    }

    sort(ALL(v),[](point a,point b){return a.x<b.x;});
    // x座圧
    map<ll,int> id;
    int tmp=0;
    rep(i,n) id[v[i].x]=tmp++;

    SegmentTree<ll> useg(n,[](ll a,ll b){return a+b;},0),dseg(n,[](ll a,ll b){return a+b;},0);
    rep(i,n) useg.set(i,1);
    useg.build();dseg.build();

    sort(ALL(v),[](point a,point b){return a.y<b.y;});

    ll ans=n*f(n)%mod;
    for(auto &p:v){
        ll upleft=useg.query(0,id[p.x]);
        ll downleft=dseg.query(0,id[p.x]);
        ll upright=useg.query(id[p.x]+1,n);
        ll downright=dseg.query(id[p.x]+1,n);

        ll mi=f(upleft+downleft)+f(upright+downright)+f(upleft+upright)+f(downleft+downright);
        mi%=mod;
        mi+=mod-f(upleft)+mod-f(upright)+mod-f(downleft)+mod-f(downright);
        mi%=mod;
        ans+=mod-mi;
        ans%=mod;

        useg.update(id[p.x],0);
        dseg.update(id[p.x],1);
    }
    cout<<ans<<endl;
    return 0;
}


Measured memory_bytes: 26860