#include <bits/stdc++.h>
using namespace std;
struct BST {
struct Node {
int key;
int val;
int min_key = key;
int max_key = key;
int max_val = val;
int size = 1;
int height = 1;
Node* left = nullptr;
Node* right = nullptr;
static int get_min_key(Node* node) {
if (node == nullptr) {
return INT_MAX;
}
return node->min_key;
}
static int get_max_key(Node* node) {
if (node == nullptr) {
return INT_MIN;
}
return node->max_key;
}
static int get_max_val(Node* node) {
if (node == nullptr) {
return INT_MIN;
}
return node->max_val;
}
static int get_size(Node* node) {
if (node == nullptr) {
return 0;
}
return node->size;
}
static int get_height(Node* node) {
if (node == nullptr) {
return 0;
}
return node->height;
}
static void update(Node* node) {
node->min_key = min(node->key, min(get_min_key(node->left), get_min_key(node->right)));
node->max_key = max(node->key, max(get_max_key(node->left), get_max_key(node->right)));
node->max_val = max(node->val, max(get_max_val(node->left), get_max_val(node->right)));
node->size = 1 + get_size(node->left) + get_size(node->right);
node->height = 1 + max(get_height(node->left), get_height(node->right));
}
static void rotate_left(Node*& node) {
Node* temp = node->right;
node->right = temp->left;
temp->left = node;
node = temp;
}
static void rotate_right(Node*& node) {
Node* temp = node->left;
node->left = temp->right;
temp->right = node;
node = temp;
}
static bool insert(Node*& node, int key, int val) {
if (node == nullptr) {
node = new Node(key, val);
return true;
}
bool inserted;
if (key < node->key) {
inserted = insert(node->left, key, val);
}
else if (key > node->key) {
inserted = insert(node->right, key, val);
}
else {
inserted = false;
}
if (inserted) {
int hl = get_height(node->left);
int hr = get_height(node->right);
if (hr - hl > 1) {
rotate_left(node);
update(node->left);
}
else if (hl - hr > 1) {
rotate_right(node);
update(node->right);
}
update(node);
}
return inserted;
}
static Node* lower_bound(Node* node, int key) {
Node* result = nullptr;
while (node != nullptr) {
if (node->key >= key) {
result = node;
node = node->left;
} else {
node = node->right;
}
}
return result;
}
static Node* upper_bound(Node* node, int key) {
Node* result = nullptr;
while (node != nullptr) {
if (node->key > key) {
result = node;
node = node->left;
} else {
node = node->right;
}
}
return result;
}
static int range_max(Node* node, int l, int h) {
if (node == nullptr) {
return INT_MIN;
}
if (node->max_key < l || node->min_key > h) {
return INT_MIN;
}
if (node->min_key >= l && node->max_key <= h) {
return node->max_val;
}
int result = max(range_max(node->left, l, h), range_max(node->right, l, h));
if (node->key >= l && node->key <= h) {
result = max(result, node->val);
}
return result;
}
};
Node* root = nullptr;
bool insert(int key, int val) {
return Node::insert(root, key, val);
}
Node* lower_bound(int key) {
return Node::lower_bound(root, key);
}
Node* upper_bound(int key) {
return Node::upper_bound(root, key);
}
int range_max(int min_key, int max_key) {
return Node::range_max(root, min_key, max_key);
}
};
BST s[4000005];
void insert(int i,int l,int r,int x,int y,int v){
if(l>x||r<x){
return;
}
s[i].insert(y,v);
if(l==r){
return;
}
insert(i*2+1,l,(l+r)/2,x,y,v);
insert(i*2+2,(l+r)/2+1,r,x,y,v);
}
int query_max(int i,int l,int r,int x0,int y0,int x1,int y1){
if(l>x1||r<x0){
return 0;
}
if(l>=x0&&r<=x1){
return s[i].range_max(y0,y1);
}
int ans1=query_max(i*2+1,l,(l+r)/2,x0,y0,x1,y1);
int ans2=query_max(i*2+2,(l+r)/2+1,r,x0,y0,x1,y1);
return max(ans1,ans2);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
#ifdef CB
freopen("be2.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
int N;
cin>>N;
vector<int>r(N),a(N);
for(int i=0;i<N;i++){
cin>>r[i]>>a[i];
}
int ans=0;
for(int i=0;i<N;i++){
int v=query_max(0,1,1000000,1,1,r[i]-1,a[i]-1)+1;
insert(0,1,1000000,r[i],a[i],v);
ans=max(ans,v);
}
cout<<ans<<'\n';
return 0;
}