#include <bits/stdc++.h>
#define INF 2000000000000000000
#define ll long long
#define pll pair<ll, ll>
using namespace std;

//=============Segment_Tree_with_Lazy_Propagation====
const int MAX_N = 1 << 18;//要変更
int n;
vector<ll> dat(2 * MAX_N - 1, 0);//要変更
vector<ll> lazy(2 * MAX_N - 1, 0);//要変更

void init(ll n_) {
  n = 1;
  while (n < n_) {
    n *= 2;
  }
}

void eval(ll k, ll l, ll r) {
  if (lazy.at(k) != 0) {
    dat.at(k) += lazy.at(k);//要変更
    if (r - l > 1) {
      lazy.at(k * 2 + 1) += lazy.at(k);//要変更
      lazy.at(k * 2 + 2) += lazy.at(k);//要変更
    }
    lazy.at(k) = 0;
  }
}

void update(ll a, ll b, ll plus = 1, ll k = 0, ll l = 0, ll r = n) {
  if (r <= a || b <= l) {
    eval(k, l, r);//子供のlazyを更新する必要がある
    return;
  }
  if (a <= l && r <= b) {
    lazy.at(k) += plus;//要変更
    eval(k, l, r);//子供のlazyを更新する必要がある
  }
  else {
    eval(k, l, r);//updateで使う子供のlazeとdat.at(k)の更新
    update(a, b, plus, k * 2 + 1, l, (l + r) / 2);
    update(a, b, plus, k * 2 + 2, (l + r) / 2, r);
    dat.at(k) = min(dat.at(2 * k + 1), dat.at(2 * k + 2));//要変更
  }
}

ll query(ll a, ll b, ll k = 0, ll l = 0, ll r = n) {
  if (r <= a || b <= l) {
    return INF;//要変更
  }
  eval(k, l, r);//dat.at(k)と子供のlazy更新のためreturn datとqueryに必要
  if (a <= l && r <= b) {
    return dat.at(k);
  }
  else {
    ll vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    ll vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return min(vl, vr);//要変更
  }
}
//=================================================

//=============modpow============================
ll modpow(ll a, ll n, ll mod)
{
    ll res = 1;
    while (n > 0)
    {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}
//=================================================

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  ll N;
  cin >> N;
  vector<pll> XY;
  vector<ll> Y;
  for (ll i = 0; i < N; ++i) {
    ll x, y;
    cin >> x >> y;
    XY.push_back({x, y});
    Y.push_back(y);
  }
  sort(XY.begin(), XY.end());
  sort(Y.begin(), Y.end());
  init(N);
  vector<vector<ll>> quadrant(N, vector<ll>(4));
  for (ll i = 0; i < N; ++i) {
    ll x = XY.at(i).first, y = XY.at(i).second;
    ll index = lower_bound(Y.begin(), Y.end(), y) - Y.begin();
    ll temp = query(index, index + 1);
    quadrant.at(i).at(1) = i - temp;
    quadrant.at(i).at(2) = temp;
    update(index + 1, N);
  }

  dat = vector<ll>(2 * MAX_N - 1, 0);
  lazy = vector<ll>(2 * MAX_N - 1, 0);
  for (ll i = N - 1; i >= 0; --i) {
    ll x = XY.at(i).first, y = XY.at(i).second;
    ll index = lower_bound(Y.begin(), Y.end(), y) - Y.begin();
    ll temp = query(index, index + 1);
    quadrant.at(i).at(0) = (N - 1 - i) - temp;
    quadrant.at(i).at(3) = temp;
    update(index + 1, N);
  }
  // for (ll i = 0; i < N; ++i) {
  //   cout << quadrant.at(i).at(0) << ' ' << quadrant.at(i).at(1) << ' ' << quadrant.at(i).at(2) << ' ' << quadrant.at(i).at(3) << "\n";
  // }
  ll ans = 0;
  ll mod = 998244353;
  ans = modpow(2, N - 1, mod) * N % mod;
  for (ll i = 0; i < N; ++i) {
    vector<ll> pattern(4, 0);
    for (ll j = 0; j < 4; ++j) {
      pattern.at(j) = modpow(2, quadrant.at(i).at(j), mod) - 1;
      if (pattern.at(j) < 0) {
        pattern.at(j) += mod;
      }
    }
    ll temp = (pattern.at(0) * pattern.at(2) % mod) * modpow(2, quadrant.at(i).at(1) + quadrant.at(i).at(3), mod) % mod;
    temp = (temp + (pattern.at(1) * pattern.at(3) % mod) * modpow(2, quadrant.at(i).at(0) + quadrant.at(i).at(2), mod) % mod) % mod;
    ll sum = 1;
    for (ll j = 0; j < 4; ++j) {
      sum = (sum * pattern.at(j)) % mod;
    }
    temp -= sum;
    if (temp < 0) {
      temp += mod;
    }
    ans = (ans + temp) % mod;
    // cout << ans << "\n";
  }
  cout << ans << "\n";
}


Measured memory_bytes: 34364