#include <bits/stdc++.h>
using namespace std;
#define int long long
using ll = long long;
#define REP(i, N) for (int i = 0; i < (N); ++i)
void chmax(int &a, const int b) { if (a < b) a = b; }

template<typename T> struct BinaryIndexedTree {
    vector< T > data;
    BinaryIndexedTree(int sz) { data.assign(++sz, 0); }
    T sum(int k) {
        if (k < 0) return T(0);
        T ret = 0;
        for (++k; k > 0; k -= k & -k) ret += data[k];
        return (ret);
    }
    T sum(int l, int r) {
        assert(l <= r);
        return sum(r - 1) - sum(l - 1);
    }
    void add(int k, T x) {
        for (++k; k < data.size(); k += k & -k) data[k] += x;
    }
};

template<typename T> vector<T> compress(vector<T> ord, map<T, int> &rev) {
    vector< T > com = ord;
    sort(com.begin(), com.end());
    com.erase(unique(com.begin(), com.end()), com.end());
    for (int i = 0; i < com.size(); ++i) rev[com[i]] = i;
    vector< T > ret; for (auto& e : ord) ret.emplace_back(rev[e]);
    return ret;
}

const int MX = 400200;
const int MOD = 998244353;

int N;
vector<pair<int, int>> points, inter;

signed main() {
    
    cin >> N;
    
    // 2^N - 1
    vector<int> twos(1, 0);
    REP(i, MX) twos.emplace_back(((twos.back() + 1) * 2 + MOD - 1) % MOD);
    
    vector<int> VX, VY;
    REP(i, N) {
        int X, Y;
        cin >> X >> Y;
        points.emplace_back(X, Y);
        VX.emplace_back(X);
        VY.emplace_back(Y);
    }
    
    map<int, int> mp_X, mp_Y;
    auto CX = compress(VX, mp_X);
    auto CY = compress(VY, mp_Y);
    
    // yの昇順, xの昇順
    /*
    sort(points.begin(), points.end(), [](pair<int, int> a, pair<int, int> b) {
        if (a.second > b.second) return false;
        if (a.second < b.second) return true;
        return a.first < b.first;
    });
    */
    
    vector<vector<int>> y_gather(MX);
    for (auto& e: points) {
        int x, y;
        tie(x, y) = e;
        x = mp_X[x];
        y = mp_Y[y];
        inter.emplace_back(x, y);
        y_gather[y].emplace_back(x);
    }
    for (auto& e: y_gather) sort(e.begin(), e.end());
    
    BinaryIndexedTree<int> bit_less(MX), bit_more(MX);
    for (auto& e: inter) bit_more.add(e.first, 1);
    
    ll res = 0;
    
    for (auto& ey: y_gather) {
        for (auto& x: ey) bit_more.add(x, -1);
        int t = ey.size();
        int l = 0, r = t - 1;
        for (auto& x: ey) {
            int A = bit_more.sum(0, x);
            int B = bit_more.sum(x + 1, MX);
            int C = bit_less.sum(0, x);
            int D = bit_less.sum(x + 1, MX);
            int AC = l;
            int BD = r;
            int AB = bit_more.sum(x, x + 1);
            int CD = bit_less.sum(x, x + 1);
            
            ll tmp = twos[N];
            
            tmp -= twos[A];
            tmp -= twos[B];
            tmp -= twos[C];
            tmp -= twos[D];
            tmp -= twos[AB];
            tmp -= twos[AC];
            tmp -= twos[BD];
            tmp -= twos[CD];
            
            tmp -= twos[A] * twos[B];
            tmp -= twos[B] * twos[D];
            tmp -= twos[D] * twos[C];
            tmp -= twos[C] * twos[A];
            
            tmp -= twos[A] * twos[AB];
            tmp -= twos[AB] * twos[B];
            tmp -= twos[B] * twos[BD];
            tmp -= twos[BD] * twos[D];
            tmp -= twos[D] * twos[CD];
            tmp -= twos[CD] * twos[C];
            tmp -= twos[C] * twos[AC];
            tmp -= twos[AC] * twos[C];
            
            tmp %= MOD;
            tmp += MOD;
            
            (res += tmp) %= MOD;
            
            ++l, --r;
        }
        for (auto& x: ey) bit_less.add(x, 1);
    }
    
    cout << res << endl;
    
}


Measured memory_bytes: 65260