#include using namespace std; using ll = long long;//int型は使わない using pll = pair; using vl = vector ; //1D using vvl = vector ;//2D using vvvl = vector ;//3D using vvvvl = vector;//4D using vvvvvl = vector;//5D using vvvvvvl = vector;//6D using vvvvvvvl = vector;//7D using vp = vector ; //1D using vvp = vector ;//2D using vvvp = vector ;//3D using vvvvp = vector;//4D using vvvvvp = vector;//5D using vvvvvvp = vector;//6D using vvvvvvvp = vector;//7D using vi = vector ; //1D using vvi = vector ;//2D using vvvi = vector ;//3D using vvvvi = vector;//4D using vvvvvi = vector;//5D using vvvvvvi = vector;//6D using vvvvvvvi = vector;//7D using vb = vector ; //1D using vvb = vector ;//2D using vvvb = vector ;//3D using vvvvb = vector;//4D using vvvvvb = vector;//5D using vvvvvvb = vector;//6D using vvvvvvvb = vector;//7D using vs = vector ; //1D using vvs = vector ;//2D using vvvs = vector ;//3D using vvvvs = vector;//4D using vvvvvs = vector;//5D using vvvvvvs = vector;//6D using vvvvvvvs = vector;//7D [[maybe_unused]] const ll INF = 2e18 ; [[maybe_unused]] const ll MOD = 998244353; #define rep(i,a,b) for(ll i=(ll)a; i<(ll)b; i++) #define rrep(i,a,b) for(ll i=(ll)b-1; i>=(ll)a; i--) #define all(vec1) (vec1).begin(), (vec1).end() #define yn(b,ex) if(1){if(b)cout << "Yes" << endl;else cout << "No" << endl ;if(ex)return 0;} #define debug(var) cerr << #var << " : " << var << endl; //fastio struct FastIO { FastIO() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); } } fastio; //あまり(負の数対応) template T ovr(T a,T b){ T ret=a%b; if(ret<0)ret+=b; return ret; } const string MOD_bi = "111111111111111111111110110111"; //MOD下での逆元 ll minv(ll ina){ ll a = ina % MOD; ll ret = 1; ll V = a; rep(i,0,MOD_bi.size()){ if(MOD_bi[i]=='1')ret=(ret*V)%MOD; V=(V*V)%MOD; } return ret; } //指数をある値で割った余り ll mpow(ll a , ll b , ll M){ ll ret = 1; ll V = a; rep(i,0,64){ if((b >> i) & 1)ret=(ret*V)%M; V=(V*V)%M; } return ret; } template bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } return 0; } template bool chmin(T &a, T b) { if (a > b) { a = b; return 1; } return 0; } /////////main///////// #include #include using namespace atcoder; using mint = modint998244353; using S = pair; // a * (1 - b) S op(S a, S b) { return {a.first * (1 - a.second) + b.first * (1 - b.second), 0}; } S e() { return {1, 1}; } using F = mint; S mapping (F f, S x) { x.first *= f; return x; } F composition(F f, F g) { return f * g; } F id() { return mint(1); } int main() { mint f34 = mint(3) / mint(4); mint f43 = 1 / f34; int N; cin >> N; vl X(N), Y(N); rep(i,0,N) cin >> X[i] >> Y[i]; vl zX = X, zY = Y; sort(all(zX)), sort(all(zY)); zX.erase(unique(all(zX)), zX.end()); zY.erase(unique(all(zY)), zY.end()); vl rX(N), rY(N); rep(i,0,N) rX[i] = lower_bound(all(zX), X[i]) - zX.begin(); rep(i,0,N) rY[i] = lower_bound(all(zY), Y[i]) - zY.begin(); if (zX.size() == 1 || zY.size() == 1) { cout << 0 << endl; return 0; } mint ans = 0; rep(_,0,2) { vvl G(zX.size()); rep(i,0,N) G[rX[i]].push_back(rY[i]); // seg木の初期化 vector V(zY.size(), e()); rep(i,0,N) if (rY[i] + 1 < zY.size()) V[rY[i] + 1].first *= f34; rep(i,1,zY.size()) V[i].first *= V[i-1].first; lazy_segtree seg(V); mint fs = 1; rep(i,0,zX.size()-1) { for (auto y : G[i]) { seg.set(y, {seg.get(y).first, seg.get(y).second * f34}); seg.apply(0, y, f34); seg.apply(y + 1, zY.size(), f43); fs *= f34; } auto all_prd = seg.all_prod(); ans += (mint(1) - all_prd.first * (1 - all_prd.second) - fs) * (zX[i + 1] - zX[i]); } swap(rX, rY); swap(zX, zY); } rep(i,0,N) ans *= 4; cout << (ans * 2).val() << endl; return 0; }