#include <bits/stdc++.h>

#define rep(i, n) for (int i = 0; i < (n); i++)
#define repr(i, n) for (int i = (n) - 1; i >= 0; i--)

using namespace std;
using ll = long long;

constexpr int MOD = 998244353;

class mint {
  int n;
public:
  mint(int n_ = 0) : n(n_) {}
  explicit operator int() { return n; }
  friend mint operator-(mint a) { return -a.n + MOD * (a.n != 0); }
  friend mint operator+(mint a, mint b) { int x = a.n + b.n; return x - (x >= MOD) * MOD; }
  friend mint operator-(mint a, mint b) { int x = a.n - b.n; return x + (x < 0) * MOD; }
  friend mint operator*(mint a, mint b) { return (long long)a.n * b.n % MOD; }
  friend mint &operator+=(mint &a, mint b) { return a = a + b; }
  friend mint &operator-=(mint &a, mint b) { return a = a - b; }
  friend mint &operator*=(mint &a, mint b) { return a = a * b; }
  friend bool operator==(mint a, mint b) { return a.n == b.n; }
  friend bool operator!=(mint a, mint b) { return a.n != b.n; }
  friend istream &operator>>(istream &i, mint &a) { return i >> a.n; }
  friend ostream &operator<<(ostream &o, mint a) { return o << a.n; }
};

// T: ring
template<class T>
struct wavelet_matrix {
  int H;
  vector<vector<int>> cnt;
  vector<vector<T>> sum;
  struct value {
    int x, y;
    T v;
  };
  vector<int> xs;
  vector<int> ys;
  vector<value> vs;

  void insert(int x, int y, T v) {
    xs.push_back(x);
    ys.push_back(y);
    vs.push_back((value){x, y, v});
  }

  void build() {
    const int n = xs.size();
    if (n == 0) return;
    sort(xs.begin(), xs.end());
    sort(ys.begin(), ys.end());
    ys.erase(unique(ys.begin(), ys.end()), ys.end());
    for (int i = 0; i < n; i++) {
      vs[i].y = lower_bound(ys.begin(), ys.end(), vs[i].y) - ys.begin();
    }
    sort(vs.begin(), vs.end(), [](value a, value b) { return a.x < b.x; });
    int mx = 0;
    for (int i = 0; i < n; i++) {
      mx = max(mx, vs[i].y);
    }
    H = 0;
    while ((1 << H) <= mx) H++;
    cnt.assign(H, vector<int>(n + 1));
    sum.assign(H+1, vector<T>(n + 1));
    auto dfs = [&](auto dfs, int l, int r, int h) -> void {
      if (r - l == 0) return;
      for (int i = l; i < r; i++) {
        sum[h][i + 1] = sum[h][i] + vs[i].v;
      }
      if (h == H) return;
      for (int i = l; i < r; i++) {
        cnt[h][i + 1] = cnt[h][i] + (~vs[i].y >> (H - 1 - h) & 1);
      }
      int m = stable_partition(vs.begin() + l, vs.begin() + r, [&](value x) {
        return ~x.y >> (H - 1 - h) & 1;
      }) - vs.begin();
      dfs(dfs, l, m, h + 1);
      dfs(dfs, m, r, h + 1);
    };
    dfs(dfs, 0, n, 0);
  }

  // [l,r) * [b,t)
  T query(int l, int r, int b, int t) {
    const int n = xs.size();
    l = lower_bound(xs.begin(), xs.end(), l) - xs.begin();
    r = lower_bound(xs.begin(), xs.end(), r) - xs.begin();
    b = lower_bound(ys.begin(), ys.end(), b) - ys.begin();
    t = lower_bound(ys.begin(), ys.end(), t) - ys.begin();
    auto dfs = [&](auto dfs, int l, int r, int b, int t, int ll, int rr, int bb, int tt, int h) -> T {
      if (r - l == 0 || t - b == 0) return T();
      if (tt <= b || t <= bb) return T();
      if (b <= bb && tt <= t) return sum[h][r] - sum[h][l];
      int mm = ll + cnt[h][rr] - cnt[h][ll];
      T vl = dfs(dfs, ll + cnt[h][l] - cnt[h][ll], ll + cnt[h][r] - cnt[h][ll], b, t, ll, mm, bb, (bb + tt) / 2, h + 1);
      T vr = dfs(dfs, l + cnt[h][rr] - cnt[h][l], r + cnt[h][rr] - cnt[h][r], b, t, mm, rr, (bb + tt) / 2, tt, h + 1);
      return vl + vr;
    };
    return dfs(dfs, l, r, b, t, 0, n, 0, 1<<H, 0);
  }
};


int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  wavelet_matrix<int> wm;
  int N; cin >> N;
  vector<int> xs(N), ys(N);
  rep(i, N) cin >> xs[i] >> ys[i], wm.insert(xs[i], ys[i], 1);
  wm.build();
  mint ans;
  const int INF = 1.01e9;
  vector<mint> two(N + 1);
  two[0] = 1;
  rep(i, N) two[i + 1] = two[i] * 2;
  rep(i, N) {
    int a = wm.query(-INF, xs[i], ys[i] + 1, INF);
    int b = wm.query(xs[i], xs[i] + 1, ys[i] + 1, INF);
    int c = wm.query(xs[i] + 1, INF, ys[i] + 1, INF);
    int d = wm.query(xs[i] + 1, INF, ys[i], ys[i] + 1);
    int e = wm.query(xs[i] + 1, INF, -INF, ys[i]);
    int f = wm.query(xs[i], xs[i] + 1, -INF, ys[i]);
    int g = wm.query(-INF, xs[i], -INF, ys[i]);
    int h = wm.query(-INF, xs[i], ys[i], ys[i] + 1);
//    cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << ' ' << f << ' ' << g << ' ' << h << endl;
    ans += 1;
    ans += two[a] - 1;
    ans += two[b] - 1;
    ans += two[c] - 1;
    ans += two[d] - 1;
    ans += two[e] - 1;
    ans += two[f] - 1;
    ans += two[g] - 1;
    ans += two[h] - 1;

    ans += (two[a] - 1) * (two[b] - 1);
    ans += (two[b] - 1) * (two[c] - 1);
    ans += (two[c] - 1) * (two[d] - 1);
    ans += (two[d] - 1) * (two[e] - 1);
    ans += (two[e] - 1) * (two[f] - 1);
    ans += (two[f] - 1) * (two[g] - 1);
    ans += (two[g] - 1) * (two[h] - 1);
    ans += (two[h] - 1) * (two[a] - 1);

    ans += (two[a] - 1) * (two[c] - 1);
    ans += (two[c] - 1) * (two[e] - 1);
    ans += (two[e] - 1) * (two[g] - 1);
    ans += (two[g] - 1) * (two[a] - 1);

    ans += (two[a] - 1) * (two[b] - 1) * (two[c] - 1);
    ans += (two[c] - 1) * (two[d] - 1) * (two[e] - 1);
    ans += (two[e] - 1) * (two[f] - 1) * (two[g] - 1);
    ans += (two[g] - 1) * (two[h] - 1) * (two[a] - 1);
  }
 // cout << ans << endl;
//  cout << two[N] * N << endl;
  ans = two[N] * N - ans;
  cout << ans << endl;
}


Measured memory_bytes: 38908