CSES - Shared codeLink to this code: https://cses.fi/paste/ab15a9545c0ffe8e2825be/
#include <bits/stdc++.h>
using namespace std;

#define ms(s,n) memset(s,n,sizeof(s))
#define all(a) a.begin(),a.end()
#define present(t, x) (t.find(x) != t.end())
#define sz(a) int((a).size())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define mp make_pair
#define endl "\n"

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;

const int MOD = (int) 1e9+7;
const int INF = (int) 1e9+1;
inline ll gcd(ll a,ll b){ll r;while(b){r=a%b;a=b;b=r;}return a;}
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}

bool cmp(pair<pi,int> a, pair<pi,int> b){
	if(a.fi.fi != b.fi.fi)
		return a.fi.fi < b.fi.fi;
	return a.fi.se > b.fi.se;
}

vector<int> BIT(200001);

void update(int n, int idx, int value){
	while(idx <= n){
		BIT[idx] += value;
		idx += idx & -idx;
	}
}

int query(int idx){
	int sum = 0;
	while(idx > 0){
		sum += BIT[idx];
		idx -= idx & -idx;
	}
	return sum;
}

int sum(int l, int r){
	return query(r) - query(l - 1);
}

int main(){
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	#endif
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n;
	cin >> n;
	pair<pi,int> a[n];
	set<int> se;
	map<int,int> mp;
	for(int i = 0; i < n; i++){
		cin >> a[i].fi.fi >> a[i].fi.se;
		a[i].se = i;
		se.insert(a[i].fi.se);
	}
	//dùng map để lưu chỉ số các điểm kết thúc của tất cả các đoạn
	int cnt = 0;
	for(int x : se){
		mp[x] = ++cnt;
	}
	int chua[n]={0}, bichua[n]={0};
	//Sắp xếp các đoạn theo thứ tự x tăng dần, nếu 2 đoạn có cùng x
	//thì sắp xếp y giảm dần
	sort(a, a + n, cmp);
	BIT.assign(n+1, 0);
	//Đoạn cuối cùng sẽ không chứa đoạn nào khác nên ko cần xét
	update(cnt, mp[a[n - 1].fi.se], 1);
	for(int i = n - 2; i >= 0; i--){
		//Tổng số đoạn mà đoạn hiện tại chứa sẽ bằng tổng
		//số lượng đoạn con có y <= y của đoạn hiện tại (a[i].fi.se)
		//giá trị này có được bằng thao tác query, ta không cần xét điểm bắt đầu x
		//của mỗi đoạn nữa vì nó đã sắp tăng dần rồi.
		chua[a[i].se] = query(mp[a[i].fi.se]);
		update(cnt, mp[a[i].fi.se], 1);
	}
	BIT.assign(n+1, 0);
	//Đoạn đầu tiên sẽ không thể bị chứa
	update(cnt, mp[a[0].fi.se], 1);
	for(int i = 1; i < n; i++){
		//Số lượng đoạn mà chứa đoạn hiện tại sẽ bằng tổng số
		//đoạn có con kết thúc là y >= kết thúc của đoạn hiện tại
		bichua[a[i].se] = sum(mp[a[i].fi.se], cnt);
		update(cnt, mp[a[i].fi.se], 1);
	}
	for(int x : chua){
		cout << x << " ";
	}
	cout << endl;
	for(int x : bichua){
		cout << x << " ";
	}

}