#include <iostream>
#include <random>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iterator>

enum colour_t { GREEN=0, RED=1, BLUE=2, BORDER_COLOUR = -1 };

// blue beats red, red beats green and green beats blue
bool less( colour_t pixel, colour_t neighbour )
{
    if( neighbour == BORDER_COLOUR ) return false ;
    else return (neighbour-pixel) == 1 || (neighbour-pixel) == -2 ;
}

std::ostream& operator<< ( std::ostream& stm, colour_t c )
{
    static constexpr char names[] = { '+', 'G', 'R', 'B' } ;
    return stm << names[c+1] ;
}

colour_t random_colour()
{
    static constexpr colour_t clrs[] = { GREEN, RED, BLUE } ;
    static std::mt19937 eng( std::time(nullptr) ) ;
    static std::uniform_int_distribution<int> dist(0,2) ;
    return clrs[ dist(eng) ] ;
}

using grid_type = std::vector< std::vector<colour_t> > ;

std::ostream& operator<< ( std::ostream& stm, const grid_type& grid )
{
    for( auto& row : grid )
    {
        for( auto c : row ) std::cout << c ;
        stm << '\n' ;
    }
    return stm ;
}

colour_t next( const grid_type& grid, std::size_t i, std::size_t j )
{
    colour_t clr = grid[i][j] ;
    if( clr == BORDER_COLOUR ) return BORDER_COLOUR ;
    else
    {
        for( int k : { j-1, j+1 } )
            if( less( clr, grid[i][k] ) ) return grid[i][k] ;
        for( int k : { i-1, i+1 } )
            if( less( clr, grid[k][j] ) ) return grid[k][j] ;
    }
    return clr ;
}

grid_type& transform( grid_type& grid )
{
    const auto cpy = grid ;

    for( std::size_t i = 0 ; i < grid.size() ; ++i )
        for( std::size_t j = 0 ; j < grid[i].size() ; ++j )
            grid[i][j] = next( cpy, i, j ) ;

    return grid ;
}

grid_type make_grid( std::size_t rows, std::size_t cols )
{
    rows += 2 ;
    cols += 2 ;

    grid_type grid(rows) ;
    for( auto& row : grid )
    {
        std::generate_n( std::back_inserter(row), cols, random_colour ) ;
        row.front() = row.back() = BORDER_COLOUR ;
    }
    std::fill_n( std::begin( grid.front() ), cols, BORDER_COLOUR ) ;
    std::fill_n( std::begin( grid.back() ), cols, BORDER_COLOUR ) ;

    return grid ;
}

int main()
{
    std::size_t rows ; std::cout << "rows? " ; std::cin >> rows ;
    std::size_t cols ; std::cout << "cols? " ; std::cin >> cols ;

    grid_type grid = make_grid( rows, cols ) ;
    std::vector< grid_type > gens ;

    while( std::find( gens.rbegin(), gens.rend(), grid ) == gens.rend() )
    {
        std::cout << grid << '\n' ;
        gens.push_back(grid) ;
        transform(grid) ;
    }

    const auto rbegin = gens.rbegin() ;
    std::cout << "cycle of length "
               << std::find( rbegin, gens.rend(), grid ) - rbegin + 1 << '\n' ;
}
