#include <iostream>
#include <array>
 
template<constexpr int N = 8>
class QueenProblemSolver {
public:
	QueenProblemSolver() {
		for (auto& i : is_occupied_column) {
			i = false;
		}
 
		for (auto& i : is_occupied_right_diagonal) {
			i = false;
		}
 
		for (auto& i : is_occupied_left_diagonal) {
			i = false;
		}
 
		placeQueen(0);
	}
 
private:	
	void placeQueen(int row) {
		for (auto col = 0; col < N; ++col) { // Iteratively try placing the row'th queen in every column
			auto right_diagonal = get_right_diagonal(row, col);
			auto left_diagonal = get_left_diagonal(row, col);
			if (!is_occupied_column[col]	// Column is not occupied by any other queen
				&& !is_occupied_right_diagonal[right_diagonal]	// Right diagonal is not occupied
				&& !is_occupied_left_diagonal[left_diagonal]	// Left diagonal is not occupied
			) {
				// row'th queen can be placed here
				placed_column_num[row] = col;
				is_occupied_column[col] = true;
				is_occupied_right_diagonal[right_diagonal] = true;
				is_occupied_left_diagonal[left_diagonal] = true;
 
				if ((row + 1) < N) {	// Recursively place the (row + 1)'th queen
					placeQueen(row + 1);
				} else {	// N queens have been placed, so we have found a solution
					printSolution();
				}
 
				// Clear the occupied flags since we have finished placing the queen at this position
				is_occupied_column[col] = false;
				is_occupied_right_diagonal[right_diagonal] = false;
				is_occupied_left_diagonal[left_diagonal] = false;
			}
		}
	}
 
	void printSolution() {
		++count;
		std::cout << count << ": ";
 
		// Print the occupied column in each row
		for (auto row = 0; row < N; ++row) {
			std::cout << placed_column_num[row] << " ";
		}
		std::cout << std::endl;
	}
 
	inline static constexpr auto get_num_diagonals() {
		return (1 << N) - 1;
	}
 
	inline int get_right_diagonal(int row, int col) const {
		return row + col;
	}
 
	inline int get_left_diagonal(int row, int col) const {
		return get_left_diagonal_offset() + (row - col);
	}
 
	inline constexpr auto get_left_diagonal_offset() const {
		return (1 << (N - 1)) - 2;
	}
 
	std::array<int, N> placed_column_num;
	std::array<bool, N> is_occupied_column;
	std::array<bool, get_num_diagonals()> is_occupied_right_diagonal;
	std::array<bool, get_num_diagonals()> is_occupied_left_diagonal;
	int count{0};
};
 
int main() {
	QueenProblemSolver<10> qp8;
}