#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define int long long
#define double long double
#define all(a) a.begin(), a.end()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;

const int mod = 998244353;
struct mint{ //modint
    int x;
    mint(int x = 0): x(x % mod) {}
    friend istream& operator >> (istream &s, mint& m){ return s >> m.x; }
    friend ostream& operator << (ostream &s, mint m){ return s << m.x; }
    inline mint& operator += (mint a){ if((x += a.x) >= mod)x -= mod; return *this; }
    inline mint& operator -= (mint a){ if((x += mod - a.x) >= mod)x -= mod; return *this; }
    inline mint& operator *= (mint a){ (x *= a.x) %= mod; return *this; }
    inline mint& operator /= (mint a){ return(*this) *= a.inv(); }
    inline mint operator + (mint a){ mint res(*this); return res += a; }
    inline mint operator - (mint a){ mint res(*this); return res -= a; }
    inline mint operator * (mint a){ mint res(*this); return res *= a; }
    inline mint operator / (mint a){ mint res(*this); return res /= a; }
    inline bool operator == (mint a){ return x == a.x; }
    inline bool operator != (mint a){ return x != a.x; }
    inline bool operator < (mint a){ return x < a.x; }
    inline bool operator > (mint a){ return x > a.x; }
    inline bool operator <= (mint a){ return x <= a.x; }
    inline bool operator >= (mint a){ return x >= a.x;}
    mint inv(){ return pow(mod - 2); }
    mint pow(int p){
        mint res(1), tmp(x);
        for(; p; p >>= 1){ if(p & 1)res *= tmp; tmp *= tmp; }
        return res;
    }
};

template<typename Monoid>
struct SegmentTree{    //セグメント木
private:
    int sz = 1; vector<Monoid> node;
    using Func = function<Monoid(Monoid, Monoid)>;
    const Func pick; const Monoid init;    //モノイドに対する操作と、その単位元
public:
    SegmentTree(vector<Monoid> vec, const Func f, const Monoid m): pick(f), init(m) {
        while((sz <<= 1) < (int)vec.size());
        node = vector<Monoid>(sz * 2 - 1, init);
        for(int i = 0; i < (int)vec.size(); i++){
            node[i + sz - 1] = vec[i]; 
        }
        for(int i = sz - 2; i >= 0; i--){
            node[i] = pick(node[i * 2 + 1], node[i * 2 + 2]);
        }
    }
    void update(int i, Monoid v){       //単一の要素を変更する
        for(node[(i += sz) - 1] = v; i >>= 1;){
            node[i - 1] = pick(node[i * 2 - 1], node[i * 2]);
        }
    }
    void add(int i, Monoid v){          //単一の要素にある値を加える
        update(i, this[i] + v);
    }
    Monoid get(int l, int r){           //区間取得
        Monoid res = init;
        for((l += sz), (r += sz); l < r; (l >>= 1), (r >>= 1)){
            if(l & 1)res = pick(res, node[(l++) - 1]);
            if(r & 1)res = pick(res, node[(--r) - 1]);
        }
        return res;
    }
    inline Monoid operator [] (int i){ //[]でアクセス
        return node[i + sz - 1];
    }
};

//ABC136
signed main(void){

    int n; cin >> n;
    vector<int> x(n), y(n);
    rep(i, n)cin >> x[i] >> y[i];
    
    vector<int> vec(n);
    iota(all(vec), 0);

    sort(all(vec), [&](int i, int j){
        return x[i] < x[j];
    });
    rep(i, n)x[vec[i]] = i;

    sort(all(vec), [&](int i, int j){
        return y[i] < y[j];
    });
    rep(i, n)y[vec[i]] = i;


    SegmentTree<int> seg1(vector<int>(n + 1, 0), [](int a, int b){ return a + b; }, 0);

    sort(all(vec), [&](int i, int j){
        return x[i] < x[j];
    });

    vector<int> cnt1(n), cnt2(n);
    rep(i, n){
        int j = vec[i];
        cnt1[j] = i - seg1.get(0, y[j]);
        cnt2[j] = i - cnt1[j];
        seg1.update(y[j], 1);
    }

    SegmentTree<int> seg2(vector<int>(n + 1, 0), [](int a, int b){ return a + b; }, 0);

    sort(all(vec), [&](int i, int j){
        return y[i] < y[j];
    });

    vector<int> cnt3(n), cnt4(n);
    rep(i, n){
        int j = vec[i];
        cnt3[j] = i - seg2.get(0, x[j]);
        cnt4[j] = (n - 1) - cnt1[j] - cnt2[j] - cnt3[j];
        seg2.update(x[j], 1);
    }

    mint ans(0), two(2);
    rep(i, n){
        mint tmp = two.pow(n);
        if(cnt1[i] + cnt2[i] > 0)tmp -= two.pow(cnt1[i] + cnt2[i]) - 1;
        if(cnt2[i] + cnt3[i] > 0)tmp -= two.pow(cnt2[i] + cnt3[i]) - 1;
        if(cnt3[i] + cnt4[i] > 0)tmp -= two.pow(cnt3[i] + cnt4[i]) - 1;
        if(cnt4[i] + cnt1[i] > 0)tmp -= two.pow(cnt4[i] + cnt1[i]) - 1;
        if(cnt1[i] > 0)tmp += two.pow(cnt1[i]) - 1;
        if(cnt2[i] > 0)tmp += two.pow(cnt2[i]) - 1;
        if(cnt3[i] > 0)tmp += two.pow(cnt3[i]) - 1;
        if(cnt4[i] > 0)tmp += two.pow(cnt4[i]) - 1;
        tmp -= 1;
        ans += tmp;
    }
    cout << ans << endl;

}

Measured memory_bytes: 19812