<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

99. Beautiful People
time limit per test: 0.25 sec.
memory limit per test: 65536 KB
input: standard
output: standard



The most prestigious sports club in one city has exactly N members. Each of its members is strong and beautiful. More precisely, i-th member of this club (members being numbered by the time they entered the club) has strength Si and beauty Bi . Since this is a very prestigious club, its members are very rich and therefore extraordinary people, so they often extremely hate each other. Strictly speaking, i-th member of the club Mr X hates j-th member of the club Mr Y if Si ≤ Sj and Bi ≥ Bj or if Si ≥ Sj and Bi ≤ Bj (if both properties of Mr X are greater then corresponding properties of Mr Y, he doesn't even notice him, on the other hand, if both of his properties are less, he respects Mr Y very much).

To celebrate a new 2003 year, the administration of the club is planning to organize a party. However they are afraid that if two people who hate each other would simultaneouly attend the party, after a drink or two they would start a fight. So no two people who hate each other should be invited. On the other hand, to keep the club presti≥ at the apropriate level, administration wants to invite as many people as possible.

Being the only one among administration who is not afraid of touching a computer, you are to write a program which would find out whom to invite to the party.

Input

The first line of the input file contains integer N — the number of members of the club. ( 2 ≤ N ≤ 100,000 ). Next N lines contain two numbers each — Si and Bi respectively ( 1 ≤ Si, Bi ≤ 109 ).

Output

On the first line of the output file print the maximum number of the people that can be invited to the party. On the second line output N integers — numbers of members to be invited in arbitrary order. If several solutions exist, output any one.

Sample test(s)

Input

4
1 1
1 2
2 1
2 2

Output

2
1 4
Author:	Andrew Stankevich
Resource:	Petrozavodsk Winter Trainings 2003
Date:	2003-02-06

<|response|>
1. Abridged Problem Statement  
You have N club members, each described by strength Si and beauty Bi. Two members hate each other if one is at least as strong but not more beautiful, or at least as beautiful but not more strong. You must select the largest possible subset with no hateful pair. Output its size and any valid set of original indices.

2. Key Observations  
- A hateful pair corresponds to an “inversion” in the two attributes: one member has higher strength but lower beauty (or vice versa).  
- To avoid any hate, within the invited subset both strength and beauty must strictly increase from one member to the next.  
- Finding the largest such subset is exactly finding a maximum-length chain in the partial order (Si < Sj and Bi < Bj).  
- By sorting members by strength ascending (and for equal strength by beauty descending), the problem reduces to finding a Longest Increasing Subsequence (LIS) on the beauty values.

3. Full Solution Approach  
a. Read N and the list of triples (Si, Bi, originalIndex).  
b. Sort the list by  
   - primary key: strength ascending  
   - secondary key: beauty descending  
  This ensures that for members with equal strength you cannot take more than one (because beauties go down).  
c. Extract the beauty array in sorted order.  
d. Compute the LIS on this beauty array in O(N log N) using the “patience sorting” method with a tail array and binary search:  
   - Maintain an array tail[], where tail[len] is the minimum possible ending beauty of an increasing subsequence of length len+1.  
   - For each beauty b at index i, find the insertion position pos = lower_bound(tail, b).  
   - Record pos as the LIS‐length index for element i.  
   - If pos equals current LIS length, append b to tail; otherwise overwrite tail[pos] = b.  
   - Maintain two auxiliary arrays:  
     • prev[i] = index of the previous element in the LIS ending at i (for reconstruction)  
     • tailIndex[len] = the index i at which an LIS of length len+1 currently ends  
e. After processing all members, the length of tail[] is the maximum invite count.  
f. Reconstruct one LIS by starting from tailIndex[last] and following prev[] pointers backward. Reverse the collected indices.  
g. Print the LIS length and the list of original indices.

4. C++ Implementation with Detailed Comments  
```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    // a[i] = {strength, beauty, originalIndex}
    vector<array<int,3>> a(N);
    for (int i = 0; i < N; i++) {
        cin >> a[i][0] >> a[i][1];
        a[i][2] = i + 1;  // store 1-based index
    }

    // Sort by strength ↑, and for equal strength by beauty ↓
    sort(a.begin(), a.end(), [](auto &A, auto &B) {
        if (A[0] != B[0]) 
            return A[0] < B[0];
        return A[1] > B[1];
    });

    // tailBeauty[len] = minimum possible ending beauty of an inc. subseq of length len+1
    vector<int> tailBeauty;
    // tailIndex[len] = index in 'a' where that subsequence currently ends
    vector<int> tailIndex;
    // prevIdx[i] = predecessor index in 'a' for reconstruction of the LIS ending at i
    vector<int> prevIdx(N, -1);

    for (int i = 0; i < N; i++) {
        int b = a[i][1];
        // Find where to place b in tailBeauty: lower_bound for strict increase
        auto it = lower_bound(tailBeauty.begin(), tailBeauty.end(), b);
        int len = int(it - tailBeauty.begin());  // length index

        if (it == tailBeauty.end()) {
            // Extend the LIS by one
            tailBeauty.push_back(b);
            tailIndex.push_back(i);
        } else {
            // Replace to keep the tail as small as possible
            *it = b;
            tailIndex[len] = i;
        }

        // Set predecessor for reconstruction
        if (len > 0) {
            prevIdx[i] = tailIndex[len - 1];
        }
        // if len == 0, prevIdx[i] stays -1
    }

    int lisLen = (int)tailBeauty.size();
    vector<int> answer;
    answer.reserve(lisLen);

    // Reconstruct LIS: start from last element of the LIS
    int idx = tailIndex[lisLen - 1];
    while (idx != -1) {
        answer.push_back(a[idx][2]);  // original index
        idx = prevIdx[idx];
    }
    // We built it backwards
    reverse(answer.begin(), answer.end());

    // Output result
    cout << lisLen << "\n";
    for (int x : answer) {
        cout << x << " ";
    }
    cout << "\n";

    return 0;
}
```

5. Python Implementation with Detailed Comments  
```python
import sys
import bisect

def main():
    input = sys.stdin.readline
    N = int(input())

    # Read members as (strength, beauty, original_index)
    members = []
    for i in range(N):
        s, b = map(int, input().split())
        members.append((s, b, i + 1))

    # Sort by strength ascending, beauty descending on ties
    members.sort(key=lambda x: (x[0], -x[1]))

    # tailBeauty will store the tail values of increasing subsequences
    tailBeauty = []
    # tailIndex[len] = index in members where an LIS of length len+1 ends
    tailIndex = []
    # prevIdx[i] = predecessor index in members for reconstructing the LIS ending at i
    prevIdx = [-1] * N

    for i, (s, b, orig) in enumerate(members):
        # Find insertion point for b
        pos = bisect.bisect_left(tailBeauty, b)
        if pos == len(tailBeauty):
            # extend tailBeauty and record this end-index
            tailBeauty.append(b)
            tailIndex.append(i)
        else:
            # replace to keep the smallest possible tail
            tailBeauty[pos] = b
            tailIndex[pos] = i

        # link to the previous element in the LIS of length pos
        if pos > 0:
            prevIdx[i] = tailIndex[pos - 1]

    lisLen = len(tailBeauty)
    result = []
    # start reconstruction from the last element of the LIS
    idx = tailIndex[lisLen - 1]
    while idx != -1:
        # collect original index
        result.append(members[idx][2])
        idx = prevIdx[idx]

    # reverse to get correct order
    result.reverse()

    # Output
    print(lisLen)
    print(*result)

if __name__ == "__main__":
    main()
```