#include<iostream>
using namespace std;
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<algorithm>
#define int long long int
int min_query(int tree[],int start,int end,int left,int right,int index)
{
	if(left>end||start>right)
	  return 1000000000;
	if(start>=left&&end<=right)
	  return tree[index];
	else
	{
		int mid=(start+end)/2;
		int x=min_query(tree,start,mid,left,right,2*index);
		int y=min_query(tree,mid+1,end,left,right,2*index+1);
		return min(x,y);
	}
}
int max_query(int tree[],int start,int end,int left,int right,int index)
{
	if(left>end||start>right)
	  return -1000000000;
	if(start>=left&&end<=right)
	  return tree[index];
	else
	{
		int mid=(start+end)/2;
		int x=max_query(tree,start,mid,left,right,2*index);
		int y=max_query(tree,mid+1,end,left,right,2*index+1);
		return max(x,y);
	}
}
void update(int tree[],int start,int end,int point,int pos,int index)
{
	if(point>end||point<start)
	  return ;
	if(start==end)
	{
		tree[index]=pos;
		return ;
	}
	else
	{
		int mid=(start+end)/2;
		update(tree,start,mid,point,pos,2*index);
		update(tree,mid+1,end,point,pos,2*index+1);
		tree[index]=min(tree[2*index],tree[2*index+1]);
	}
}
void dfs(int src,vector<int> adj[],vector<int> &vec,bool visited[])
{
	if(visited[src])
	  return ;
	visited[src]=true;
	vec.push_back(src);
	for(int x:adj[src])
	  dfs(x,adj,vec,visited);
}
int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n;
	cin>>n;
	int j;
	map<int,int> mp;
	map<pair<int,int>,int> pos;
	for(j=0;j<n;j++)
	{
		int x,y;
		cin>>x>>y;
		x--;
		y--;
		mp.insert({x,y});
		pos[{x,y}]=j;
	}
	int arr1[n],arr2[n];
	int ptr=0;
	for(auto p:mp)
	{
		int x=p.first;
		int y=p.second;
		arr1[ptr]=x;
		arr2[ptr]=y;
		ptr++;
	}
	int position[n];
	for(j=0;j<n;j++)
	{
		int x=arr1[j],y=arr2[j];
		int val=pos[{x,y}];
		position[j]=val;
	}
	int tree1[4*n+1];
	for(j=0;j<=4*n;j++)
	{
		tree1[j]=100000000;
	}
	vector<int> adj[n+1];
	for(j=n-1;j>=0;j--)
	{
		int y=arr2[j];
		int index=min_query(tree1,0,n-1,y+1,n-1,1);
		if(index<=n-1)
		{
			int u=position[j];
			int v=position[index];
			adj[u].push_back(v);
			adj[v].push_back(u);
		}
		update(tree1,0,n-1,y,j,1);
	}
	for(j=0;j<=4*n;j++)
	{
		tree1[j]=-1;
	}
	for(j=n-1;j>=0;j--)
	{
		int y=arr2[j];
		int index=max_query(tree1,0,n-1,y+1,n-1,1);
		if(index>=0)
		{
			int u=position[j];
			int v=position[index];
			adj[u].push_back(v);
			adj[v].push_back(u);
		}
		update(tree1,0,n-1,y,j,1);
	}
	int tree2[4*n+1];
	for(j=0;j<=4*n;j++)
	  tree2[j]=-1;
	for(j=0;j<n;j++)
	{
		int y=arr2[j];
		int index=max_query(tree2,0,n-1,0,y-1,1);
		if(index>=0)
		{
			int u=position[j];
			int v=position[index];
			adj[u].push_back(v);
			adj[v].push_back(u);
		}
		update(tree2,0,n-1,y,j,1);
	}
	for(j=0;j<=4*n;j++)
	  tree2[j]=1000000000;
	for(j=0;j<n;j++)
	{
		int y=arr2[j];
		int index=min_query(tree2,0,n-1,0,y-1,1);
		if(index<=n-1)
		{
			int u=position[j];
			int v=position[index];
			adj[u].push_back(v);
			adj[v].push_back(u);
		}
		update(tree2,0,n-1,y,j,1);
	}
	bool visited[n]={false};
	int answer[n]={0};
	for(j=0;j<n;j++)
	{
		if(!visited[j])
		{
			vector<int> vec;
			dfs(j,adj,vec,visited);
			for(int x:vec)
			{
				answer[x]=vec.size();
			}
		}
	}
	for(j=0;j<n;j++)
	{
		cout<<answer[j]<<endl;
	}
	cout<<endl;
}


Measured memory_bytes: 77524