//Memory 1528K Time 188MS
#include <bits/stdc++.h>
using namespace std;
struct Node {
int x, y;//开始时间,结束时间
int id;
//优先队列的优先级设置
//根据结束时间的先后调整
//结束时间早的在前面
//结束时间相同,在根据开始时间从小到大调整
bool operator<(const Node &obj) const {
if (y != obj.y)
return y > obj.y;
else
return x > obj.x;
}
} node[50010];
//排序
//根据开始时间从小到大排序,若开始时间相等,根据结束时间从小到大排序
bool cmp(Node a, Node b) {
if (a.x != b.x)
return a.x < b.x;
else
return a.y < b.y;
}
int n, *result;//牛的数量,记录结果的数组
int operation() {
priority_queue<Node> pq;
sort(node, node + n, cmp);
//默认将刚开始优先队列的队首数据作为第一个蓄栏序号
int count = 1;//蓄栏个数
pq.push(node[0]);
result[node[0].id] = 1;
//遍历每只牛
for (int i = 1; i < n; i++) {
//当前牛和队首数据存放在同一个蓄栏
//当前牛的开始时间大于队首数据的结束时间
if (!pq.empty() && node[i].x > pq.top().y)
result[node[i].id] = result[pq.top().id], pq.pop();
else//当前牛的开始时间小于队首数据的结束时间
//存放在下一个蓄栏
result[node[i].id] = ++count;
pq.push(node[i]);
}
return count;
}
int main() {
//录入牛的数量
while (~scanf("%d", &n)) {
//初始化
result = new int[n];
memset(result, 0, sizeof(result));
//录入节点信息
for (int i = 0; i < n; i++)
scanf("%d%d", &node[i].x, &node[i].y), node[i].id = i;
//打印最少需要的蓄栏数目
printf("%d\n", operation());
//打印每头牛分配到的蓄栏序号
for (int i = 0; i < n; i++)
printf("%d\n", result[i]);
//释放内存
delete[] result;
}
return 0;
}