void main() {
    int rows = getNumberOfRows();
    int cols = getNumberOfColumns();
          
    boolean[][] cells = new boolean[rows][cols];
    
    while (true) {
              
        // calc new generation
        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                int number = numberOfLivingNeighbors(r, c);
                if (isLiving(r, c)) {
                   cells[r][c] = (number == 2 || number == 3);
                } else {
                   cells[r][c] = (number == 3);
                }
            }
        }
        
        // print new generation
        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                if (cells[r][c]) {
                    setLiving(r, c);
                } else {
                    setDead(r, c);
                }
            }
        }
        
    }
}

int numberOfLivingNeighbors(int row, int col) {
    int rows = getNumberOfRows();
    int cols = getNumberOfColumns();
    int number = 0;
    for (int r = -1; r <= 1; r++) {
        int rc = (row + r + rows) % rows;
        for (int c = -1; c <= 1; c++) {
            int cc = (col + c + cols) % cols;
            if (!(rc == row && cc == col) && 
                   isLiving(rc, cc)) {
                number++;
            }
        }
    }
    return number;
}
