#include <set>
#include <vector>

template<class T>
struct Compression {
  using size_type = std::size_t;

  std::vector<T> v;

  Compression(){}
  void add(const T& t) { v.push_back(t); }
  void build() {
    sort(begin(v), end(v));
    v.erase(unique(begin(v), end(v)), end(v));
  }
  size_type comp(const T& x) const {
    return lower_bound(begin(v), end(v), x) - begin(v);
  }
  size_type size() const { return v.size(); }
};

template<class T>
struct plane_to_line {
  using size_type = std::size_t;
  using coord_type = std::pair<T, T>;
  using value_type = T;

  std::vector<std::pair<coord_type, size_type>> elems;
  std::vector<size_type> yarray;
  std::vector<size_type> xstart;
  Compression<value_type> X, Y;

  plane_to_line(const std::vector<coord_type>& a): elems(a.size()) {
    for(size_type i = 0;i < a.size();i++) {
      elems[i] = { a[i], i };
      X.add(a[i].first);
      Y.add(a[i].second);
    }
    sort(std::begin(elems), std::end(elems));
    X.build();
    Y.build();

    xstart.resize(X.size() + 1);
    yarray.resize(elems.size());
    size_type x = 0;
    for(size_type i = 0;i < elems.size();i++) {
      if(!i || elems[i - 1].first.first < elems[i].first.first) {
        xstart[x++] = i;
      }
      yarray[i] = Y.comp(elems[i].first.second);
    }
    xstart[X.size()] = elems.size();
  }

  struct rangefreq_arg {
    size_type left;
    size_type right;
    size_type x;
    size_type y;
  };

  rangefreq_arg to_rangefreq(value_type xl, value_type xr, value_type yl, value_type yr) const {
    size_type cxl = xstart[X.comp(xl)];
    size_type cxr = xstart[X.comp(xr)];
    size_type cyl = Y.comp(yl);
    size_type cyr = Y.comp(yr);
    return rangefreq_arg { cxl, cxr, cyl, cyr };
  }
};

#include <cstdint>
#include <set>
#include <vector>
#include <iostream>

using i64 = long long;

class bitvector {
  using bit_type = std::uint_least64_t;
  using size_type = std::size_t;
  static constexpr size_type wordsize = 64;
  
  std::vector<bit_type> bit;
  std::vector<size_type> sum;
  
public:

  bitvector() : bit(), sum() {} 
  bitvector(const size_type size)
    : bit(size / wordsize + 1, 0), sum(size / wordsize + 1, 0) {}

  void set(const size_type i) {
    bit[i / wordsize] |= static_cast<bit_type>(1) << (i % wordsize);
  }
  void build() {
    for (size_type i = 1; i < bit.size(); i++) {
      sum[i] = sum[i - 1] + __builtin_popcountll(bit[i - 1]);
    }
  }

  size_type at(const size_type i) const {
    return bit[i / wordsize] >> (i % wordsize);
  }

  // count of ones in [0, i)
  size_type rank(const size_type i) const {
    return sum[i / wordsize]
      + __builtin_popcountll(bit[i / wordsize] & (static_cast<bit_type>(1) << (i % wordsize)) - 1);
  }

  // count of ones in [0, i)
  size_type rank(const size_type i, const size_type b) const {
    size_type ans = sum[i / wordsize]
      + __builtin_popcountll(bit[i / wordsize] & (static_cast<bit_type>(1) << (i % wordsize)) - 1);
    if(b) return ans;
    else return i - ans;
  }
};

class wavelet_matrix {
  using Integer = std::size_t;
  using integer_type = Integer;
  using size_type = std::size_t;


  const size_type depth;
  const size_type len;
  std::vector<bitvector> mat;
  std::vector<size_type> spl;

public:

  wavelet_matrix(const std::vector<integer_type>& arr, size_type de)
    : depth(de),
      len(arr.size()),
      mat(std::vector<bitvector>(depth, bitvector(arr.size()))),
      spl(std::vector<size_type>(depth, 0)) {
        std::vector<size_type> idx(len);
        std::vector<size_type> left(len), right(len);
        for(size_type i = 0;i < len;i++) idx[i] = i;
        for(size_type d = depth; d-- > 0;) {
          size_type l = 0, r = 0;
          
          for(size_type i = 0; i < len; i++) {
            size_type k = (arr[idx[i]] >> d) & 1;
            if(k) right[r++] = idx[i], mat[d].set(i);
            else left[l++] = idx[i];
          }
          mat[d].build();
          spl[d] = l;
          swap(idx, left);
          for(size_type i = 0; i < r; i++) idx[i + l] = right[i];
        }
      }

  integer_type at(size_type i) const {
    integer_type x = static_cast<integer_type>(0);
    for(size_type d = depth; d-- > 0;) {
      size_type k = mat[d].at(i);
      x |= (static_cast<integer_type>(k) << d);
      i = mat[d].rank(i, k) + spl[d] * k;
    }
    return x;
  }

  // counting elements that equal to x in range [left, right)
  size_type rank_x(size_type left, size_type right, integer_type x) const {
    for(size_type d = depth; d-- > 0;) {
      size_type k = ((x >> d) & 1);
      left = mat[d].rank(left, k) + spl[d] * k;
      right = mat[d].rank(right, k) + spl[d] * k;
    }
    return right - left;
  }

  // sorted(arr[left..right])[i]
  integer_type quantile(size_type left, size_type right, size_type i) const {
    integer_type x = static_cast<integer_type>(0);
    for(size_type d = depth; d-- > 0;) {
      size_type cnt = mat[d].rank(right, 0) - mat[d].rank(left, 0);
      size_type k = (i < cnt) ? 0 : 1;
      if(k == 1) {
        i -= cnt;
        x |= (1 << d);
      }
      left = mat[d].rank(left, k) + spl[d] * k;
      right = mat[d].rank(right, k) + spl[d] * k;
    }
    return x;
  }

  struct rank_result {
    size_type le;
    size_type eq;
    size_type mo;
  };

  // couting elements that less than x, equal to x, and more than x in range [left, right)
  rank_result rank_less_eq_more(size_type left, size_type right, integer_type x) const {
    size_type le = 0, mo = 0;
    for(size_type d = depth; d --> 0;) {
      size_type k = (x >> d) & 1;
      size_type l = mat[d].rank(left, 1);
      size_type r = mat[d].rank(right, 1);
      if(k == 0) {
        mo += r - l;
        left -= l;
        right -= r;
      }
      else {
        le += (right - left) - (r - l);
        left = l + spl[d];
        right = r + spl[d];
      }
    }
    return rank_result { le, right - left, mo };
  }

  size_type rangefreq(size_type left, size_type right, integer_type x, integer_type y, integer_type l, size_type d) const {
    integer_type r = l + (1 << d);
    if(x <= l && r <= y) {
      return right - left;
    }
    else if(y <= l || r <= x) {
      return 0;
    }
    else {
      d--;
      size_type lr = mat[d].rank(left, 1);
      size_type rr = mat[d].rank(right, 1);
      return
        rangefreq(left - lr, right - rr, x, y, l, d) +
        rangefreq(lr + spl[d], rr + spl[d], x, y, l + (1 << d), d);
    }
  }

  size_type rangefreq(size_type left, size_type right, integer_type x, integer_type y) const {
    return rangefreq(left, right, x, y, 0, depth);
  }
};

#include <iostream>
using i64 = long long;
template<i64 M> struct modint { i64 a;
  constexpr modint(const i64 x = 0): a((x%M+M)%M){}
  constexpr i64 value() const { return a; }
  constexpr modint inv() const { return this->pow(M-2); }
  constexpr modint pow(i64 r) const {
    modint ans(1); modint aa = *this;
    while(r) { if(r & 1) ans *= aa; aa *= aa; r >>= 1; }
    return ans;
  }
  constexpr modint& operator=(const i64 r) { a = (r % M + M) % M; return *this; }
  constexpr modint& operator+=(const modint r) { a += r.a; if(a >= M) a -= M; return *this; }
  constexpr modint& operator-=(const modint r) { a -= r.a; if(a < 0) a += M; return *this; }
  constexpr modint& operator*=(const modint r) { a = a * r.a % M; return *this; }
  constexpr modint& operator/=(const modint r) { (*this) *= r.inv(); return *this; }
  constexpr modint operator+(const modint r) const { return modint(*this) += r; }
  constexpr modint operator-(const modint r) const { return modint(*this) -= r; }
  constexpr modint operator*(const modint r) const { return modint(*this) *= r; }
  constexpr modint operator/(const modint r) const { return modint(*this) /= r; }
  constexpr bool operator!=(const modint r) const { return this->value() != r.value(); }
};

template<const i64 M> std::ostream& operator<<(std::ostream& os, const modint<M>& m) { os << m.value(); return os; }

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(i64 (i) = (s);(i) < (e);(i)++)
#define all(x) x.begin(),x.end()

template<class T>
static inline std::vector<T> ndvec(size_t&& n, T val) { return std::vector<T>(n, std::forward<T>(val)); }
template<class... Tail>
static inline auto ndvec(size_t&& n, Tail&&... tail) {
  return std::vector<decltype(ndvec(std::forward<Tail>(tail)...))>(n, ndvec(std::forward<Tail>(tail)...));
}
template<class Cond> struct chain {
  Cond cond; chain(Cond cond) : cond(cond) {}
  template<class T> bool operator()(T& a, const T& b) const { if(cond(a, b)) { a = b; return true; } return false; }
};
template<class Cond> chain<Cond> make_chain(Cond cond) { return chain<Cond>(cond); }

using fp = modint<998244353>;

int main() {
  i64 N;
  cin >> N;
  vector<pair<i64, i64>> A(N);
  rep(i,0,N) {
    cin >> A[i].first >> A[i].second;
  }
  plane_to_line<i64> pl(A);
  wavelet_matrix wv(pl.yarray, 20);

  vector<fp> bin;
  bin.push_back(fp(1));
  rep(i,0,N) {
    bin.push_back(bin.back() * fp(2));
  }
  fp ans(0);
  const i64 INF = 1e10 + 1;
  rep(i,0,N) {
    i64 a, b, c, d;
    i64 x = A[i].first;
    i64 y = A[i].second;
    {
      auto ar = pl.to_rangefreq(-INF, x, y + 1, INF);
      a = wv.rangefreq(ar.left, ar.right, ar.x, ar.y);
    }
    {
      auto ar = pl.to_rangefreq(x + 1, INF, y + 1, INF);
      b = wv.rangefreq(ar.left, ar.right, ar.x, ar.y);
    }
    {
      auto ar = pl.to_rangefreq(-INF, x, -INF, y);
      c = wv.rangefreq(ar.left, ar.right, ar.x, ar.y);
    }
    {
      auto ar = pl.to_rangefreq(x + 1, INF, -INF, y);
      d = wv.rangefreq(ar.left, ar.right, ar.x, ar.y);
    }
    ans += bin[a + b + c + d];
    ans += (bin[a] - 1) * (bin[d] - 1) * bin[b + c];
    ans += (bin[b] - 1) * (bin[c] - 1) * bin[a + d];
    ans -= (bin[b] - 1) * (bin[c] - 1) * (bin[a] - 1) * (bin[d] - 1);
  }
  cout << ans << endl;
}


Measured memory_bytes: 21400