Problem:
Score : 300 points

Problem Statement

There are N cities on a 2D plane. The coordinate of the i-th city is (x_i, y_i). Here (x_1, x_2, \dots, x_N) and (y_1, y_2, \dots, y_N) are both permuations of (1, 2, \dots, N).

For each k = 1,2,\dots,N, find the answer to the following question:

Rng is in City k.
Rng can perform the following move arbitrarily many times:

move to another city that has a smaller x-coordinate and a smaller y-coordinate, or a larger x-coordinate and a larger y-coordinate, than the city he is currently in.

How many cities (including City k) are reachable from City k?

Constraints

1 \leq N \leq 200,000

(x_1, x_2, \dots, x_N) is a permutation of (1, 2, \dots, N).

(y_1, y_2, \dots, y_N) is a permutation of (1, 2, \dots, N).

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_N y_N

Output

Print N lines. In i-th line print the answer to the question when k = i.

Sample Input 1

4
1 4
2 3
3 1
4 2

Sample Output 1

1
1
2
2

Rng can reach City 4 from City 3, or conversely City 3 from City 4.

Sample Input 2

7
6 4
4 3
3 5
7 1
2 7
5 2
1 6

Sample Output 2

3
3
1
1
2
3
2

Solution in C (GCC 9.2.1) (judge verdict: Runtime Error)

#include <stdio.h>
#include <stdlib.h>

static void* malloc2(size_t s) {
	void* r = malloc(s);
	if (r == NULL) {
		perror("malloc");
		exit(2);
	}
	return r;
}

struct aaaaa {
	int x, y;
	int idx;
};

int nya(const void* x, const void* y) {
	struct aaaaa a = *(const struct aaaaa*)x, b = *(const struct aaaaa*)y;
	if (a.x != b.x) return a.x < b.x ? -1 : a.x > b.x;
	if (a.y != b.y) return a.y < b.y ? -1 : a.y > b.y;
	if (a.idx < 0 && b.idx >= 0) return 1;
	if (a.idx >= 0 && b.idx < 0) return -1;
	return 0;
}

#define KI_MAX 212345

int ki[KI_MAX];

void ki_init(void) {
	int i;
	for (i = 0; i < KI_MAX; i++) {
		ki[i] = -1;
	}
}

int ki_root(int n) {
	if (ki[n] < 0) return n;
	return ki[n] = ki_root(ki[n]);
}

static int ki_size(int n) {
	return -ki[ki_root(n)];
}

static void ki_merge(int a, int b) {
	int ar = ki_root(a);
	int br = ki_root(b);
	if (ar != br) {
		int as = ki_size(ar);
		int bs = ki_size(br);
		if (as <= bs) {
			ki[br] += ki[ar];
			ki[ar] = br;
		} else {
			ki[ar] += ki[br];
			ki[br] = ar;
		}
	}
}

#define SEG_MAX (1 << 19) /* 524288 */

struct snode_t {
	int value;
	struct snode_t *left, *right;
};

struct snode_t* sadd_i(struct snode_t* node, int ss, int se, int pos, int value) {
	if (pos < ss || se <= pos) {
		return node;
	} else if (se == ss + 1) {
		struct snode_t* nnode = malloc2(sizeof(*nnode));
		nnode->value = (node != NULL ? node->value : 0) + value;
		nnode->left = NULL;
		nnode->right = NULL;
		return nnode;
	} else {
		int sm = ss + (se - ss) / 2;
		struct snode_t* nnode = malloc2(sizeof(*nnode));
		nnode->left = sadd_i(node != NULL ? node->left : NULL, ss, sm, pos, value);
		nnode->right = sadd_i(node != NULL ? node->right : NULL, sm, se, pos, value);
		nnode->value = (nnode->left == NULL ? 0 : nnode->left->value) +
			(nnode->right == NULL ? 0 : nnode->right->value);
		return nnode;
	}
}

static struct snode_t* sadd(struct snode_t* node, int pos, int value) {
	return sadd_i(node, 0, SEG_MAX, pos, value);
}

int sget_i(const struct snode_t* node, int qs, int qe, int ss, int se) {
	if (qe <= ss || se <= qs) { /* はずれ */
		return 0;
	} else if (node == NULL) { /* ゼロ */
		return 0;
	} else if (qs <= ss && se <= qe) { /* セグメントがクエリに完全に含まれる */
		return node->value;
	} else {
		int sm = ss + (se - ss) / 2;
		int left = sget_i(node->left, qs, qe, ss, sm);
		int right = sget_i(node->right, qs, qe, sm, se);
		return left + right;
	}
}

static int sget(const struct snode_t* node, int qs, int qe) {
	return qs < qe ? sget_i(node, qs, qe, 0, SEG_MAX) : 0;
}

int N;
struct aaaaa mati[212345 + 256 * 256];

int next[212345 + 256 * 256];
int N2;
int kotae[212345];
int genzan_idx[212345];

struct snode_t* ruisekiwa[212345];
struct snode_t* ruisekiwa_hit[212345];

int dc;
struct aaaaa dummy[256 * 256];

/* lu : inclusive, rd : exclusive */
static int ruisekiwa_hani(int lu_x, int lu_y, int rd_x, int rd_y) {
	return sget(ruisekiwa[lu_x], lu_y, rd_y) - sget(ruisekiwa[rd_x], lu_y, rd_y);
}

static int ruisekiwa_hani2(int cache, int lu_y, int rd_x, int rd_y) {
	return cache - sget(ruisekiwa[rd_x], lu_y, rd_y);
}

static int ruisekiwa_hit_hani(int lu_x, int lu_y, int rd_x, int rd_y) {
	return sget(ruisekiwa_hit[lu_x], lu_y, rd_y) - sget(ruisekiwa_hit[rd_x], lu_y, rd_y);
}

#define KUGYU 1000

int main(void) {
	int i;
	ki_init();
	if (scanf("%d", &N) != 1) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d%d", &mati[i].x, &mati[i].y) != 2) return 1;
		mati[i].y = (mati[i].y - 1) * 2;
		mati[i].idx = i;
	}
	qsort(mati, N, sizeof(*mati), nya);
	for (i = N - 1; i >= 0; i--) {
		ruisekiwa[i] = sadd(ruisekiwa[i + 1], mati[i].y, 1);
	}
	N2 = N;
	for (i = KUGYU; i < N; i += KUGYU) {
		int j;
		for (j = KUGYU; j < N; j += KUGYU) {
			if (ruisekiwa_hani(0, 0, i, j * 2 + 1) > 0 && ruisekiwa_hani(i, j * 2 + 1, N, N * 2) > 0) {
				mati[N2].x = i;
				mati[N2].y = j * 2 + 1;
				mati[N2].idx = -1;
				N2++;
				dummy[dc].x = i;
				dummy[dc].y = j * 2 + 1;
				dummy[dc].idx = -1;
				dc++;
			}
		}
	}
#if 0
	printf("N2 = %d, dc = %d\n", N2, dc);
#endif
	qsort(dummy, dc, sizeof(*dummy), nya);
	{
		int target = dc - 1;
		for (i = N - 1; i >= 0; i--) {
			ruisekiwa_hit[i] = ruisekiwa_hit[i + 1];
			while (target >= 0 && dummy[target].x == i) {
				ruisekiwa_hit[i] = sadd(ruisekiwa_hit[i], dummy[target].y, 1);
				target--;
			}
		}
	}

	if (N2 > N) {
		qsort(mati, N2, sizeof(*mati), nya);
		for (i = N2 - 1; i >= 0; i--) {
			ruisekiwa[i] = sadd(ruisekiwa[i + 1], mati[i].y, 1);
		}
	}
	next[N2] = N2 + 1;
	next[N2 - 1] = N2;
	for (i = N2 - 2; i >= 0; i--) {
		if (mati[i].x == mati[i + 1].x) {
			next[i] = next[i + 1];
		} else {
			next[i] = i + 1;
		}
	}
	for (i = 0; i < N2; i++) {
		int gokan = N * 2;
		for (;;) {
#if 0
			int nex = next[i];
#else
			int nex = i + 1;
#endif
			int no = nex, yes = N2 - 1;
			int cache = sget(ruisekiwa[nex], mati[i].y, gokan);
			if (ruisekiwa_hani2(cache, mati[i].y, N2, gokan) == 0) break;
			if (mati[nex].y > mati[i].y && mati[nex].y < gokan) {
				yes = nex;
			} else {
				while (no + 1 < yes) {
					int m = no + (yes - no) / 2;
					int q = ruisekiwa_hani2(cache, mati[i].y, m + 1, gokan);
					if (q > 0) yes = m; else no = m;
				}
			}
			ki_merge(i, yes);
#if 0
			printf("(%d, %d) -> (%d, %d)\n", mati[i].x, mati[i].y, mati[yes].x, mati[yes].y);
#endif
			gokan = mati[yes].y;
		}
		if (mati[i].idx >= 0) genzan_idx[mati[i].idx] = i;
	}
	for (i = 0; i < N2; i++) {
		if (mati[i].idx >= 0) {
			int ko = ki_size(i);
			ko -= ruisekiwa_hit_hani(0, 0, genzan_idx[i], mati[i].y + 1);
#if 0
			ko -= ruisekiwa_hit_hani(next[genzan_idx[i]], mati[i].y, N, N * 2);
#else
			ko -= ruisekiwa_hit_hani(genzan_idx[i] + 1, mati[i].y, N, N * 2);
#endif
			kotae[mati[i].idx] = ko;
		}
	}
	for (i = 0; i < N; i++) {
		printf("%d\n", kotae[i]);
	}
	return 0;
}

/*

左に行く → yも上に行く
より上のやつがある → 上位互換

*/

/*

↓こういうので死にそう

....*.....
...*......
..*.......
.*........
*.........
.........*
........*.
.......*..
......*...
.....*....

10
5 1
4 2
3 3
2 4
1 5
10 6
9 7
8 8
7 9
6 10

*/