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

typedef long long  LongLong;
/* If you are using visual C++ you will use:
   typedef __int64 LongLong;*/

/*In this program individual multiplicities are pairs of number
  and a weight which we think of as a polynomial in the
  rank number of variales. */
struct muldata {
	   int  mul;
       short wht[2];
};
typedef struct muldata muldata;
struct muldata4 {
	   int  mul;
       short wht[4];
};

 
typedef struct muldata4 muldata4;

typedef struct mullnode mullnode, *mullist;

struct mullnode {
       muldata* multip;
       mullist next;
};
/* Give the decomposition of a module as a list of
   multiplicities of weights.*/   
typedef struct mullnode4 mullnode4, *mullist4;

struct mullnode4 {
       muldata4* multip;
       mullist4 next;
};

int part(int a,int b){
   if(a < 0) return(0);
   if (b <=0) {
        if ((-b) > a) return(0);
		return((a+b+1-((a+b)/2))*(((a+b)/2) + 1));}
   if (a >= b) return((a*a + 4*a + 4 + 2*b + 2*a*b -b*b -((a+b)%2))/4);
   return((a*a + 3*a +2)/2);
 }
/*This is Kostant's partition function for SL(4)->SO(4) */
int parte(int a,int b){
   if ((a%2!=0)||(b%2!=0)) return(0);
   return(part(a/2,b/2));
}
/*These are the elements of the Weyl group */
int perms[24][4] = {{0,1,2,3},{0,1,3,2},{0,2,1,3},{0,2,3,1},
					{0,3,1,2},{0,3,2,1},{1,0,2,3},{1,0,3,2},
					{1,2,0,3},{1,2,3,0},{1,3,0,2},{1,3,2,0},
					{2,0,1,3},{2,0,3,1},{2,1,0,3},{2,1,3,0},
					{2,3,0,1},{2,3,1,0},{3,0,1,2},{3,0,2,1},
					{3,1,0,2},{3,1,2,0},{3,2,0,1},{3,2,1,0}};

int sgnum[24] = {1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,
				-1,-1,1,1,-1,-1,1};
/*These are the only premutations that yield a non-zero
  term in Kostant's formula.*/
int useful[11] = {0,1,2,3,4,5,6,7,8,12,14};
/* These are standard operations on lists.*/
void push(struct mullnode** head, struct muldata* data){
    struct mullnode* newnode = malloc(sizeof(struct mullnode));
	newnode -> multip = data;
	newnode -> next = *head;
    *head = newnode;
} 
void push4(struct mullnode4** head, struct muldata4* data){
    struct mullnode4* newnode = malloc(sizeof(struct mullnode4));
	newnode -> multip = data;
	newnode -> next = *head;
    *head = newnode;
}

/*This function takes a dominant form written in terms of fundamental
highest wts for A3 and outputs a linked list with nodes:
		{m,(k,l)}
with m > 0 the multiplicity of the irreducible representation of
A1A1 imbedded as SO(4) in SL(4) with highest weight (k,l)*/

mullnode* mult(int a,int b, int c){ 
     int k,l,i,u,v,j,L[4],r;
	 mullnode *out = NULL;
     muldata *temp;
	 L[0]=a+b+c+3;L[1]=b+c+2;L[2]= c+1; L[3]=0;
	 for(k = a+2*b+c; k >=0;k=k-2)
		for (l= a+ 2*b + c; l>=0;l = l-2){
           r = 0;
		   for (j=0;j<11;j++) {
				i = useful[j];
				u = L[perms[i][0]]+L[perms[i][1]]-L[perms[i][2]]
						-L[perms[i][3]]-k-4;
				v = L[perms[i][0]]-L[perms[i][1]]+L[perms[i][2]]
						-L[perms[i][3]]-l-2;
                r = r + sgnum[i]*parte(u,v);}
           if (r != 0){
				temp = (muldata *)malloc(sizeof(muldata));
				temp->mul = r;
				temp->wht[0]=k;
				temp->wht[1]=l;
       			push(&out ,temp);
				}
			}
           return(out);
}

mullnode* multcut(int a,int b, int c, int s){ 
     int k,l,i,u,v,j,L[4],cut,r;
	 mullnode *out = NULL;
     muldata *temp;
	 L[0]=a+b+c+3;L[1]=b+c+2;L[2]= c+1; L[3]=0;
	 cut = a+2*b+c;
     if(s < cut) cut = s;
	 for(k = cut; k >=0;k=k-2)
		for (l= cut; l>=0;l = l-2){
           r = 0;
		   for (j=0;j<11;j++) {
				i = useful[j];
				u = L[perms[i][0]]+L[perms[i][1]]-L[perms[i][2]]
						-L[perms[i][3]]-k-4;
				v = L[perms[i][0]]-L[perms[i][1]]+L[perms[i][2]]
						-L[perms[i][3]]-l-2;
                r = r + sgnum[i]*parte(u,v);}
           if (r != 0){
				temp = (muldata *)malloc(sizeof(muldata));
				temp->mul = r;
				temp->wht[0]=k;
				temp->wht[1]=l;
       			push(&out ,temp);
				}
			}
           return(out);
}

/* This kills a list that is no longer in use.*/
void destroy(mullist *p_m){
       mullist current,tmp;
       current = *p_m;
       while(current != NULL){
	 tmp = current->next;
	 free(current->multip);
	 free(current);
	 current = tmp;}
}

void destroy4(mullist4 *p_m){
       mullist4 current,tmp;
       current = *p_m;
       while(current != NULL){
	 tmp = current->next;
	 free(current->multip);
	 free(current);
	 current = tmp;}
}

 mullnode4* sym_piece(int a,int b,int c){
           mullist L,M,N;
           mullnode4* out;
           muldata *inp1,*inp2;
           muldata4* data;
		   L = (mullist) mult(a,b,c);
		   out = NULL;
           for(M = L; M != NULL;M = M->next)
				for(N = L;N != NULL;N = N->next){
				data = (muldata4 *)malloc(sizeof(muldata4));
				inp1 = M->multip; inp2 = N->multip;
				data->mul = (inp1->mul)*(inp2->mul);
				data->wht[0]=inp1->wht[0];
				data->wht[1]=inp1->wht[1];
				data->wht[2]=inp2->wht[0];
				data->wht[3]=inp2->wht[1];
				push4(&out,data);}
				destroy(&L);
				return(out);
}
									          
 
	       		 
 mullnode4* sym_piececut(int a,int b,int c,int s){
           mullist L,M,N;
           mullnode4* out;
           muldata *inp1,*inp2;
           muldata4* data;
		   L = (mullist) multcut(a,b,c,s);
		   out = NULL;
           for(M = L; M != NULL;M = M->next)
				for(N = L;N != NULL;N = N->next){
				data = (muldata4 *)malloc(sizeof(muldata4));
				inp1 = M->multip; inp2 = N->multip;
				data->mul = (inp1->mul)*(inp2->mul);
				data->wht[0]=inp1->wht[0];
				data->wht[1]=inp1->wht[1];
				data->wht[2]=inp2->wht[0];
				data->wht[3]=inp2->wht[1];
				push4(&out,data);}
				destroy(&L);
				return(out);
}
		       		 

void print_mult(mullnode * mull){
        struct mullnode* current = mull;
		muldata inf;
		int count = 0;
		while (current != NULL){
			if (count > 0) printf(" + ");
			inf = *(current->multip);
			if(inf.wht[0]+inf.wht[1]==0) printf("%d",inf.mul); 
				else{
					if (inf.mul > 1) printf("%d ",inf.mul);
			if (inf.wht[0]>0) printf("x^%d ",inf.wht[0]);
			if (inf.wht[1]>0) printf("y^%d",inf.wht[1]);}
			current = current->next;
			count++;
		}
		printf("\n");}

void print_mult4(mullnode4 * mull){
        struct mullnode4* current = mull;
		muldata4 inf;
		int count = 0;
		while (current != NULL){
			if (count > 0) printf(" + ");
			inf = *(current->multip);
			if(inf.wht[0]+inf.wht[1]+inf.wht[2]+inf.wht[3]==0) printf("%u",inf.mul); 
				else{
			if (inf.mul > 1) printf("%d ",inf.mul);
			if (inf.wht[0]>0) printf("x1^%d",inf.wht[0]);
			if (inf.wht[1]>0) printf("x2^%d",inf.wht[1]);
			if (inf.wht[2]>0) printf("x3^%d",inf.wht[2]);
			if (inf.wht[3]>0) printf("x4^%d",inf.wht[3]);}
			current = current->next;
			count++;
		}
		printf("\n");}


LongLong *rawsym(int k){
	int i,j,par,exp,N;
    LongLong  *raw;
    mullnode4 *out,*current;
	muldata4 inf;
	par = k%2;
	N = ((k/2) + 1)*((k/2) + 1)*((k/2) +1)*((k/2)+1);
	raw = (LongLong *) calloc(N,sizeof(LongLong));
	for(i = k;i >=0;i--)
	  for(j = (int)k-i; j>=0;j--)
		if((i>=j)&&(j >= (int)k-i-j)){
			out = sym_piece(i-j,i+2*j-k,k-i-j);
			current = out;
			while(current != NULL){
                  inf = *(current->multip);
				  exp = (inf.wht[0]-par)/2 + (inf.wht[1]-par)*((k/2)+1)/2 +
					(inf.wht[2]-par)*((k/2)+1)*((k/2)+1)/2 +
					(inf.wht[3]-par)*((k/2)+1)*((k/2)+1)*((k/2)+1)/2;
				  raw[exp] = raw[exp] + (LongLong)inf.mul;
				  current = current->next;}
		    destroy4(&out);		
    }
	return(raw);
}
/*This should be used with care it assumes that s <= k */
LongLong *rawsymcut(int k,int s){
	int i,j,par,exp,N;
    LongLong  *raw;
    mullnode4 *out,*current;
	muldata4 inf;
	par = k%2;
	N = ((s/2) + 1)*((s/2) + 1)*((s/2) +1)*((s/2)+1);
	raw = (LongLong *) calloc(N,sizeof(LongLong));
	for(i = k;i >=0;i--)
	  for(j = (int)k-i; j>=0;j--)
		if((i>=j)&&(j >= (int)k-i-j)){
			out = sym_piececut(i-j,i+2*j-k,k-i-j,s);
			current = out;
			while(current != NULL){
                  inf = *(current->multip);
				  exp = (inf.wht[0]-par)/2 + (inf.wht[1]-par)*((s/2)+1)/2 +
					(inf.wht[2]-par)*((s/2)+1)*((s/2)+1)/2 +
					(inf.wht[3]-par)*((s/2)+1)*((s/2)+1)*((s/2)+1)/2;
				  raw[exp] = raw[exp] + (LongLong)inf.mul;
				  current = current->next;}
		    destroy4(&out);		
    }
	return(raw);
}
/*This calculates the dimension of invariants in degree 2n*/
LongLong invar(int n){
	int i,j,N;
	LongLong *m1,*m2;
	LongLong out=(LongLong)0;
	for (i=0;i<n;i++) {N = (i/2+1)*(i/2+1)*(i/2+1)*(i/2+1);
		 m1 = rawsym(i);
		 m2 = rawsymcut(2*n-i,i);
		 for(j=0;j<N;j++) out = out + 2*m1[j]*m2[j];}
	free(m1);free(m2);
    m1 = rawsym(n);
    N = (n/2+1)*(n/2+1)*(n/2+1)*(n/2+1);
	for(i=0;i<N;i++) out = out + m1[i]*m1[i];
	return(out);
}
 



main(int argc,char *argv[]){
	int k;
	/*	char buff[20];*/
	LongLong mul;
	if (argc < 2){
		printf("Give a positive integer: ");
		scanf("%d",&k);}
		else{
			k=atoi(argv[1]);
			}
        if(k%2==1) printf("0\n");
	else{
	mul=invar(k/2);
	printf("%lld\n",mul);}
	/*If you are using visual C++ you will have to uncomment 
        the definition of buf above and replace the else clause
	with 
        {mul=invar(k/2);
	 _i64toa(mul,buf,10);
         printf("%s\n",buf);}*/

	}

    
		
					 
		   
 
      
