This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define forn(i, n) for(int i=0; i<(int)n; ++i)
#define dforn(i, n) for(int i=n-1; i>=0; --i)
#define PB push_back
const int MAXN=1000010, INF=1000000000;
int n, arr[MAXN], brr[MAXN], rle[MAXN], rri[MAXN], d[MAXN], key[MAXN], lans;
vector<int> anti[MAXN];
vector<vector<int>> ret;
void lis(int* arg, int* res){
    forn(i, n+1) d[i]=INF;
    d[0]=-INF;
    forn(i, n){
        auto itr = upper_bound(d, d+n+1, arg[i]);
        res[i]=itr-d;
        *itr=arg[i];        
    }
}
bool drop(int pos){
    bool flag=false, touched=true;
    while(touched && !anti[pos].empty() && !anti[pos+1].empty()){
        touched=false;
        if(anti[pos].back() > anti[pos+1].back()){
            touched=flag=true;
            anti[pos].pop_back();
        }
        if(arr[anti[pos].back()] > arr[anti[pos+1].back()]){
            touched=flag=true;
            anti[pos+1].pop_back();
        }
    }
    if(pos && flag) drop(pos-1);
    return flag;
}
int main(){
    scanf("%d", &n);
    forn(i, n) scanf("%d", &arr[i]), brr[n-1-i]=n-arr[i];
    lis(arr, rle);    
    lis(brr, rri);
    forn(i, n) lans=max(lans, rle[i]);
    forn(i, n) key[i]= (rle[i] + rri[n-1-i] == lans+1)? rle[i] : -1;
    forn(i, n) if(key[i]!=-1) anti[key[i]-1].PB(i);
    
    while(true){
        vector<int> add;
        forn(i, lans){
            add.PB(anti[i].back());
            anti[i].pop_back();
        }
        ret.PB(add);
        forn(i, lans-1) while(drop(i));
        forn(i, lans) if(anti[i].empty()) goto end;
    }
    end:
    printf("%d %d\n", (int)ret.size(), lans);
    for(auto vec:ret){
        for(auto el:vec) printf("%d ", el+1);
        printf("\n");
    }
}
Compilation message (stderr)
Main.cpp: In function 'int main()':
Main.cpp:42:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   42 |     scanf("%d", &n);
      |     ~~~~~^~~~~~~~~~
Main.cpp:43:21: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   43 |     forn(i, n) scanf("%d", &arr[i]), brr[n-1-i]=n-arr[i];
      |                ~~~~~^~~~~~~~~~~~~~~| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |