#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <functional>
#include <numeric>
#include <set>
// #include <bits/stdc++.h>

using namespace std;
typedef long long li;


template <long long mod>
struct modint {
    static const long long CACHE_SIZE = 1000000;

    long long x;

    modint<mod>(): x(0LL) {}
    modint<mod>(const long long _data) {
        if (_data < 0) {
            x = (_data % mod + mod) % mod;
        } else if (_data >= mod) {
            x = _data % mod;
        } else {
            x = _data;
        }
    }

    bool operator==(const modint<mod>& op) const {
        return x == op.x;
    }

    bool operator!=(const modint<mod>& op) const {
        return !((*this) == op);
    }

    modint<mod> operator-() const {
        if (x == 0) {
            return modint(0);
        }
        return modint(mod - x);
    }

    modint<mod> operator+(const modint<mod>& op) const {
        const long long newdata = x + op.x;
        if (newdata >= mod) {
            return modint<mod>(newdata - mod);
        } else {
            return modint<mod>(newdata);
        }
    }

    modint<mod> operator-(const modint<mod>& op) const {
        return *this + (-op);
    }

    modint<mod> operator*(const modint<mod>& op) const {
        return modint<mod>(x * op.x % mod);
    }

    modint<mod> pow(const long long n) const {
        if (n == 0) {
            return modint<mod>(1);
        }
        modint<mod> sq = pow(n / 2);
        if (n & 1) {
            return (*this) * sq * sq;
        } else {
            return sq * sq;
        }
    }

    modint<mod> inverse() const {
        return pow(mod - 2);
    }

    modint<mod> operator/(const modint<mod>& op) const {
        return (*this) * op.inverse();
    }

    friend modint<mod> operator/(const long long dividend, const modint<mod>& divisor) {
        return modint<mod>(dividend) / divisor;
    }

    static modint<mod> factorial(const long long n) {
        static modint<mod> cache[CACHE_SIZE] = {};

        if (cache[n].x != 0) {
            return cache[n];
        }

        if (n == 0) {
            return cache[0] = modint<mod>(1);
        } else {
            const modint<mod> retvar = modint<mod>(n) * factorial(n - 1);
            if (n < CACHE_SIZE) {
                cache[n] = retvar;
            }
            return retvar;
        }
    }

    static modint<mod> combination(const long long n, const long long k) {
        if (k < 0 || n < k) {
            return modint<mod>(0);
        }

        if (n < CACHE_SIZE) {
            return factorial(n) / (factorial(k) * factorial(n - k));
        }

        modint<mod> ret(1);
        for (int i = 1; i <= k; ++i) {
            ret = ret * modint<mod>(n - i + 1) / modint<mod>(i);
        }
        return ret;
    }
};

typedef modint<998244353> mint;

// Index range: [1, n]
// sum(x) returns the sum over [1, x]
// add(x, v) adds v to the value at x.
struct BIT {
    int n;
    vector<li> bit;

    BIT(int _n): n(_n), bit(_n + 1) {}

    li sum(int i) {
        li s = 0;
        while (i > 0) {
            s += bit[i];
            i -= i & -i;
        }
        return s;
    }

    void add(int i, li x) {
        while (i <= n) {
            bit[i] += x;
            i += i & -i;
        }
    }
};

#include <map>

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    li n;
    cin >> n;
    vector<li> xs(n), ys(n);
    set<li> xvs, yvs;

    for (int i = 0; i < n; ++i) {
        li x, y;
        cin >> x >> y;
        xvs.insert(x);
        yvs.insert(y);
        xs[i] = x;
        ys[i] = y;
    }

    map<li, li> xcomp, ycomp;
    for (const auto &xv : xvs) {
        li idx = xcomp.size();
        xcomp[xv] = idx + 1;
    }
    for (const auto &yv : yvs) {
        li idx = ycomp.size();
        ycomp[yv] = idx + 1;
    }

    for (int i = 0; i < n; ++i) {
        xs[i] = xcomp[xs[i]];
        ys[i] = ycomp[ys[i]];
    }

    set<pair<li, li>> order;
    map<li, vector<li>> points_byx;
    BIT right_t(n + 5), mid_t(n + 5), left_t(n + 5);
    for (int i = 0; i < n; ++i) {
        order.emplace(xs[i], i);
        points_byx[xs[i]].push_back(i);

        right_t.add(ys[i], 1);
    }

    li prevx = -1;
    mint ans = 0;
    for (const auto &item : order) {
        ans = ans + mint(2).pow(n) - 1;

        li i = item.second;
        li x = xs[i];
        li y = ys[i];

        if (x != prevx) {
            for (const auto &idx : points_byx[prevx]) {
                mid_t.add(ys[idx], -1);
                left_t.add(ys[idx], 1);
            }
            for (const auto &idx : points_byx[x]) {
                right_t.add(ys[idx], -1);
                mid_t.add(ys[idx], 1);
            }
        }

        li topleft = left_t.sum(n) - left_t.sum(y);
        li bottomleft = left_t.sum(y - 1);
        li topright = right_t.sum(n) - right_t.sum(y);
        li bottomright = right_t.sum(y - 1);

        li top = topleft + topright + mid_t.sum(n) - mid_t.sum(y);
        li bottom = bottomleft + bottomright + mid_t.sum(y - 1);
        li left = left_t.sum(n);
        li right = right_t.sum(n);

        ans = ans - mint(2).pow(top);
        ans = ans - mint(2).pow(bottom);
        ans = ans - mint(2).pow(left);
        ans = ans - mint(2).pow(right);

        ans = ans + mint(2).pow(topleft);
        ans = ans + mint(2).pow(topright);
        ans = ans + mint(2).pow(bottomleft);
        ans = ans + mint(2).pow(bottomright);

        prevx = x;
    }

    cout << ans.x << endl;
    return 0;
}


Measured memory_bytes: 86272