macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}
macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}
macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => { ( $(read_value!($iter, $t)),* ) };
    ($iter:expr, [ $t:tt ; $len:expr ]) => { (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>() };
    ($iter:expr, chars) => { read_value!($iter, String).chars().collect::<Vec<char>>() };
    ($iter:expr, usize1) => { read_value!($iter, usize) - 1 };
    ($iter:expr, $t:ty) => { $iter.next().unwrap().parse::<$t>().expect("Parse error") };
}

static MOD: u64 = 998244353;
use std::ops::*;
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default)]
struct Mint(u64);
impl Mint {
    pub fn value(&self) -> u64 { self.0 }
    pub fn zero() -> Mint { Mint(0) }
    pub fn from(n: u64) -> Mint { Mint(n % MOD) }
    pub fn pow(&self, mut n: u64) -> Mint {
        let mut v = 1;
        let mut a = self.0;
        while n > 0 {
            if n & 1 != 0 {
                v *= a;
                v %= MOD;
            }
            a *= a;
            a %= MOD;
            n >>= 1;
        }
        Mint(v)
    }
}
impl AddAssign for Mint {
    fn add_assign(&mut self, rhs: Mint) {
        self.0 += rhs.0;
        if self.0 >= MOD { self.0 -= MOD }
    }
}
impl Sub<u64> for Mint {
    type Output = Mint;
    fn sub(self, rhs: u64) -> Mint {
        let v = rhs % MOD;
        let mut v = self.0 + MOD - v;
        if v >= MOD { v -= MOD }
        Mint(v)
    }
}
impl SubAssign for Mint {
    fn sub_assign(&mut self, other: Mint) {
        self.0 += MOD - other.0;
        if self.0 >= MOD { self.0 -= MOD }
    }
}
impl Mul for Mint {
    type Output = Mint;
    fn mul(self, rhs: Mint) -> Mint { Mint(self.0 * rhs.0 % MOD) }
}

struct Bit<T>(Vec<T>);
impl<T: Default + Copy + ::std::ops::AddAssign> Bit<T> {
    pub fn new(n: usize) -> Bit<T> {
        Bit(vec![Default::default(); n + 1])
    }
    pub fn inc(&mut self, mut i: usize, val: T) {
        i += 1;
        while i < self.0.len() {
            self.0[i] += val;
            i += Bit::<T>::low(i);
        }
    }
    pub fn sum(&self, mut i: usize) -> T {
        i += 1;
        let mut v = T::default();
        while i > 0 {
            v += self.0[i];
            i -= Bit::<T>::low(i);
        }
        v
    }
    fn low(n: usize) -> usize {
        let n = n as isize;
        let n = n & -n;
        n as usize
    }
}

use std::hash::Hash;
fn compress<T: Copy + Ord + Hash, I: Iterator<Item=T>>(iter: I) -> HashMap<T, usize> {
    let mut vec: Vec<T> = iter.collect();
    vec.sort();
    vec.iter().cloned().enumerate().map(|(k, v)| (v, k)).collect()
}

use std::collections::*;
fn main() {
    input! {
        n: usize,
        ps: [(i32, i32); n]
    }
    let mut ps = ps;
    // let map_x = compress(ps.iter().map(|&(x, _)| x));
    let map_y = compress(ps.iter().map(|&(_, y)| y));

    ps.sort();
    let left = {
        let mut left = vec![];
        let mut bit: Bit<usize> = Bit::new(n);
        for (i, &(_, y)) in ps.iter().enumerate() {
            let y: usize = map_y[&y];
            let up = bit.sum(y);
            left.push((up, i - up));
            bit.inc(y, 1);
        }
        left
    };
    let right = {
        let mut right = vec![];
        let mut bit: Bit<usize> = Bit::new(n);
        for (i, &(_, y)) in ps.iter().rev().enumerate() {
            let y: usize = map_y[&y];
            let up = bit.sum(y);
            // assert!(i >= up, "{} >= {}", i, up);
            right.push((up, i - up));
            bit.inc(y, 1);
        }
        right.reverse();
        right
    };

    let mut sum: Mint = Mint::zero();
    for i in 0..n {
        let (lu, ld) = left[i];
        let (ru, rd) = right[i];

        let luc = Mint::from(2).pow(lu as u64);
        let ldc = Mint::from(2).pow(ld as u64);
        let ruc = Mint::from(2).pow(ru as u64);
        let rdc = Mint::from(2).pow(rd as u64);
        sum += luc * (ldc - 1) * (ruc - 1) * rdc;
        sum += (luc - 1) * ldc * ruc * (rdc - 1);
        sum -= (luc - 1) * (ldc - 1) * (ruc - 1) * (rdc - 1);
        sum += luc * ldc * ruc * rdc;
    }
    println!("{}", sum.value());
}



Measured memory_bytes: 26908