#include<iostream>
#define _USE_MATH_DEFINES
#include<math.h>
#include<vector>
#include<array>
#include<algorithm>
#include<numeric>
#include<map>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<ll> vec;
typedef vector<vector<ll>> mat;
typedef pair<ll,ll> P;
typedef map<ll,ll> MP;
typedef priority_queue<ll> PQ;
typedef stack<ll> ST;
typedef queue<ll> QUE;
#define pb push_back
#define st first
#define nd second
#define SZ(x) ((int)(x).size())
#define FOR(i,s,n) for(int i=(int)(s); i< (int)(n); i++)
#define rep(i,n) FOR(i,0,n)
#define all(x) (x).begin(),(x).end()
#define each(x,c) for(auto x: (c))
#define LB(x,a) lower_bound(all(x), a)
#define UB(x,a) upper_bound(all(x), a)
const ll mod=998244353;
const ll INF=1e18;
const double EPS=1.0e-10;
const double PI=M_PI;

//累乗(aのk乗)
ll matpow(ll a,int k){
    ll dp=1,mt=a;
    while(k>0){
        if(k & 1)dp=(dp*mt)%mod;
        mt=(mt*mt)%mod;
        k/=2;
    }
    return dp;
}

struct LazySegmentTree{
    int n;
    vec node,lazy;
    
    LazySegmentTree(vec v){
        int s=v.size();
        n=1;
        while(n<s)n*=2;
        node.resize(2*n-1);
        lazy.resize(2*n-1,0);

        for(int i=0;i<s;i++)node[i+n-1]=v[i];
        for(int i=n-2;i>=0;i--)node[i]=node[2*i+1]+node[2*i+2];
    }

    //k番目のノードについて遅延評価
    void eval(int k,int l,int r){
        if(lazy[k]!=0){
            node[k]+=lazy[k];

            if(r-l>1){
                lazy[2*k+1]+=lazy[k]/2;
                lazy[2*k+2]+=lazy[k]/2;
            }
            lazy[k]=0;
        }
    }

    //[a,b)にxを加算、kは区間[l,r)の節点
    void add(int a,int b,ll x,int k,int l,int r){
        eval(k,l,r);

        if(b<=l || r<=a)return;

        if(a<=l && r<=b){
            lazy[k]+=x*(ll)(r-l);
            eval(k,l,r);
        }

        else{
            add(a,b,x,2*k+1,l,(l+r)/2);
            add(a,b,x,2*k+2,(l+r)/2,r);
            node[k]=node[2*k+1]+node[2*k+2];
        }
    }

    //[a,b)の区間和を取得
    ll getsum(int a,int b,int k,int l,int r){
        if(b<=l || r<=a) return 0;

        eval(k,l,r);
        if(a<=l && r<=b) return node[k];
        ll vl=getsum(a,b,2*k+1,l,(l+r)/2);
        ll vr=getsum(a,b,2*k+2,(l+r)/2,r);
        return vl+vr;
    }   
};

int main(){
    int N; cin>>N;
    vector<P> X(N),Y(N);
    vec v(N,1),u(N,0);
    LazySegmentTree right(v),left(u);
    rep(i,N){
        cin>>X[i].st>>X[i].nd;
    }
    sort(all(X));
    rep(i,N){
        Y[i]={X[i].nd,i};
    }
    sort(all(Y));
    vec ind(N);
    rep(j,N){
        ind[Y[j].nd]=j;
    }
    ll ans=(N*matpow(2,N-1))%mod;
    vec num(4); vector<bool> area(4,false);
    rep(i,N){
        int j=ind[i];
        right.add(j,j+1,-1,0,0,right.n);
        num[2]=left.getsum(0,j,0,0,left.n);
        num[1]=i-num[2];
        num[3]=right.getsum(0,j,0,0,right.n);
        num[0]=N-1-i-num[3];
        rep(bit,(1<<4)){
            ll res=1;
            rep(i,4){
                if(bit & (1<<i)){
                    area[i]=true;
                    res=(res*(matpow(2,num[i])-1))%mod;
                }
            }
            if((area[0] && area[2]) || (area[1] && area[3])){
                ans=(ans+res)%mod;
            }
            fill(all(area),false);
        }
        left.add(j,j+1,1,0,0,left.n);
    }
    printf("%lld\n",ans);
    return 0;
}

Measured memory_bytes: 27624