template<typename S, typename E = S> class SegmentTreeDLP {
 public:
  using Size = long long;
  SegmentTreeDLP(Size L, Size R, S es=0, E ee=0) : L(L), R(R), es(es), ee(ee), root(new Node(es,ee)) {}
  void set(Size a, S x) {set(a, x, root, L, R);}
  void add(Size a, Size b, E x) {add(a, b, x, root, L, R);}
  S query(Size a, Size b) {return query(a, b, root, L, R);}
 private:
  struct Node {
    S val; E laz;
    Node *lchild, *rchild;
    Node(S val, E laz) : val(val), laz(laz), lchild(nullptr), rchild(nullptr) {}
  };
  inline S fs(S l, S r) const {return l + r;}
  inline S fa(S l, E r, Size len) const {return l + r * len;}
  inline E fe(E l, E r) const {return l + r;}
  inline S reflect(const auto& n, Size len) {return n->laz==ee ? n->val : fa(n->val, n->laz, len);}
  inline void propagate(const auto& n, Size len) {
    if(n->lchild == nullptr) n->lchild = new Node(es, ee);
    if(n->rchild == nullptr) n->rchild = new Node(es, ee);
    if(n->laz == ee) return;
    n->lchild->laz = fe(n->lchild->laz, n->laz);
    n->rchild->laz = fe(n->rchild->laz, n->laz);
    n->val = reflect(n, len);
    n->laz = ee;
  }
  inline void recalc(const auto& n, Size len) {n->val = fs(reflect(n->lchild, len), reflect(n->rchild, len));}
  void set(Size a, E x, const auto &n, Size l, Size r) {
    propagate(n, r-l);
    if(l+1 == r) {
      n->val = x;
      return;
    }
    auto m = (l + r) / 2;
    if(a < m) set(a, x, n->lchild, l, m);
    else      set(a, x, n->rchild, m, r);
    recalc(n, r-l);
  }
  void add(Size a, Size b, E x, const auto &n, Size l, Size r) {
    propagate(n, r-l);
    if(b <= l || r <= a) return;
    if(a <= l && r <= b) {
      n->laz = fe(n->laz, x);
      propagate(n, r-l);
      return;
    }
    auto m = (l + r) / 2;
    add(a, b, x, n->lchild, l, m);
    add(a, b, x, n->rchild, m, r);
    recalc(n, r-l);
  }
  S query(Size a, Size b, const auto &n, Size l, Size r) {
    propagate(n, r-l);
    if(b <= l || r <= a) return es;
    if(a <= l && r <= b) return reflect(n, r-l);
    auto m = (l + r) / 2;
    auto vl = query(a, b, n->lchild, l, m);
    auto vr = query(a, b, n->rchild, m, r);
    return fs(vl, vr);
  }
  Size L, R;
  Node *root;
  S es; E ee;
};

#include<bits/stdc++.h>
using namespace std;

using LL = long long;

const LL M = 998244353;
const LL INF = 1e9+1;

LL power(LL m, LL n) {
  if(!n) return 1;
  return (n & 1) ? (power(m, n - 1) * m % M) : power(m * m % M, n >> 1);
}

int main() {
  struct Point {LL x, y, ul, ur, ll, lr;};
  int N;
  cin >> N;
  vector<Point> P(N);
  for(auto& i: P) cin >> i.x >> i.y;

  sort(begin(P), end(P), [](auto& l, auto& r){
    if(l.x != r.x) return l.x < r.x;
    return l.y < r.y;
  });
  SegmentTreeDLP<int> rsq(-INF, INF);
  for(auto& p: P) {
    p.ll = rsq.query(-INF,  p.y+1);
    p.ul = rsq.query(p.y+1, INF);
    rsq.set(p.y, 1);
  }

  sort(begin(P), end(P), [](auto& l, auto& r){
    if(l.x != r.x) return l.x > r.x;
    return l.y > r.y;
  });
  rsq = SegmentTreeDLP<int>(-INF, INF);
  for(auto& p: P) {
    p.ur = rsq.query(p.y,  INF);
    p.lr = rsq.query(-INF, p.y);
    rsq.set(p.y, 1);
  }

  LL ans = 0;
  for(auto& p: P) {
    (ans += power(2,N-1)) %= M;
    auto urll = (power(2,p.ur)-1) * (power(2,p.ll)-1) % M;
    auto ullr = (power(2,p.ul)-1) * (power(2,p.lr)-1) % M;
    (ans += urll * power(2,N-1-p.ur-p.ll) % M) %= M;
    (ans += ullr * power(2,N-1-p.ul-p.lr) % M) %= M;
    (ans += M - (urll*ullr%M) * power(2,N-1-p.ur-p.ll-p.ul-p.lr)%M) %= M;
  }
  cout << ans << endl;
}


Measured memory_bytes: 658328