#include <bits/stdc++.h>

#define REP(i,n) for (int i=0;i<(n);++i)
#define RREP(i,n) for (int i=(n)-1;i>=0;--i)
#define all(a) (a).begin(),(a).end()
#define MOD 998244353

using namespace std;

using pii = pair<int, int>;
using ll = long long;

template<class T>
class fenwick_tree {
private:
    const size_t size;
    const std::function<T(T, T)> f;
    const T unit;
    std::vector<T> a;
public:
    fenwick_tree(size_t size, std::function<T(T, T)> f, T unit) : size(size), f(f), unit(unit), a(size, unit) { }

    void update(size_t i, T x) {
        for (size_t j = i; j < size; j |= j + 1) {
            a[j] = f(a[j], x);
        }
    }

    T query(size_t i) const {
        T result = unit;
        for (size_t j = i; j > 0; j = (j & (j + 1))) {
            result = f(result, a[--j]);
        }
        return result;
    }
};

template <class T>
class range_add_sum_query {
private:
    fenwick_tree<T> fenwick_1;
    fenwick_tree<T> fenwick_2;
public:
    range_add_sum_query(size_t n) : fenwick_1(n + 1, [](T x, T y) { return x + y; }, 0),
                                    fenwick_2(n + 1, [](T x, T y) { return x + y; }, 0) { }

    void update(size_t first, size_t last, T x) {
        fenwick_1.update(first, x);
        fenwick_1.update(last, -x);
        fenwick_2.update(first, first * x);
        fenwick_2.update(last, -last * x);
    }

    T query(size_t last) const {
        return fenwick_1.query(last) * last - fenwick_2.query(last);
    }

    T query(size_t first, size_t last) const {
        return query(last) - query(first);
    }
};

template <class T, T M>
class modulo {
public:
    T data;

    modulo(T data = 0) {
        T r = data % M;
        if (r < 0) {
            r += M;
        }
        this->data = r;
    }

    modulo operator+(const modulo &x) const {
        return modulo(data + x.data);
    }

    modulo operator-(const modulo &x) const {
        return modulo(data + (M - x.data));
    }

    modulo operator*(const modulo &x) const {
        return modulo(data * x.data);
    }

    modulo operator/(const modulo &x) const {
        return modulo(data * x.inv().data);
    }

    modulo operator+=(const modulo &x) {
        return data = (data + x.data) % M;
    }

    modulo operator-=(const modulo &x) {
        return data = (data + (M - x.data)) % M;
    }

    modulo operator*=(const modulo &x) {
        return data = (data * x.data) % M;
    }

    modulo operator/=(const modulo &x) {
        return data = (data * x.inv().data) % M;
    }

    modulo inv() const {
        return _pow(M - 2);
    }

    template <class Integer>
    modulo operator^(Integer n) const {
        if (n >= 0) {
            return _pow(n);
        } else {
            return _pow(M - 1 - (-n) % (M - 1));
        }
    }

    friend std::ostream& operator<<(std::ostream &os, const modulo &x) {
        os << x.data;
        return os;
    }

private:
    template <class NonNegativeInteger>
    modulo _pow(NonNegativeInteger n) const {
        modulo result(1);
        modulo x(*this);
        while (n) {
            if (n & 1) {
                result *= x;
            }
            x *= x;
            n >>= 1;
        }
        return result;
    }
};

template <class T>
std::vector<size_t> get_rank(const std::vector<T> &a) {

    size_t N = a.size();

    std::vector<std::pair<T, size_t>> v(N);
    REP(i, N) v[i] = std::make_pair(a[i], i);
    std::sort(v.begin(), v.end());

    std::vector<size_t> result(N);
    for (size_t i = 0; i < N; ++i) {
        auto [x, r] = v[i];
        result[r] = i;
    }

    return result;
}

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

    using Mod = modulo<ll, MOD>;

    int N;
    cin >> N;
    vector<int> _x(N), _y(N);
    REP(i, N) cin >> _x[i] >> _y[i];

    auto x = get_rank(_x);
    auto y = get_rank(_y);

    vector<pii> xy(N);
    REP(i, N) xy[i] = make_pair(x[i], y[i]);
    sort(all(xy));

    vector<int> UL(N), UR(N), DL(N), DR(N);
    auto rasq1 = range_add_sum_query<int>(N);
    REP(i, N) {
        int Y = xy[i].second;
        UR[i] = rasq1.query(Y, Y + 1);
        UL[i] = i - UR[i];
        rasq1.update(0, Y + 1, 1);
    }
    auto rasq2 = range_add_sum_query<int>(N);
    RREP(i, N) {
        int Y = xy[i].second;
        DR[i] = rasq2.query(Y, Y + 1);
        DL[i] = (N - 1 - i) - DR[i];
        rasq2.update(0, Y + 1, 1);
    }

    Mod result = 0;
    REP(i, N) {
        Mod t = 2;
        result += t ^ (N - 1);    
        result += ((t ^ UL[i]) - 1) * ((t ^ DR[i]) - 1) * (t ^ (UR[i] + DL[i]));
        result += ((t ^ UR[i]) - 1) * ((t ^ DL[i]) - 1) * (t ^ (UL[i] + DR[i]));
        result -= ((t ^ UL[i]) - 1) * ((t ^ DR[i]) - 1) * ((t ^ UR[i]) - 1) * ((t ^ DL[i]) - 1);
    }

    cout << result << endl;

    return 0;
}


Measured memory_bytes: 16508