#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>

#define NUM_TOTAL   12
#define NUM_COLUMN  4
#define NUM_CROP    5

typedef struct {
  char crop[ NUM_CROP ];
  char flag[ NUM_CROP ];
} st;


void chk( char *buf, int len )
{
  for ( int i = 0; i < len; i++ ) {
    printf( "%d ", *buf++ );
  }
  printf( "\n" );
}


bool next( st *g )
{
  for ( int i = NUM_CROP - 1; i >= 0; i-- )
    if ( NUM_TOTAL - NUM_CROP > g->crop[ i ] - i ) {
      g->crop[ i++ ] += 1;

      for ( ; i < NUM_CROP; i++ )
        g->crop[ i ] = g->crop[ i - 1 ] + 1;

      return true;
    }

  return false;
}


char flag_set( st *g, int index, char target_flag )
{
  char cur_flag = g->flag[ index ];
  g->flag[ index ] = target_flag;
  if ( cur_flag )
    for ( int i = 0; i < index; i++ )
      if ( g->flag[ i ] == cur_flag )
        g->flag[ i ] = target_flag;
  return 1;
}


bool continuity( st *g )
{
  char base_flag = 1;
  memset( g->flag, 0, NUM_CROP );

  for ( int j = 0; j < NUM_CROP; j++ ) {
    char connected = 0;

    for ( int i = 0; i < j; i++ ) {
      switch ( g->crop[ j ] - g->crop[ i ] ) {

        case NUM_COLUMN:
          connected += flag_set( g, j, g->flag[ i ] );
          break;

        case 1:
          if ( g->crop[ j ] % NUM_COLUMN )
            connected += flag_set( g, j, g->flag[ i ] );
          break;
      }
    }

    if ( ! connected ) g->flag[ j ] = base_flag++;
  }

  char cur_flag = g->flag[ 0 ];
  for ( int i = 1; i < NUM_CROP; i++ )
    if ( g->flag[ i ] != cur_flag )
      return false;

  return true;
}


int main()
{
  st g;
  for ( int i = 0; i < NUM_CROP; i++ ) {
    g.crop[ i ] = i;
  }

  int count = 0;
  do {
    if ( continuity( &g ) ) count += 1;
  } while ( next( &g ) );

  printf( "%d\n", count );
  return 0;
}