#include <bits/stdc++.h>   using namespace std;   const int di[] = {-1, 0, 1, 0};   const int dj[] = {0, 1, 0, -1};   const long long MOD = 1e9 + 7;   const long long INF = 1e9;   const double EPS = 1e-11;   class UnionFind {    private:     vector<long long> p, rank, setSize;     int numSets;       public:     UnionFind(int N) {       setSize.assign(N, 1);       numSets = N;       rank.assign(N, 0);       p.assign(N, 0);       for (int i = 0; i < N; i++) p[i] = i;     }     int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }     bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }     void unionSet(int i, int j) {       if (!isSameSet(i, j)) {         numSets--;         int x = findSet(i), y = findSet(j);         if (rank[x] > rank[y]) {           p[y] = x;           setSize[x] += setSize[y];         } else {           p[x] = y;           setSize[y] += setSize[x];           if (rank[x] == rank[y]) rank[y]++;         }       }     }     int numDisjointSets() { return numSets; }     int sizeOfSet(int i) { return setSize[findSet(i)]; }   };   int main() {     ios::sync_with_stdio(false), cin.tie(0);     int n;     cin >> n;     vector<long long> num(n);     map<int, int> idx, vis;     for (int i = 0; i < n; ++i) cin >> num[i], idx[num[i]] = i;     vector<long long> num2 = num;     sort(num2.begin(), num2.end());     UnionFind dsu(n);     for (int i = 0; i < n; ++i) {       swap(num[i], num[idx[num2[i]]]);       dsu.unionSet(i, idx[num2[i]]);     }     for (int i = 0; i < n; ++i) num[i] = dsu.findSet(i);     map<int, vector<long long> > r;     for (int i = 0; i < n; ++i) r[num[i]].push_back(i + 1);     cout << r.size() << endl;     for (map<int, vector<long long> >::iterator i = r.begin(); i != r.end();          ++i) {       cout << i->second.size() <<    ;       for (int j = 0; j < i->second.size(); ++j)         cout << i->second[j] <<    n [j == i->second.size() - 1];     }   }   