#include <bits/stdc++.h>

#define fst(t) std::get<0>(t)
#define snd(t) std::get<1>(t)
#define thd(t) std::get<2>(t)
#define unless(p) if(!(p))
#define until(p) while(!(p))

using ll = std::int64_t;
using P = std::tuple<int,int>;

template <typename T>
T mod_expt(T a, std::int64_t n, T mod){
    T power {1};
    while(n > 0){
        if(n & 1){power = power * a % mod;}
        a = a * a % mod;
        n >>= 1;
    }
    return power;
}

template <typename M>
struct SegmentTree{
    using T = typename M::type;

    int numLeaves;
    std::vector<T> data;
    
    SegmentTree(int n){
        numLeaves = 1;
        while(numLeaves < n){
            numLeaves *= 2;
        }
        
        data.resize(numLeaves * 2);
        std::fill(data.begin() + numLeaves, data.end(), M::identity());
        
        for(int i=numLeaves-1;i>0;--i){
            data[i] = M::bop(data[i*2], data[i*2+1]);
        }
    }

    template <typename F>
    SegmentTree(int n, F f){
        numLeaves = 1;
        while(numLeaves < n){
            numLeaves *= 2;
        }

        data.resize(numLeaves * 2);
        for(int i=0;i<n;++i){
            data[i + numLeaves] = std::move(f(i));
        }
        std::fill(data.begin() + numLeaves + n, data.end(), M::identity());

        for(int i=numLeaves-1;i>0;--i){
            data[i] = M::bop(data[i*2], data[i*2+1]);
        }
    }

    void set(int k, T v){
        k += numLeaves;
        data[k] = v;
        
        while(k > 1){
            k /= 2;
            data[k] = M::bop(data[k*2], data[k*2+1]);
        }
    }
    
    T product(int l, int r){
        l += numLeaves;
        r += numLeaves;
        
        T pl = M::identity(), pr = M::identity();
        for(;l<r;l/=2,r/=2){
            if(l & 1){
                pl = M::bop(pl, data[l]);
                l += 1;
            }
            if(r & 1){
                r -= 1;
                pr = M::bop(data[r], pr);
            }
        }
        
        return M::bop(pl, pr);
    }
    
    T at(int i){
        return data[i + numLeaves];
    }
};

struct M{
    using type = int;
    static type identity(){
        return 0;
    }
    static type bop(type &m1, type &m2){
        return m1 + m2;
    }
};

constexpr ll MOD = 998244353;
int N;
P ps[200100];
std::vector<int> ys;
SegmentTree<M> seg1(200100), seg2(200100);

int main(){
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  std::cin >> N;

  for(int i=0;i<N;++i){
      int x, y;
      std::cin >> x >> y;
      
      ps[i] = std::make_tuple(x, y);
      ys.emplace_back(y);
  }

  std::sort(ps, ps + N);

  std::sort(ys.begin(), ys.end());

  for(int i=0;i<N;++i){
      snd(ps[i]) = std::lower_bound(ys.begin(), ys.end(), snd(ps[i])) - ys.begin();
  }

  for(int i=0;i<N;++i){
      seg2.set(i, 1);
  }

  ll res = 0;

  for(int i=0,j=0;i<N;){
      for(int k=i;k<j;++k){
          int y = snd(ps[k]);
          int a = seg1.product(0, y), b = seg1.product(y + 1, N),
              c = seg2.product(0, y), d = seg2.product(y + 1, N);
          ll x = 1;          

          x += mod_expt<ll>(2, a, MOD) - 1;
          x += mod_expt<ll>(2, b, MOD) - 1;
          x += mod_expt<ll>(2, c, MOD) - 1;
          x += mod_expt<ll>(2, d, MOD) - 1;
          x += (mod_expt<ll>(2, a, MOD) - 1) * (mod_expt<ll>(2, b, MOD) - 1) % MOD;
          x += (mod_expt<ll>(2, b, MOD) - 1) * (mod_expt<ll>(2, d, MOD) - 1) % MOD;
          x += (mod_expt<ll>(2, d, MOD) - 1) * (mod_expt<ll>(2, c, MOD) - 1) % MOD;
          x += (mod_expt<ll>(2, c, MOD) - 1) * (mod_expt<ll>(2, a, MOD) - 1) % MOD;
          x = (mod_expt<ll>(2, N, MOD) - x) % MOD;
          if(x < 0){
              x += MOD;
          }

          res += x;
      }

      while(i < j){
          int y = snd(ps[i]);
          seg1.set(y, 1);
          i += 1;
      }

      while(j < N && fst(ps[j]) == fst(ps[i])){
          int y = snd(ps[j]);
          seg2.set(y, 0);
          j += 1;
      }
  }

  res %= MOD;

  std::cout << res << std::endl;
}


Measured memory_bytes: 6900