#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(),(x).end()
#define ln '\n'
//constexpr long long MOD = 1000000007LL;
constexpr long long MOD = 998244353LL;
typedef long long ll;
typedef unsigned long long ull; 
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
template<class T, class U> inline bool chmax(T &a, U b) { if (a < b) { a = b; return true;} return false; }
template<class T, class U> inline bool chmin(T &a, U b) { if (a > b) { a = b; return true;} return false; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

template <std::uint_fast64_t Modulus> 
struct ModInt {
    using u64 = std::uint_fast64_t;

    u64 a;

    constexpr ModInt(const long long x = 0) noexcept : a(x >= 0 ? x % Modulus : (Modulus - (-x) % Modulus) % Modulus) {}
    constexpr u64 &value() noexcept { return a; }
    constexpr const u64 &value() const noexcept { return a; }
    constexpr ModInt operator+(const ModInt rhs) const noexcept {return ModInt(*this) += rhs;}
    constexpr ModInt operator-(const ModInt rhs) const noexcept {return ModInt(*this) -= rhs;}
    constexpr ModInt operator*(const ModInt rhs) const noexcept {return ModInt(*this) *= rhs;}
    constexpr ModInt operator/(const ModInt rhs) const noexcept {return ModInt(*this) /= rhs;}
    constexpr ModInt operator^(const long long rhs) const noexcept {return ModInt(*this) ^= rhs;}
    constexpr ModInt &operator+=(const ModInt rhs) noexcept {
        a += rhs.a;
        if (a >= Modulus) {
            a -= Modulus;
        }
        return *this;
    }
    constexpr ModInt &operator-=(const ModInt rhs) noexcept {
        if (a < rhs.a) {
            a += Modulus;
        }
        a -= rhs.a;
        return *this;
    }
    constexpr ModInt &operator*=(const ModInt rhs) noexcept {
        a = a * rhs.a % Modulus;
        return *this;
    }
    constexpr ModInt &operator/=(ModInt rhs) noexcept {
        u64 exp = Modulus - 2;
        while (exp) {
            if (exp % 2) {
                *this *= rhs;
            }
            rhs *= rhs;
            exp /= 2;
        }
        return *this;
    }
    constexpr ModInt &operator^=(long long exp) noexcept {
        ModInt b = a;
        a = 1;
        while (exp) {
            if (exp&1) *this *= b;
            exp >>= 1;
            b *= b;
        }
        return *this;
    }

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

};

using mint = 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);
  }

  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));
  }

  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;
  }

  int get(const T &x) const {
    return lower_bound(begin(xs), end(xs), x) - begin(xs);
  }

  const T &operator[](int k) const {
    return xs[k];
  }
};


template<typename T>
struct BinaryIndexedTree {
    int N;
    vector<T> data;

    BinaryIndexedTree(int sz) {
        N = sz;
        data.assign(++sz, 0);
    }

    T sum(int k) { // [0,k) (0-indexed) a[0] + … + a[k-1]
        T ret = 0;
        for(; k > 0; k -= k & -k) ret += data[k];
        return (ret);
    }

    T sum(int l, int r) { // [l,r) (0-indexed) a[l] + …　+ a[r-1]
        T vl = sum(l);
        T vr = sum(r);
        return vr - vl;
    }

    void add(int k, T x) { // (0-indexed) a[k] += x;
        for(++k; k <= N; k += k & -k) data[k] += x;
    }

    int lowerbound(T x) { // (0-indexed)
        int k = 1;
        int ret = 0;
        while ((k<<1) <= N) k <<= 1;
        while (k > 0) {
            if (ret + k <= N && data[ret+k] < x) {
                x -= data[ret+k];
                ret += k;
            }
            k >>= 1;
        }
        return ret;
    }

    int upperbound(T x) { // (0-indexed)
        ++x;
        int k = 1;
        int ret = 0;
        while ((k<<1) <= N) k <<= 1;
        while (k > 0) {
            if (ret + k <= N && data[ret+k] < x) {
                x -= data[ret+k];
                ret += k;
            }
            k >>= 1;
        }
        return ret;
    }
};

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    vector<int> x(N),y(N);
    rep(i,N) cin >> x[i] >> y[i];
    Compress<int> Com1(x), Com2(y);
    Com1.build();
    Com2.build();
    vector<pii> A;
    rep(i,N) {
        int a = Com1.get(x[i]);
        int b = Com2.get(y[i]);
        A.emplace_back(a,b);
    }

    sort(all(A));
    BinaryIndexedTree<int> BIT(N);
    vector<mint> beki(N+1,1);
    rep(i,N) beki[i+1] = beki[i]*2;
    mint ans = (beki[N]-1)*N;
    rep(i,N) {
        int k = BIT.sum(A[i].second);
        ans -= beki[i] + beki[N-1-i] + beki[A[i].second] + beki[N-1-A[i].second] - beki[k] - beki[i-k] - beki[A[i].second-k] - beki[N-1-A[i].second-i+k];
        BIT.add(A[i].second,1);
    }

    cout << ans.a << ln;
}

Measured memory_bytes: 7736