#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <stack>
#include <tuple>
#include <deque>
#include <numeric>
#include <bitset>
#include <iomanip>
#include <cassert>
#include <chrono>
#include <random>
#include <limits>
#include <iterator>
#include <functional>
#include <sstream>
#include <complex>
using namespace std;

#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, double> Pid;
typedef pair<double, int> Pdi;
typedef pair<ll, int> Pl;
typedef pair<int, pair<int, int>> PP;
typedef pair<P, int> PPi;
constexpr double PI = 3.1415926535897932;   // acos(-1)
constexpr double EPS = 1e-9;
constexpr int INF = 1001001001;
// constexpr int mod = 1e+9 + 7;
constexpr int mod = 998244353;

template<int mod>
struct ModInt{
    int x;

    ModInt() : x(0) {}
    
    ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
    
    ModInt &operator+=(const ModInt &p){
        if((x += p.x) >= mod)   x -= mod;
        return *this;
    }
    
    ModInt &operator-=(const ModInt &p){
        if((x += mod - p.x) >= mod) x -= mod;
        return *this;
    }

    ModInt &operator*=(const ModInt &p){
        x = (int)(1LL * x * p.x % mod);
        return *this;
    }

    ModInt &operator/=(const ModInt &p){
        *this *= p.inverse();
        return *this;
    }
    
    ModInt operator-() const {return ModInt(-x);}

    ModInt operator+(const ModInt &p) const {return ModInt(*this) += p;}

    ModInt operator-(const ModInt &p) const {return ModInt(*this) -= p;}

    ModInt operator*(const ModInt &p) const {return ModInt(*this) *= p;}

    ModInt operator/(const ModInt &p) const {return ModInt(*this) /= p;}

    bool operator==(const ModInt &p) const {return x == p.x;}

    bool operator!=(const ModInt &p) const {return x != p.x;}

    ModInt inverse() const{
        int a = x, b = mod, u = 1, v = 0, t;
        while(b > 0){
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return ModInt(u);
    }

    ModInt pow(int64_t n) const{
        ModInt ret(1), mul(x);
        while(n > 0){
            if(n & 1)   ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const ModInt &p){
        return os << p.x;
    }

    friend istream &operator>>(istream &is, ModInt &a){
        int64_t t;
        is >> t;
        a = ModInt<mod>(t);
        return (is);
    }

    static int get_MOD() {return mod;}
};

using modint = ModInt<mod>;

template<typename T>
struct Compress{
    vector<T> xs;
    Compress() = default;
    Compress(const vector<T> &vs){
        add(vs);
    }
    Compress(const initializer_list<vector<T>> &vs){
        for(auto &p : vs)   add(p);
    }

    // vs内の座標をすべて追加
    void add(const vector<T> &vs){
        copy(begin(vs), end(vs), back_inserter(xs));
    }

    void add(const T &x){
        xs.emplace_back(x);
    }
    
    void build(){
        sort(begin(xs), end(xs));
        xs.erase(unique(begin(xs), end(xs)), end(xs));
    }

    // vs内の座標を座標圧縮したものを返す
    vector<int> get(const vector<T> &vs) const{
        vector<int> ret;
        transform(begin(vs), end(vs), back_inserter(ret), [&](const T &x){
            return lower_bound(begin(xs), end(xs), x) - begin(xs);
        });
        return ret;
    }

    // 座標xを座標圧縮したものを返す (x が xs 内で何番目にあるかを返す)
    int get(const T &x) const{
        return lower_bound(begin(xs), end(xs), x) - begin(xs);
    }

    // 座標圧縮後のkが示す実際の座標を返す
    const T &operator[](int k) const{
        return xs[k];
    }
};

template<typename Monoid>
struct SegmentTree{
    using F = function<Monoid(Monoid, Monoid)>;

    int sz;
    vector<Monoid> seg;

    const F f;      // モノイドに対して二項演算を行う関数オブジェクト
    const Monoid M1;

    SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1){
        sz = 1;
        while(sz < n)   sz <<= 1;
        seg.assign(2 * sz, M1);
    }

    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[k << 1], seg[k << 1 | 1]);
        }
    }

    void update(int k, const Monoid &x){
        k += sz;
        seg[k] = x;
        while(k >>= 1){
            seg[k] = f(seg[k << 1], seg[k << 1 | 1]);
        }
    }

    Monoid query(int a, int b){
        Monoid L = M1, R = M1;
        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];
    }
};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<P> ps(n);
    for(int i = 0; i < n; ++i){
        int x, y;
        cin >> x >> y;
        ps[i] = P(x, y);
    }
    sort(ps.begin(), ps.end());

    Compress<int> compress;
    for(int i = 0; i < n; ++i)  compress.add(ps[i].second);
    compress.build();
    
    SegmentTree<int> segl(n, [](int a, int b){return a + b;}, 0);
    vector<vector<int>> left(n, vector<int>(2));
    for(int i = 0; i < n; ++i){
        int y = compress.get(ps[i].second);
        left[i][0] = segl.query(0, y);
        left[i][1] = segl.query(y, n);
        segl.update(y, 1);
    }

    SegmentTree<int> segr(n, [](int a, int b){return a + b;}, 0);
    vector<vector<int>> right(n, vector<int>(2));
    for(int i = n - 1; i >= 0; --i){
        int y = compress.get(ps[i].second);
        right[i][0] = segr.query(0, y);
        right[i][1] = segr.query(y, n);
        segr.update(y, 1);
    }

    modint res = 0;
    for(int i = 0; i < n; ++i){
        modint foo = 2;
        foo = foo.pow(n - 1);
        modint bar = 0;
        modint A = 2, B = 2, C = 2, D = 2;
        A = A.pow(left[i][0]), B = B.pow(left[i][1]);
        C = C.pow(right[i][0]), D = D.pow(right[i][1]);
        bar += (A - 1) * (D - 1) * B * C;
        bar += (B - 1) * (C - 1) * A * D;
        bar -= (A - 1) * (D - 1) * (B - 1) * (C - 1);
        res += foo + bar;
    }
    cout << res << endl;
}

Measured memory_bytes: 28532