class FlipBoard
  def initialize(size)
    raise ArgumentError.new() if size < 2

    @size = size
    @board = Array.new(size**2, 0)

    randomize_board
    loop do
      @target = generate_target
      break unless solved?
    end 

    
    @columns = [*'a'...('a'.ord+@size).chr]
    @rows = (1..@size).map(&:to_s)
  end

  

  def play
    moves = 0
    puts , target

    until solved? 
      puts , , self
      print 
      ans = $stdin.gets.strip

      if @columns.include? ans
        flip_column @columns.index(ans)
        moves += 1
      elsif @rows.include? ans
        flip_row @rows.index(ans)
        moves += 1
      else
        puts  + ans
      end
    end

    puts , , self
  end

  
  def target
    format_array @target
  end

  
  def to_s
    format_array @board
  end

  
  private

  def solved?
    @board == @target
  end

  
  def randomize_board
    (@size + rand(@size)).times do
      flip_bit rand(@size), rand(@size)
    end
  end

  
  def generate_target
    orig_board = @board.clone
    (@size + rand(@size)).times do 
      rand(2).zero?? flip_row( rand(@size) ): flip_column( rand(@size) )
    end
    target, @board = @board, orig_board
    target
  end

  def flip_row(row)
    @size.times {|col| flip_bit(row, col)}
  end

  def flip_column(col)
    @size.times {|row| flip_bit(row, col)}
  end

  def flip_bit(row, col)
    @board[@size * row + col] ^= 1
  end

  def format_array(ary)
    str =  + @columns.join() + 
    @size.times do |row|
      str <<  % @rows[row] + ary[@size*row, @size].join() + 
    end
    str
  end
end


begin
  FlipBoard.new(ARGV.shift.to_i).play
rescue => e
  puts e.message
end