Problem: You are given a sequence a1, a2, ..., an consisting of different integers. It is required to split this sequence into the maximum number of subsequences such that after sorting integers in each of them in increasing order, the total sequence also will be sorted in increasing order.

Sorting integers in a subsequence is a process such that the numbers included in a subsequence are ordered in increasing order, and the numbers which are not included in a subsequence don't change their places.

Every element of the sequence must appear in exactly one subsequence.

Input

The first line of input data contains integer n (1 ≤ n ≤ 105) — the length of the sequence.

The second line of input data contains n different integers a1, a2, ..., an ( - 109 ≤ ai ≤ 109) — the elements of the sequence. It is guaranteed that all elements of the sequence are distinct.

Output

In the first line print the maximum number of subsequences k, which the original sequence can be split into while fulfilling the requirements.

In the next k lines print the description of subsequences in the following format: the number of elements in subsequence ci (0 < ci ≤ n), then ci integers l1, l2, ..., lci (1 ≤ lj ≤ n) — indices of these elements in the original sequence. 

Indices could be printed in any order. Every index from 1 to n must appear in output exactly once.

If there are several possible answers, print any of them.

Examples

Input

6
3 2 1 6 5 4


Output

4
2 1 3
1 2
2 4 6
1 5


Input

6
83 -75 -49 11 37 62


Output

1
6 1 2 3 4 5 6

Note

In the first sample output:

After sorting the first subsequence we will get sequence 1 2 3 6 5 4.

Sorting the second subsequence changes nothing.

After sorting the third subsequence we will get sequence 1 2 3 4 5 6.

Sorting the last subsequence changes nothing.

Solution (in JAVA):

Solution:
/*
 * DA-IICT
 * Author: Jugal Kalal
 */
import java.util.*;
import java.io.*;
import java.math.*;
public class Hackerearth{
	static long mod=(long)Math.pow(10,9)+7l;
	public static void main(String args[]) {
        new Thread(null, new Runnable() {
            public void run() {
                try{
                    solve();
                    w.close();
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        }, "1", 1 << 26).start();
	}
	static InputReader in=new InputReader(System.in);
    static PrintWriter w=new PrintWriter(System.out);
    char ch[][];
	//int ans = 0, cnt = 0, Q;
	int n1, n2, k1, k2, M;
	static ArrayList<Integer>[] g;
	static long ok[];	
	static int phi[]=new int[500005];//static int b[]=new int[100005];
	static void solve(){
            int n=in.nextInt();
            int a[]=in.nextIntArray(n);
            int b[]=Arrays.copyOf(a,n);
            Arrays.sort(b);
            g=new ArrayList[n+1];
            HashMap<Integer,Integer> hm=new HashMap();
            for(int i=0;i<n;i++)
            {
            	hm.put(a[i],i+1);
            }
            for(int i=1;i<=n;i++)
            	g[i]=new ArrayList<Integer>();
            for(int i=0;i<n;i++)
            {
            	int x=hm.get(b[i]);
            	g[i+1].add(x);
            	g[x].add(i+1);
            }
            ans=new ArrayList[n+1];
            for(int i=0;i<=n;i++)
            	ans[i]=new ArrayList<Integer>();
            for(int i=1;i<=n;i++)
            {
            	if(!visited[i])
            	{
            		dfs(i);
            		count++;
            	}
            }
            w.println(count);
            for(int i=0;i<count;i++)
            {
            	w.print(ans[i].size()+" ");
            	for(int x:ans[i])
            	{
            		w.print(x+" ");
            	}
            	w.println();
            }
}
	static ArrayList<Integer> ans[];
	static int count=0;
	private static void dfs(int curr) {
		visited[curr]=true;
		ans[count].add(curr);
		for(int x:g[curr])
		{
			if(!visited[x])
			{
				dfs(x);
			}
		}
	}
	static boolean visited[]=new boolean[100005];

        

    public static void minSwaps(int[] arr){
        int n = arr.length,ans=0;
        for(int i=0;i<n;i++) {
        		if(arr[i]==i+1) {
        			w.println("1 "+arr[i]);
        			ans++;
        		}
        }
        // Create two arrays and use as pairs where first
        // array is element and second array
        // is position of first element
        ArrayList <Pair> arrpos =new ArrayList <Pair> ();
        for (int i = 0; i < n; i++)
             arrpos.add(new Pair(arr[i], i));
        // Sort the array by array element values to
        // get right position of every element as the
        // elements of second array.
        arrpos.sort(new Comparator<Pair>(){
            @Override
            public int compare(Pair o1,Pair o2){
                if (o1.first < o2.first)
                    return -1;
                // We can change this to make it then look at the
                // words alphabetical order
                else if (o1.second==(o2.second))
                    return 0;
                else
                    return 1;
            }
        });
        // To keep track of visited elements. Initialize
        // all elements as not visited or false.
        Boolean[] vis = new Boolean[n];
        Arrays.fill(vis, false);
        // Initialize result
        // Traverse array elements
        for (int i = 0; i < n; i++){
            // already swapped and corrected or
            // already present at correct pos
            if (vis[i] || arrpos.get(i).second == i)
                continue;
            // find out the number of  node in
            // this cycle and add in ans
            int j = i;
            HashSet<Integer> set=new HashSet<>();
            while (!vis[j]){
                vis[j] = true;
                // move to next node
                j = arrpos.get(j).second;
                set.add(j+1);
            }
            if(set.size()>0) {
	            	ans++;
	            w.print(set.size()+" ");
	            for(int jack:set) {
	            		w.print(jack+" ");
	            }
	            w.println();
            }
            // Update answer by adding current cycle.
        }
        // Return result
        System.out.println(ans);
    }
    static class Pair{
    		int first;
    		int second;
    		public Pair(int first,int second) {
    			this.first=first;
    			this.second=second;
    		}
    }
    static int Arr[];
    static void initialize(int n) {
    		Arr=new int[n];
    		for(int i=0;i<n;i++)
    			Arr[i]=i;
    }
    static int root(int i){
        while(Arr[ i ] != i){
        		i = Arr[ i ];
        }
        return i;
    }
    /*modified union function where we connect the elements by changing the root of one of the element */
    static void union(int A ,int B) {
        int root_A = root(A);       
        int root_B = root(B);  
        Arr[ root_A ] = root_B ;       //setting parent of root(A) as root(B).
    }
    static boolean find(int A,int B){
        if( root(A)==root(B) )       //if A and B have same root,means they are connected.
        		return true;
        else
        		return false;
    }
    static void delete_edge(int A,int B) {
    		int parent_A=Arr[A];
    		int parent_B=Arr[B];
    		if(parent_A==B) {
    			Arr[A]=A;
    		}else {
    			Arr[B]=B;
    		}
    }
//    static int Arr[];
//    static long size[];
//  //modified initialize function:
//    static void initialize(int N){
//    	Arr=new int[N];
//    	size=new long[N];
//        for(int i = 0;i<N;i++){
//        	Arr[ i ] = i ;
//        	size[ i ] = 1;
//        }
//    }
//    static boolean find(int A,int B){
//        if( root(A)==root(B) )//if A and B have same root,means they are connected.
//        return true;
//        else
//        return false;
//    }
//    static void delete_edge() {
//    		
//    }
// // modified root function.
//    static void weighted_union(int A,int B,int n){
//        int root_A = root(A);
//        int root_B = root(B);
//        if(size[root_A] < size[root_B ]){
//        	Arr[ root_A ] = Arr[root_B];
//        	size[root_B] += size[root_A];
//        }
//        else{
//        	Arr[ root_B ] = Arr[root_A];
//        	size[root_A] += size[root_B];
//        }
//    }
//    static int root (int i){
//        while(Arr[ i ] != i){
//            Arr[ i ] = Arr[ Arr[ i ] ] ; 
//            i = Arr[ i ]; 
//        }
//        return i;
//    }
//    static long[] isHamiltonian_path(int n){
//    	boolean dp[][]=new boolean[n][1<<n];
//    	long ans[]=new long[n];
//    	long sum[]=new long[n];
//    	for(int i=0;i<n;i++){
//    		dp[i][1<<i]=true;
//    		ans[i]=0;
//    		sum[i]=i+1;
//    	}
//    	for(int mask=0;mask<(1<<n);mask++){
//    		int s=0;
//    		int count=0,temp=mask;
//    		while(temp>0){
//    			s+=1+Math.log(temp&(-temp))/Math.log(2);
//    			temp=temp&(temp-1);
//    			count++;
//    		}
//    		for(int j=0;j<n;j++){
//    			if((mask&(1<<j))>0){
//    				for(int k=0;k<n;k++){
//    					if(j!=k&&(mask&(1<<k))>0&&adj[j][k]&&dp[k][mask^(1<<j)]){
//    						dp[j][mask]=true;
//    						ans[j]=Math.max(ans[j],count-1);
//    						if(ans[j]==count-1){
//    							sum[j]=Math.max(sum[j], s);
//    						}
//    					}
//    				}
//    			}
//    		}
//    	}
//    	return sum;
//    }
//    static void bfs(int s,int n){
//    	boolean visited[]=new boolean[n];
//    	LinkedList<Integer> queue=new LinkedList<Integer>();
//    	queue.add(s);
//    	visited[s]=true;
//    	while(!queue.isEmpty()){
//    		int num=queue.pop();
////    		System.out.println(ans.toString());
//    		for(int i=0;i<adj[num].size();i++){
//    			if(!visited[adj[num].get(i)]){
//    				visited[adj[num].get(i)]=true;
//    				queue.add(adj[num].get(i));
//    			}
//    		}
//    	}
//    }
    static int gcd(int a,int b){
		if(a==0){
			return b;
		}
		return gcd(b%a,a);
	}
    static long power(long base, long exponent, long modulus){
	    long result = 1L;
	    while (exponent > 0) {
	        if (exponent % 2L == 1L)
	            result = (result * base) % modulus;
	        exponent = exponent >> 1;
	        base = (base * base) % modulus;
	    }
	    return result;
	}
    static HashMap<Long,Long> primeFactors(long n){
        HashMap<Long,Long> ans=new HashMap<Long,Long>();
    	// Print the number of 2s that divide n
        while (n%2L==0L)
        {
            if(ans.containsKey(2L)){
            	ans.put(2L,ans.get(2L)+1L);
            }else{
            	ans.put(2L,1L);
            }
            n /= 2L;
        }
 
        // n must be odd at this point.  So we can
        // skip one element (Note i = i +2)
        for (long i = 3; i <= Math.sqrt(n); i+= 2L)
        {
            // While i divides n, print i and divide n
            while (n%i == 0)
            {
            	if(ans.containsKey(i)){
                	ans.put(i,ans.get(i)+1L);
                }else{
                	ans.put(i,1L);
                }
                n /= i;
            }
        }
 
        // This condition is to handle the case whien
        // n is a prime number greater than 2
        if (n > 2)
            ans.put(n,1L);
        return ans;
    }
////for marking all prime numbers greater than 1 and less than equal to N
	static void sieve(int N) {
	 boolean isPrime[]=new boolean[N+1];
	 isPrime[0] = true;
	 isPrime[1] = true;
	 for(int i = 2; i * i <= N; ++i) {
	      if(isPrime[i] == false) {//Mark all the multiples of i as composite numbers
	          for(int j = i * i; j <= N ;j += i)
	              isPrime[j] = true;
	     }
	 }
	}
//  //if  str2 (pattern) is subsequence of str1 (Text) or not
//	static boolean function(String str1,String str2){
//	     str2 = str2.replace("", ".*");  //returns .*a.*n.*n.*a.
//	     return (str1.matches(str2));  // returns true
//	}
    
    
 
	static boolean isPrime(long n) {
		if(n < 2L) return false;
		if(n == 2L || n == 3L) return true;
		if(n%2L == 0 || n%3L == 0) return false;	
		long sqrtN = (long)Math.sqrt(n)+1L;
		for(long i = 6L; i <= sqrtN; i += 6L) {
			if(n%(i-1) == 0 || n%(i+1) == 0) return false;
		}
		return true;
	}
//	static HashMap<Integer,Integer> level;;
//	static HashMap<Integer,Integer> parent;
	static int maxlevel=0;
	
//	static boolean T[][][];
//	static void subsetSum(int input[], int total, int count) {
//        T = new boolean[input.length + 1][total + 1][count+1];
//        for (int i = 0; i <= input.length; i++) {
//        	T[i][0][0] = true;
//        	for(int j = 1; j<=count; j++){
//        		T[i][0][j] = false;
//        	}
//        }
//        int sum[]=new int[input.length+1];
//        for(int i=1;i<=input.length;i++){
//            sum[i]=sum[i-1]+input[i-1];
//        }
//        for (int i = 1; i <= input.length; i++) {
//            for (int j = 1; j <= (int)Math.min(total,sum[i]); j++) {
//            	for (int k = 1; k <= (int)Math.min(i,count); k++){
//            		 if (j >= input[i - 1]) {//Exclude and Include
//                         T[i][j][k] = T[i - 1][j][k] || T[i - 1][j - input[i - 1]][k-1];
//                     } else {
//                         T[i][j][k] = T[i-1][j][k];
//                     }
//            	}
//            }
//        }
//    }
//	static <K,V extends Comparable<? super V>>
//	SortedSet<Map.Entry<K,V>> entriesSortedByValues(Map<K,V> map) {
//	    SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(
//	        new Comparator<Map.Entry<K,V>>() {
//	            @Override public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
//	                int res = e2.getValue().compareTo(e1.getValue());
//	                return res != 0 ? res : 1;
//	            }
//	        }
//	    );
//	    sortedEntries.addAll(map.entrySet());
//	    return sortedEntries;
//	}
	
 
	 
	//minimum prime factor of all the numbers less than n
    static int minPrime[];
	static void minimumPrime(int n){
		minPrime=new int[n+1];
		minPrime[1]=1;
        for (int i = 2; i * i <= n; ++i) {
            if (minPrime[i] == 0) {         //If i is prime
                for (int j = i * i; j <= n; j += i) {
                    if (minPrime[j] == 0) {
                        minPrime[j] = i;
                    }
                }
            }
        }
        for (int i = 2; i <= n; ++i) {
            if (minPrime[i] == 0) {
                minPrime[i] = i;
            }
        }
	}
	static long modInverse(long A, long M)
	{
		long x=extendedEuclid(A,M)[0];
		return (x%M+M)%M;    //x may be negative
	}
	static long[] extendedEuclid(long A, long B) {
		if(B == 0) {
			long d = A;
			long x = 1;
			long y = 0;
			return new long[]{x,y,d};
		}
		else {
			long arr[]=extendedEuclid(B, A%B);
			long temp = arr[0];
			arr[0] = arr[1];
			arr[1] = temp - (A/B)*arr[1];
			return arr;
		}
	}
 
	static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, numChars;
        private SpaceCharFilter filter;
 
        public InputReader(InputStream stream) {
            this.stream = stream;
        }
        
        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }
 
        public String nextLine() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }
 
        public String readString() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }
 
        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }
 
        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }
 
        public int[] nextIntArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextInt();
            }
            return arr;
        }
 
        public long[] nextLongArray(int n) {
            long[] arr = new long[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextLong();
            }
            return arr;
        }
 
        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }
 
        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }
        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
	}
}