#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int insection_sort(int *A, int n, int g){
	int cnt = 0;
	int i,j,v;

	for(i=g;i<=n-1;i++){
		v = A[i];
		j = i - g;
		while( j>=0 && A[j]>v ){
			A[j+g] = A[j];
			j = j - g;
			cnt++;
		}
		A[j+g] = v;
	}

	return cnt;
}

int shell_sort(int *A, int n, int *G, int m){
	int total_cnt = 0;
	int i,cnt;

	for(i=0;i<=m-1;i++){
		cnt = insection_sort(A, n, G[i]);
		total_cnt += cnt;
	}

	return total_cnt;
}

int is_sorted(int *A, int n){
	int i;

	for(i=0;i<n-1;i++){
		if( A[i] > A[i+1] ){
			return 0;
		}
	}

	return 1;
}

int main(int argc, char** argv){
	int *A,n,*G,m,total_cnt;
	int *A_save;
	int i,G_next_index,G_next_value;
	int max_total_cnt,found;

	// Create A_save;
	scanf("%d",&n);
	A_save = malloc(sizeof(int)*n);
	for(i=0;i<n;i++){
		scanf("%d",A_save+i);
	}

	// Calc Max Total Count
	max_total_cnt = (int)sqrt(((double)n)*n*n);

	// Create A
	A = malloc(sizeof(int)*n);
	found = 0;
	for(m=1;m<=100&&m<n;m++){
		// Create G
		G = malloc(sizeof(int)*m);
		G[m-1] = 1;
		G_next_index = m - 2;
		G_next_value = 2;
		for(;;){
			if( G_next_index < 0 ){
				// Reset A
				memcpy(A,A_save,sizeof(int)*n);
				// Sort
				total_cnt = shell_sort(A,n,G,m);
				if( total_cnt <= max_total_cnt ){
					if( is_sorted(A, n) ){
						// found
						found = 1;
						// Output
						printf("%d\n",m);
						for(i=0;i<m;i++){
							if( i > 0 ){
								putchar(' ');
							}
							printf("%d",G[i]);
						}
						putchar('\n');
						printf("%d\n",total_cnt);
						for(i=0;i<n;i++){
							printf("%d\n",A[i]);
						}
						break;
					}
				}
				// Current Pattern Finish -> Back Index
				G_next_index++;
				G_next_value = G[G_next_index]+1;
			} else if( G_next_index >= m-1 ){
				// No More Pattern -> Inc M
				break;
			} else if( G_next_value >= n ){
				// Next Value Over -> Back Index
				G_next_index++;
				G_next_value = G[G_next_index]+1;
			} else {
				// Set Next Value -> Foward Index	
				G[G_next_index] = G_next_value;
				G_next_index--;
				G_next_value++;
			}
		}
		// Delete G
		free(G);
		// Exit if Found
		if( found ){
			break;
		}
	}
	// Delete A
	free(A);

	// Dete A(Save)
	free(A_save);

	return 0;
}