#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#define MAX_LENGTH 0xffff

typedef enum colour{
	white = 1,
	red = 4,
	green = 5,
	blue = 6,
	yellow = 3,
	orange = 2
}colour;

typedef enum cmd{
	quit,
	go_state,
	do_action,
	print,
	printfile,
	m,
	load,
	write,
	check,
	read,
	none
}cmd;

typedef	union data_node{
	int c[6];
	struct {
		unsigned c0 : 3;
		unsigned c1 : 3;
		unsigned c2 : 3;
		unsigned c3 : 3;
		unsigned c4 : 3;
		unsigned c5 : 3;

		unsigned c00 : 3;
		unsigned c01 : 3;
		unsigned c02 : 3;
		unsigned c03 : 3;
			unsigned a : 2;
		unsigned c04 : 3;
		unsigned c05 : 3;
		unsigned c06 : 3;
		unsigned c07 : 3;
		unsigned c08 : 3;

		unsigned c10 : 3;
		unsigned c11 : 3;
		unsigned c12 : 3;
		unsigned c13 : 3;
		unsigned c14 : 3;
			unsigned b : 2;
		unsigned c15 : 3;
		unsigned c16 : 3;
		unsigned c17 : 3;
		unsigned c18 : 3;

		unsigned c20 : 3;
		unsigned c21 : 3;
		unsigned c22 : 3;
		unsigned c23 : 3;
		unsigned c24 : 3;
		unsigned c25 : 3;
			unsigned c : 2;
		unsigned c26 : 3;
		unsigned c27 : 3;
		unsigned c28 : 3;

		unsigned c30 : 3;
		unsigned c31 : 3;
		unsigned c32 : 3;
		unsigned c33 : 3;
		unsigned c34 : 3;
		unsigned c35 : 3;
		unsigned c36 : 3;
			unsigned d : 2;
		unsigned c37 : 3;
		unsigned c38 : 3;

		unsigned c40 : 3;
		unsigned c41 : 3;
		unsigned c42 : 3;
		unsigned c43 : 3;
		unsigned c44 : 3;
		unsigned c45 : 3;
		unsigned c46 : 3;
		unsigned c47 : 3;
			unsigned e : 2;
		unsigned c48 : 3;

		unsigned c50 : 3;
		unsigned c51 : 3;
		unsigned c52 : 3;
		unsigned c53 : 3;
		unsigned c54 : 3;
		unsigned c55 : 3;
		unsigned c56 : 3;
		unsigned c57 : 3;
		unsigned c58 : 3;
			unsigned f : 2;
	}data;
}data_node;

typedef struct info_node{
	unsigned short pfile_index;
	unsigned short pnode_index;
	char action;
}info_node;

data_node data_s[MAX_LENGTH], data_d[MAX_LENGTH];
info_node info_s[MAX_LENGTH], info_d[MAX_LENGTH];
unsigned short index_s = 0;
unsigned short index_d = 0;
int exe_quit = 0;
void action0(data_node *s, data_node *d);
void action1(data_node *s, data_node *d);
void action2(data_node *s, data_node *d);
void action3(data_node *s, data_node *d);
void action4(data_node *s, data_node *d);
void action5(data_node *s, data_node *d);
void action6(data_node *s, data_node *d);
void action7(data_node *s, data_node *d);
void action8(data_node *s, data_node *d);
void action9(data_node *s, data_node *d);
void action10(data_node *s, data_node *d);
void action11(data_node *s, data_node *d);
void action12(data_node *s, data_node *d);

void (*action[])(data_node *s, data_node *d)={
	action0,
	action1,
	action2,
	action3,
	action4,
	action5,
	action6,
	action7,
	action8,
	action9,
	action10,
	action11,
	action12,
};

void print_c(int color)
{
	static int i = 0;
	if(color < 0){
		i = 0;
		return;
	}
	if(i == 9){
		printf("\n");
		i = 1;
	}
	else i++;
	switch(color){
		case white:
			printf("white ");
			break;
		case red:
			printf("red ");
			break;
		case green:
			printf("green ");
			break;
		case blue:
			printf("blue ");
			break;
		case yellow:
			printf("yellow ");
			break;
		case orange:
			printf("orange ");
			break;
	}
}

void print_node(data_node d[MAX_LENGTH], int i)
{
	void (*function)(int i);
	function = print_c;

	function(d[i].data.c00);
	function(d[i].data.c01);
	function(d[i].data.c02);
	function(d[i].data.c03);
	function(d[i].data.c04);
	function(d[i].data.c05);
	function(d[i].data.c06);
	function(d[i].data.c07);
	function(d[i].data.c08);

	function(d[i].data.c10);
	function(d[i].data.c11);
	function(d[i].data.c12);
	function(d[i].data.c13);
	function(d[i].data.c14);
	function(d[i].data.c15);
	function(d[i].data.c16);
	function(d[i].data.c17);
	function(d[i].data.c18);

	function(d[i].data.c20);
	function(d[i].data.c21);
	function(d[i].data.c22);
	function(d[i].data.c23);
	function(d[i].data.c24);
	function(d[i].data.c25);
	function(d[i].data.c26);
	function(d[i].data.c27);
	function(d[i].data.c28);

	function(d[i].data.c30);
	function(d[i].data.c31);
	function(d[i].data.c32);
	function(d[i].data.c33);
	function(d[i].data.c34);
	function(d[i].data.c35);
	function(d[i].data.c36);
	function(d[i].data.c37);
	function(d[i].data.c38);

	function(d[i].data.c40);
	function(d[i].data.c41);
	function(d[i].data.c42);
	function(d[i].data.c43);
	function(d[i].data.c44);
	function(d[i].data.c45);
	function(d[i].data.c46);
	function(d[i].data.c47);
	function(d[i].data.c48);

	function(d[i].data.c50);
	function(d[i].data.c51);
	function(d[i].data.c52);
	function(d[i].data.c53);
	function(d[i].data.c54);
	function(d[i].data.c55);
	function(d[i].data.c56);
	function(d[i].data.c57);
	function(d[i].data.c58);
}

int load_config(char * file_name)
{
	FILE * fp;
	int i, j;
	int s[6][9];
	char buf[100];
	fp = fopen(file_name, "r");

	if(!fp){
		printf("failed to open file %s\n", file_name);
		return -1;
	}
	for(i = 0; i < 6; i++){
		char color[30];
		int n = 0;
		n = 0;
		fgets(buf, 100, fp);
		for(j = 0; j < 9; j++){
			int m = 0;
			m = 0;
			while(buf[n] != ' ') color[m++] = buf[n++];
			color[m] = 0;
			n++;
			if(!strcmp(color,"white")) s[i][j] = white;
			if(!strcmp(color,"red")) s[i][j] = red;
			if(!strcmp(color,"green")) s[i][j] = green;
			if(!strcmp(color,"blue")) s[i][j] = blue;
			if(!strcmp(color,"yellow")) s[i][j] = yellow;
			if(!strcmp(color,"orange")) s[i][j] = orange;
		}
	}

	fclose(fp);

	data_s[0].data.c00 = s[0][0];
	data_s[0].data.c01 = s[0][1];
	data_s[0].data.c02 = s[0][2];
	data_s[0].data.c03 = s[0][3];
	data_s[0].data.c04 = s[0][4];
	data_s[0].data.c05 = s[0][5];
	data_s[0].data.c06 = s[0][6];
	data_s[0].data.c07 = s[0][7];
	data_s[0].data.c08 = s[0][8];

	data_s[0].data.c10 = s[1][0];
	data_s[0].data.c11 = s[1][1];
	data_s[0].data.c12 = s[1][2];
	data_s[0].data.c13 = s[1][3];
	data_s[0].data.c14 = s[1][4];
	data_s[0].data.c15 = s[1][5];
	data_s[0].data.c16 = s[1][6];
	data_s[0].data.c17 = s[1][7];
	data_s[0].data.c18 = s[1][8];

	data_s[0].data.c20 = s[2][0];
	data_s[0].data.c21 = s[2][1];
	data_s[0].data.c22 = s[2][2];
	data_s[0].data.c23 = s[2][3];
	data_s[0].data.c24 = s[2][4];
	data_s[0].data.c25 = s[2][5];
	data_s[0].data.c26 = s[2][6];
	data_s[0].data.c27 = s[2][7];
	data_s[0].data.c28 = s[2][8];

	data_s[0].data.c30 = s[3][0];
	data_s[0].data.c31 = s[3][1];
	data_s[0].data.c32 = s[3][2];
	data_s[0].data.c33 = s[3][3];
	data_s[0].data.c34 = s[3][4];
	data_s[0].data.c35 = s[3][5];
	data_s[0].data.c36 = s[3][6];
	data_s[0].data.c37 = s[3][7];
	data_s[0].data.c38 = s[3][8];

	data_s[0].data.c40 = s[4][0];
	data_s[0].data.c41 = s[4][1];
	data_s[0].data.c42 = s[4][2];
	data_s[0].data.c43 = s[4][3];
	data_s[0].data.c44 = s[4][4];
	data_s[0].data.c45 = s[4][5];
	data_s[0].data.c46 = s[4][6];
	data_s[0].data.c47 = s[4][7];
	data_s[0].data.c48 = s[4][8];

	data_s[0].data.c50 = s[5][0];
	data_s[0].data.c51 = s[5][1];
	data_s[0].data.c52 = s[5][2];
	data_s[0].data.c53 = s[5][3];
	data_s[0].data.c54 = s[5][4];
	data_s[0].data.c55 = s[5][5];
	data_s[0].data.c56 = s[5][6];
	data_s[0].data.c57 = s[5][7];
	data_s[0].data.c58 = s[5][8];

	index_s = 1;
	action0(&(data_s[0]), &(data_s[0]));
	info_s[0].pfile_index = 0;
	info_s[0].pnode_index = 0;
	info_s[0].action = 0;
	return 0;
}

void print_file(int i, int j)
{
	char c[100];int k;
	FILE * fp;
	char file_name[100];
	sprintf(file_name, "%d.%d", i, j);
	if((fp = fopen(file_name, "r")) == NULL) return;
	k = fread(c, 100, 1,fp);
printf("i = %d\n", k);
	while(100>k)
		printf("%x ",(int)c[k++]);
	fclose(fp);
}

int node_search(data_node d, unsigned short *nlevel, unsigned short *findex, unsigned short *nindex)
{
	FILE * fp;
	int i = 0, j = 0, k;
	data_node data[MAX_LENGTH];
	info_node info[MAX_LENGTH];
	unsigned short index = 0;
	char file_name[100];
	while(1){
		sprintf(file_name, "%d.%d", i, j);
		if((fp = fopen(file_name, "r")) == NULL){
			if(j == 0){
				return 0;
			}
			else{
				i++;
				j = 0;
				continue;
			}
		}
		fread(&index, sizeof(index), 1,fp);
		fread(data, sizeof(data_node), index, fp);
		fclose(fp);
		while(index--){
			for(k = 0; k < 6; k++){
				if(data[index].c[k] != d.c[k]) break;
			}
			if(k == 6) {
				if(nlevel) *nlevel = i;
				if(findex) *findex = j;
				if(nindex) *nindex = index;
				return 1;
			}
		}
		j++;
	}
	return 0;
}

void write_file(int i, int j)
{
	FILE * fp;
	char file_name[100];
	sprintf(file_name, "%d.%d", i, j);
	fp = fopen(file_name, "w");
	printf("write_file %s\n",file_name);
	fwrite( &index_d, sizeof(index_d), 1,fp);
	fwrite(data_d, sizeof(data_node), index_d, fp);
	fwrite(info_d, sizeof(info_node), index_d, fp);
	fclose(fp);
}

int read_file(int i, int j)
{
	FILE * fp;
	char file_name[100];
	sprintf(file_name, "%d.%d", i, j);
	if((fp = fopen(file_name, "r")) == NULL) return -1;
	fread(&index_s, sizeof(index_s), 1,fp);
	fread(data_s, sizeof(data_node), index_s, fp);
	fread(info_s, sizeof(info_node), index_s, fp);
	fclose(fp);
	
	return 0;
}
int search()
{
				unsigned short i, j;
					i = index_d;
					while(i--){
						for(j = 0; j < 6; j++){
						if(data_d[index_d].c[j] != data_d[i].c[j]) break;
						}
						if(j == 6) return 1;
					}
					return 0;

}
void go(int i, int fi,int ni)
{
	unsigned short j = 0, k = 0;
		index_d = 0;
		FILE * fp;
		char filename[10];
		unsigned short index = 0;char a;
		if(i< 0){
			sprintf(filename,"%d.%d",fi,ni);
			fp = fopen(filename,"r");
			printf("d file open %s\n",filename);
			fread(&index_d, sizeof(index_d), 1,fp);
			fread(data_d, sizeof(data_node), index_d, fp);
			fread(info_d, sizeof(info_node), index_d, fp);
			fclose(fp);
			index_d--;
			i = fi-1;
			j = info_d[index_d].pfile_index;
			k = ni+1;
			read_file(i, j++);
			printf("s file open %d.%d\n",i,j-1);
			index = info_d[index_d].pnode_index;
			
			a = 13 - info_d[index_d].action;
			printf("index = %d, index_s = %d, index_d = %d, a = %d\n",index,index_s,index_d,a);
			goto c_go;
		}
		
		while(!read_file(i, j++)){
		printf("file open %d.%d\n", i, j-1);

		while(1){
			for(a = 1; a <=12; a++){
//				printf("do action %d\n", a);
				(*action[a])(&(data_s[index]),&(data_d[index_d]));
//				printf("search node\n");

//				if(a == 9) printf("d %d d 9 ", 13 - info_s[index].action);
				if(search() || node_search(data_d[index_d],NULL,NULL,NULL)){
//					if(a == 9) printf("\n");
					continue;
				}
//				if(a == 9) printf("add node\n");
				info_d[index_d].action = 13 - a;
				info_d[index_d].pfile_index = j-1;
				info_d[index_d].pnode_index = index;

//				printf("index_d = %d, pfile_index = %d, pnode_index = %d, action = %d\n",index_d,info_d[index_d].pfile_index,info_d[index_d].pnode_index,info_d[index_d].action);
//				if(exe_quit){index_d++;write_file(i+1,k);exit(0);}
				if((++index_d) >= MAX_LENGTH){
					write_file(i+1, k++);
c_go:			index_d = 0;
				}
			}
			if(++index == index_s){
//				if(index_d > 0 && index_d <MAX_LENGTH)	write_file(i+1, k++);
				break;
			}//printf("index++\n");
		}
	}
	if(index_d > 0 && index_d <MAX_LENGTH)	write_file(i+1, k++);
}

void get_action_info(unsigned short nlevel, unsigned short findex, unsigned short nindex)
{
	FILE * fp;
	char file_name[100];
	info_node info;
	unsigned short index;
	while(1){
		sprintf(file_name, "%d.%d", nlevel--, findex);
		if((fp = fopen(file_name, "r")) == NULL) return;
		fread(&index, sizeof(index), 1, fp);
		fseek(fp, sizeof(data_node)*index+sizeof(info_node)*nindex, SEEK_CUR);
		fread(&info, sizeof(info_node), 1, fp);
		fclose(fp);
		printf("file = %s, index = %d, action = %d\n", file_name, nindex, info.action);		
		findex = info.pfile_index;
		nindex = info.pnode_index;

	}

}

cmd get_cmd(void)
{
	char buf[30];
	printf("get_cmd: ");
	scanf("%s",	buf);
	printf("cmd %s\n", buf);
	if(!strcmp(buf,"e")) return quit;
	if(!strcmp(buf,"p")) return print;
	if(!strcmp(buf,"g")) return go_state;
	if(!strcmp(buf,"l")) return load;
	if(!strcmp(buf,"q")) return quit;
	if(!strcmp(buf,"d")) return do_action;
	if(!strcmp(buf,"w")) return write;
	if(!strcmp(buf,"r")) return read;
	if(!strcmp(buf,"pf")) return printfile;
	if(!strcmp(buf,"c")) return check;
	if(!strcmp(buf,"m")) return m;

	return none;
	
}
int odd_check(data_node *d);

void handler()
{
	printf("ctrl+c\n");
	exe_quit = 1;
	
}
int main(int argc, char *argv[])
{
	cmd c;char file[30];
struct timeval tvafter,tvpre;
struct timezone tz;
	unsigned short s = MAX_LENGTH; int i = 0x7fffffff;
unsigned short nlevel, findex, nindex;
	printf("size of data_node: %d\n", sizeof(data_node));
	printf("size of info_node: %d\n", sizeof(info_node));
	printf("max number of node: %d\n", 1024*1024/(sizeof(data_node)+sizeof(info_node)));
	printf("file length: %d\n", s*(sizeof(data_node)+sizeof(info_node)));
	printf("max of int: %d\n",i);
	printf("max of unsigned short: %d\n",s);
	printf("size of unsigned short: %d\n", sizeof(unsigned short));
	printf("size of int: %d\n", sizeof(int));
	printf("size of long: %d\n", sizeof(long long));
	
	printf("\n\nargc = %d\n", argc);
	for(i = 0; i < argc; i++){
		printf("argv[%d] = %s\n", i, argv[i]);
	}
	
	if(argc > 1){
		load_config(argv[1]);
	}
/*	
	if (signal(SIGINT, handler) == SIG_ERR) {
		perror("Fail to set signal");
		return (-1);
	}
	if (signal(SIGTERM, handler) == SIG_ERR) {
		perror("Fail to set signal");
		return (-1);
	}
*/
	while(quit != (c = get_cmd())){
		switch(c){
			case load:
				scanf("%s",file);
				load_config(file);
				break;
			case do_action:
				scanf("%d",&i);
				(*action[i])(&(data_s[index_s-1]),&(data_s[index_s]));
				printf("index_s = %d\n", index_s++);
				break;
			case go_state:{
					int j , k;
					scanf("%d %d %d",&i,&j,&k);
					if(i < 0){
						i = -i;
						while(i) go(i++, 0,0);
					}
					else if(i == 0){
						go(-1, j,k);
					}
					else go(i, 0,0);
				}break;
			case write:
				write_file(0, 0);
				break;
			case read:
				read_file(0, 0);
				break;
			case printfile:
				print_file(0, 0);
				break;
			case check:
				scanf("%d", &i);
				if(odd_check(&(data_s[i]))){
					printf("check error!\n");
				}
				else printf("check right!\n");
				break;
			case print:
				scanf("%d", &i);
				if(i >= 0){
					print_c(-1);
					print_node(data_s, i);
					printf("\n");
				}
				break;
			case m:
				scanf("%s",file);
				load_config(file);
				gettimeofday (&tvpre , &tz);
				if(!node_search(data_s[0], &nlevel, &findex, &nindex)){ 
//				printf("get_action_info %d.%d %d\n",nlevel, findex, nindex);
			gettimeofday (&tvafter , &tz);
printf("time:%ld\n", (tvafter.tv_sec-tvpre.tv_sec)*1000+(tvafter.tv_usec-tvpre.tv_usec)/1000);break;}
			gettimeofday (&tvafter , &tz);
printf("time:%ld\n", (tvafter.tv_sec-tvpre.tv_sec)*1000+(tvafter.tv_usec-tvpre.tv_usec)/1000);
				get_action_info(nlevel, findex, nindex);
				index_s = 1;
				break;
		}
	}
}

/*
right
	d->data.ci2 = s->data.ci0;
	d->data.ci5 = s->data.ci1;
	d->data.ci8 = s->data.ci2;
	d->data.ci1 = s->data.ci3;
	d->data.ci4 = s->data.ci4;
	d->data.ci7 = s->data.ci5;
	d->data.ci0 = s->data.ci6;
	d->data.ci3 = s->data.ci7;
	d->data.ci6 = s->data.ci8;
left
	d->data.ci6 = s->data.ci0;
	d->data.ci3 = s->data.ci1;
	d->data.ci0 = s->data.ci2;
	d->data.ci7 = s->data.ci3;
	d->data.ci4 = s->data.ci4;
	d->data.ci1 = s->data.ci5;
	d->data.ci8 = s->data.ci6;
	d->data.ci5 = s->data.ci7;
	d->data.ci2 = s->data.ci8;
odd
	d->data.ci = 0;
	d->data.ci ^= d->data.ci0;
	d->data.ci ^= d->data.ci1;
	d->data.ci ^= d->data.ci2;
	d->data.ci ^= d->data.ci3;
	d->data.ci ^= d->data.ci4;
	d->data.ci ^= d->data.ci5;
	d->data.ci ^= d->data.ci6;
	d->data.ci ^= d->data.ci7;
	d->data.ci ^= d->data.ci8;
*/

int odd_check(data_node *d)
{
	int i;

	i = d->data.c0;
	i ^= d->data.c00;
	i ^= d->data.c01;
	i ^= d->data.c02;
	i ^= d->data.c03;
	i ^= d->data.c04;
	i ^= d->data.c05;
	i ^= d->data.c06;
	i ^= d->data.c07;
	i ^= d->data.c08;
	if(i) return -1;

	i = d->data.c1;
	i ^= d->data.c10;
	i ^= d->data.c11;
	i ^= d->data.c12;
	i ^= d->data.c13;
	i ^= d->data.c14;
	i ^= d->data.c15;
	i ^= d->data.c16;
	i ^= d->data.c17;
	i ^= d->data.c18;
	if(i) return -1;

	i = d->data.c2;
	i ^= d->data.c20;
	i ^= d->data.c21;
	i ^= d->data.c22;
	i ^= d->data.c23;
	i ^= d->data.c24;
	i ^= d->data.c25;
	i ^= d->data.c26;
	i ^= d->data.c27;
	i ^= d->data.c28;
	if(i) return -1;

	i = d->data.c3;
	i ^= d->data.c30;
	i ^= d->data.c31;
	i ^= d->data.c32;
	i ^= d->data.c33;
	i ^= d->data.c34;
	i ^= d->data.c35;
	i ^= d->data.c36;
	i ^= d->data.c37;
	i ^= d->data.c38;
	if(i) return -1;

	i = d->data.c4;
	i ^= d->data.c40;
	i ^= d->data.c41;
	i ^= d->data.c42;
	i ^= d->data.c43;
	i ^= d->data.c44;
	i ^= d->data.c45;
	i ^= d->data.c46;
	i ^= d->data.c47;
	i ^= d->data.c48;
	if(i) return -1;

	i = d->data.c5;
	i ^= d->data.c50;
	i ^= d->data.c51;
	i ^= d->data.c52;
	i ^= d->data.c53;
	i ^= d->data.c54;
	i ^= d->data.c55;
	i ^= d->data.c56;
	i ^= d->data.c57;
	i ^= d->data.c58;
	if(i) return -1; 
	return 0;
}
void odd(data_node *d)
{
	d->data.c0 = 0;
	d->data.c0 ^= d->data.c00;
	d->data.c0 ^= d->data.c01;
	d->data.c0 ^= d->data.c02;
	d->data.c0 ^= d->data.c03;
	d->data.c0 ^= d->data.c04;
	d->data.c0 ^= d->data.c05;
	d->data.c0 ^= d->data.c06;
	d->data.c0 ^= d->data.c07;
	d->data.c0 ^= d->data.c08;

	d->data.c1 = 0;
	d->data.c1 ^= d->data.c10;
	d->data.c1 ^= d->data.c11;
	d->data.c1 ^= d->data.c12;
	d->data.c1 ^= d->data.c13;
	d->data.c1 ^= d->data.c14;
	d->data.c1 ^= d->data.c15;
	d->data.c1 ^= d->data.c16;
	d->data.c1 ^= d->data.c17;
	d->data.c1 ^= d->data.c18;

	d->data.c2 = 0;
	d->data.c2 ^= d->data.c20;
	d->data.c2 ^= d->data.c21;
	d->data.c2 ^= d->data.c22;
	d->data.c2 ^= d->data.c23;
	d->data.c2 ^= d->data.c24;
	d->data.c2 ^= d->data.c25;
	d->data.c2 ^= d->data.c26;
	d->data.c2 ^= d->data.c27;
	d->data.c2 ^= d->data.c28;

	d->data.c3 = 0;
	d->data.c3 ^= d->data.c30;
	d->data.c3 ^= d->data.c31;
	d->data.c3 ^= d->data.c32;
	d->data.c3 ^= d->data.c33;
	d->data.c3 ^= d->data.c34;
	d->data.c3 ^= d->data.c35;
	d->data.c3 ^= d->data.c36;
	d->data.c3 ^= d->data.c37;
	d->data.c3 ^= d->data.c38;

	d->data.c4 = 0;
	d->data.c4 ^= d->data.c40;
	d->data.c4 ^= d->data.c41;
	d->data.c4 ^= d->data.c42;
	d->data.c4 ^= d->data.c43;
	d->data.c4 ^= d->data.c44;
	d->data.c4 ^= d->data.c45;
	d->data.c4 ^= d->data.c46;
	d->data.c4 ^= d->data.c47;
	d->data.c4 ^= d->data.c48;

	d->data.c5 = 0;
	d->data.c5 ^= d->data.c50;
	d->data.c5 ^= d->data.c51;
	d->data.c5 ^= d->data.c52;
	d->data.c5 ^= d->data.c53;
	d->data.c5 ^= d->data.c54;
	d->data.c5 ^= d->data.c55;
	d->data.c5 ^= d->data.c56;
	d->data.c5 ^= d->data.c57;
	d->data.c5 ^= d->data.c58;
}
void action0(data_node *s, data_node *d)
{
	register int i;
	for(i = 0; i < 6; i++) d->c[i] = s->c[i];
	odd(d);
}

void action1(data_node *s, data_node *d)
{
	action0(s, d);//(*action[0])(s, d);

	d->data.c30 = s->data.c00;
	d->data.c31 = s->data.c01;
	d->data.c32 = s->data.c02;

	d->data.c20 = s->data.c30;
	d->data.c21 = s->data.c31;
	d->data.c22 = s->data.c32;

	d->data.c10 = s->data.c20;
	d->data.c11 = s->data.c21;
	d->data.c12 = s->data.c22;

	d->data.c00 = s->data.c10;
	d->data.c01 = s->data.c11;
	d->data.c02 = s->data.c12;

	d->data.c42 = s->data.c40;
	d->data.c45 = s->data.c41;
	d->data.c48 = s->data.c42;
	d->data.c41 = s->data.c43;
	d->data.c44 = s->data.c44;
	d->data.c47 = s->data.c45;
	d->data.c40 = s->data.c46;
	d->data.c43 = s->data.c47;
	d->data.c46 = s->data.c48;
	odd(d);
}

void action2(data_node *s, data_node *d)
{
	action0(s, d);

	d->data.c36 = s->data.c06;
	d->data.c37 = s->data.c07;
	d->data.c38 = s->data.c08;

	d->data.c26 = s->data.c36;
	d->data.c27 = s->data.c37;
	d->data.c28 = s->data.c38;

	d->data.c16 = s->data.c26;
	d->data.c17 = s->data.c27;
	d->data.c18 = s->data.c28;

	d->data.c06 = s->data.c16;
	d->data.c07 = s->data.c17;
	d->data.c08 = s->data.c18;

	d->data.c56 = s->data.c50;
	d->data.c53 = s->data.c51;
	d->data.c50 = s->data.c52;
	d->data.c57 = s->data.c53;
	d->data.c54 = s->data.c54;
	d->data.c51 = s->data.c55;
	d->data.c58 = s->data.c56;
	d->data.c55 = s->data.c57;
	d->data.c52 = s->data.c58;
	odd(d);
}


void action3(data_node *s, data_node *d)
{
	action0(s, d);

	d->data.c02 = s->data.c52;
	d->data.c05 = s->data.c55;
	d->data.c08 = s->data.c58;

	d->data.c42 = s->data.c02;
	d->data.c45 = s->data.c05;
	d->data.c48 = s->data.c08;

	d->data.c26 = s->data.c42;
	d->data.c23 = s->data.c45;
	d->data.c20 = s->data.c48;

	d->data.c52 = s->data.c26;
	d->data.c55 = s->data.c23;
	d->data.c58 = s->data.c20;

	d->data.c12 = s->data.c10;
	d->data.c15 = s->data.c11;
	d->data.c18 = s->data.c12;
	d->data.c11 = s->data.c13;
	d->data.c14 = s->data.c14;
	d->data.c17 = s->data.c15;
	d->data.c10 = s->data.c16;
	d->data.c13 = s->data.c17;
	d->data.c16 = s->data.c18;
	odd(d);
}

void action4(data_node *s, data_node *d)
{
	action0(s, d);

	d->data.c00 = s->data.c50;
	d->data.c03 = s->data.c53;
	d->data.c06 = s->data.c56;

	d->data.c40 = s->data.c00;
	d->data.c43 = s->data.c03;
	d->data.c46 = s->data.c06;

	d->data.c28 = s->data.c40;
	d->data.c25 = s->data.c43;
	d->data.c22 = s->data.c46;

	d->data.c50 = s->data.c28;
	d->data.c53 = s->data.c25;
	d->data.c56 = s->data.c22;

	d->data.c36 = s->data.c30;
	d->data.c33 = s->data.c31;
	d->data.c30 = s->data.c32;
	d->data.c37 = s->data.c33;
	d->data.c34 = s->data.c34;
	d->data.c31 = s->data.c35;
	d->data.c38 = s->data.c36;
	d->data.c35 = s->data.c37;
	d->data.c32 = s->data.c38;
	odd(d);
}

void action5(data_node *s, data_node *d)
{
	action0(s, d);
	d->data.c10 = s->data.c52;
	d->data.c13 = s->data.c51;
	d->data.c16 = s->data.c50;
	
	d->data.c46 = s->data.c10;
	d->data.c47 = s->data.c13;
	d->data.c48 = s->data.c16;
	
	d->data.c32 = s->data.c48;
	d->data.c35 = s->data.c47;
	d->data.c38 = s->data.c46;
	
	d->data.c50 = s->data.c32;
	d->data.c51 = s->data.c35;
	d->data.c52 = s->data.c38;

	d->data.c06 = s->data.c00;
	d->data.c03 = s->data.c01;
	d->data.c00 = s->data.c02;
	d->data.c07 = s->data.c03;
	d->data.c04 = s->data.c04;
	d->data.c01 = s->data.c05;
	d->data.c08 = s->data.c06;
	d->data.c05 = s->data.c07;
	d->data.c02 = s->data.c08;
	odd(d);
}

void action6(data_node *s, data_node *d)
{
	action0(s, d);
	d->data.c30 = s->data.c42;
	d->data.c33 = s->data.c41;
	d->data.c36 = s->data.c40;

	d->data.c56 = s->data.c30;
	d->data.c57 = s->data.c33;
	d->data.c58 = s->data.c36;

	d->data.c12 = s->data.c58;
	d->data.c15 = s->data.c57;
	d->data.c18 = s->data.c56;

	d->data.c40 = s->data.c12;
	d->data.c41 = s->data.c15;
	d->data.c42 = s->data.c18;

	d->data.c22 = s->data.c20;
	d->data.c25 = s->data.c21;
	d->data.c28 = s->data.c22;
	d->data.c21 = s->data.c23;
	d->data.c24 = s->data.c24;
	d->data.c27 = s->data.c25;
	d->data.c20 = s->data.c26;
	d->data.c23 = s->data.c27;
	d->data.c26 = s->data.c28;
	odd(d);
}

void action7(data_node *s, data_node *d)
{
	action0(s, d);
	d->data.c42 = s->data.c30;
	d->data.c41 = s->data.c33;
	d->data.c40 = s->data.c36;

	d->data.c30 = s->data.c56;
	d->data.c33 = s->data.c57;
	d->data.c36 = s->data.c58;

	d->data.c58 = s->data.c12;
	d->data.c57 = s->data.c15;
	d->data.c56 = s->data.c18;

	d->data.c12 = s->data.c40;
	d->data.c15 = s->data.c41;
	d->data.c18 = s->data.c42;

	d->data.c20 = s->data.c22;
	d->data.c21 = s->data.c25;
	d->data.c22 = s->data.c28;
	d->data.c23 = s->data.c21;
	d->data.c24 = s->data.c24;
	d->data.c25 = s->data.c27;
	d->data.c26 = s->data.c20;
	d->data.c27 = s->data.c23;
	d->data.c28 = s->data.c26;
	odd(d);
}

void action8(data_node *s, data_node *d)
{
	action0(s, d);
	d->data.c52 = s->data.c10;
	d->data.c51 = s->data.c13;
	d->data.c50 = s->data.c16;
	
	d->data.c10 = s->data.c46;
	d->data.c13 = s->data.c47;
	d->data.c16 = s->data.c48;
	
	d->data.c48 = s->data.c32;
	d->data.c47 = s->data.c35;
	d->data.c46 = s->data.c38;
	
	d->data.c32 = s->data.c50;
	d->data.c35 = s->data.c51;
	d->data.c38 = s->data.c52;

	d->data.c00 = s->data.c06;
	d->data.c01 = s->data.c03;
	d->data.c02 = s->data.c00;
	d->data.c03 = s->data.c07;
	d->data.c04 = s->data.c04;
	d->data.c05 = s->data.c01;
	d->data.c06 = s->data.c08;
	d->data.c07 = s->data.c05;
	d->data.c08 = s->data.c02;
	odd(d);
}
void action9(data_node *s, data_node *d)
{
	action0(s, d);

	d->data.c50 = s->data.c00;
	d->data.c53 = s->data.c03;
	d->data.c56 = s->data.c06;

	d->data.c00 = s->data.c40;
	d->data.c03 = s->data.c43;
	d->data.c06 = s->data.c46;

	d->data.c40 = s->data.c28;
	d->data.c43 = s->data.c25;
	d->data.c46 = s->data.c22;

	d->data.c28 = s->data.c50;
	d->data.c25 = s->data.c53;
	d->data.c22 = s->data.c56;

	d->data.c30 = s->data.c36;
	d->data.c31 = s->data.c33;
	d->data.c32 = s->data.c30;
	d->data.c33 = s->data.c37;
	d->data.c34 = s->data.c34;
	d->data.c35 = s->data.c31;
	d->data.c36 = s->data.c38;
	d->data.c37 = s->data.c35;
	d->data.c38 = s->data.c32;
	odd(d);
}
void action10(data_node *s, data_node *d)
{
	action0(s, d);

	d->data.c52 = s->data.c02;
	d->data.c55 = s->data.c05;
	d->data.c58 = s->data.c08;

	d->data.c02 = s->data.c42;
	d->data.c05 = s->data.c45;
	d->data.c08 = s->data.c48;

	d->data.c42 = s->data.c26;
	d->data.c45 = s->data.c23;
	d->data.c48 = s->data.c20;

	d->data.c26 = s->data.c52;
	d->data.c23 = s->data.c55;
	d->data.c20 = s->data.c58;

	d->data.c10 = s->data.c12;
	d->data.c11 = s->data.c15;
	d->data.c12 = s->data.c18;
	d->data.c13 = s->data.c11;
	d->data.c14 = s->data.c14;
	d->data.c15 = s->data.c17;
	d->data.c16 = s->data.c10;
	d->data.c17 = s->data.c13;
	d->data.c18 = s->data.c16;
	odd(d);
}
void action11(data_node *s, data_node *d)
{
	action0(s, d);

	d->data.c06 = s->data.c36;
	d->data.c07 = s->data.c37;
	d->data.c08 = s->data.c38;

	d->data.c36 = s->data.c26;
	d->data.c37 = s->data.c27;
	d->data.c38 = s->data.c28;

	d->data.c26 = s->data.c16;
	d->data.c27 = s->data.c17;
	d->data.c28 = s->data.c18;

	d->data.c16 = s->data.c06;
	d->data.c17 = s->data.c07;
	d->data.c18 = s->data.c08;

	d->data.c50 = s->data.c56;
	d->data.c51 = s->data.c53;
	d->data.c52 = s->data.c50;
	d->data.c53 = s->data.c57;
	d->data.c54 = s->data.c54;
	d->data.c55 = s->data.c51;
	d->data.c56 = s->data.c58;
	d->data.c57 = s->data.c55;
	d->data.c58 = s->data.c52;
	odd(d);
}

void action12(data_node *s, data_node *d)
{
	action0(s, d);

	d->data.c00 = s->data.c30;
	d->data.c01 = s->data.c31;
	d->data.c02 = s->data.c32;

	d->data.c30 = s->data.c20;
	d->data.c31 = s->data.c21;
	d->data.c32 = s->data.c22;

	d->data.c20 = s->data.c10;
	d->data.c21 = s->data.c11;
	d->data.c22 = s->data.c12;

	d->data.c10 = s->data.c00;
	d->data.c11 = s->data.c01;
	d->data.c12 = s->data.c02;

	d->data.c40 = s->data.c42;
	d->data.c41 = s->data.c45;
	d->data.c42 = s->data.c48;
	d->data.c43 = s->data.c41;
	d->data.c44 = s->data.c44;
	d->data.c45 = s->data.c47;
	d->data.c46 = s->data.c40;
	d->data.c47 = s->data.c43;
	d->data.c48 = s->data.c46;
	odd(d);
}
