<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

224. Little Queens
time limit per test: 0.75 sec.
memory limit per test: 65536 KB
input: standard
output: standard



Well, you might have heard about a curious boy Petya who likes to learn the number of ways one can put k identical chess pieces on a chessboard of size n× n so that no two of them are in the attacking positions. He have solved the problems for bishops, rooks and kings. Recently he has met Farmer John and told him about that.

Impressed FJ has decided to teach his cows to play chess. The first question Bessie asked on the first lesson was: "What about the number of ways one can put k queens on a chessboard of size n × n, so that no two of them are in the attacking positions?"

The queen can move diagonally, horizonatally and vertically, thus combining the properties of a bishop and a rook. Two queens are in the attacking positions if they are on the path of each other.

Input

The input file contains two integers n (1 ≤ n ≤ 10) and k (0 ≤ k ≤ n2).

Output

Print a line containing the total number of ways one can put the given number of queens on a chessboard of the given size so that no two of them are in attacking positions.

Sample test(s)

Input
Test #1

3 2

Test #2

4 4

Output
Test #1

8

Test #2

2
Author:	Andrew Stankevich
Resource:	Little Chess Pieces Series, SPb IFMO 2003-2004 Authumn Training Sessions
Date:	2003-10-08

<|response|>
1. Abridged Problem Statement  
Given an n×n chessboard (1 ≤ n ≤ 10) and an integer k (0 ≤ k ≤ n²), count the number of ways to place k identical queens so that no two attack each other (i.e. no two share a row, column, or diagonal).

2. Key Observations  
- A queen attacks along its row, its column, and both diagonals.  
- Since queens are identical, the order of placement doesn’t matter; we just count distinct sets of k squares.  
- We can build solutions row by row. In each row we either place exactly one queen or none.  
- If we ever need to place more queens than rows remaining, we can prune that branch.  
- Two classic ways to track attacks:  
  a. A 2D array `attacked[r][c]` counting how many queens attack square (r,c).  
  b. Three bitmasks for columns and the two diagonal directions, shifting them as we go down the board.

3. Full Solution Approach  
We describe the 2D-array “attacked” approach here; the Python bitmask variant appears in section 5.

- Maintain an n×n integer array `attacked`, initially all zeros.  
  attacked[r][c] > 0 means (r,c) is under attack by at least one placed queen.  
- Define a recursive function `dfs(row, k_left)` that returns the number of ways to place `k_left` queens in rows `row..n-1`.  
  1. If `k_left == 0`, we have placed all queens—count 1 valid configuration (any remaining rows are empty).  
  2. If `row == n` but `k_left > 0`, no more rows remain—count 0.  
  3. Prune: if `k_left > (n - row)`, we cannot place enough one-queen-per-row to reach k, so return 0.  
  4. First option: place no queen in this row → `ways = dfs(row+1, k_left)`.  
  5. Second option (if `k_left > 0`): for each column `c` in [0..n-1], if `attacked[row][c] == 0` (safe), then:  
     a. Mark all squares attacked by placing a queen at (row,c) by calling `mark(row,c,+1)`.  
     b. Add `dfs(row+1, k_left-1)` to `ways`.  
     c. Unmark with `mark(row,c,-1)` to backtrack.  
- The helper `mark(r,c,delta)` will iterate over the row, column, and the four diagonals passing through (r,c), adding `delta` (+1 or –1) to each attacked cell. We correct the triple-counting at (r,c) itself by subtracting `3*delta`.

Overall complexity is acceptable for n≤10 and k≤n², especially with the “must place ≤1 queen per row” pruning.

4. C++ Implementation with Detailed Comments  
```cpp
#include <bits/stdc++.h>
using namespace std;

int n, k;

// attacked[r][c] = how many queens attack (r,c)
// if zero, square is safe
vector<vector<int>> attacked;

// Mark or unmark the attack influence of a queen at (r,c)
// delta = +1 when placing, -1 when removing
void markQueen(int r, int c, int delta) {
    // mark row and column
    for (int i = 0; i < n; i++) {
        attacked[r][i] += delta;   // entire row
        attacked[i][c] += delta;   // entire column
    }
    // mark 4 diagonals
    for (int d = 1; d < n; d++) {
        if (r + d < n && c + d < n) attacked[r + d][c + d] += delta;
        if (r + d < n && c - d >= 0) attacked[r + d][c - d] += delta;
        if (r - d >= 0 && c + d < n) attacked[r - d][c + d] += delta;
        if (r - d >= 0 && c - d >= 0) attacked[r - d][c - d] += delta;
    }
    // The loops above each touched (r,c) once per direction (6 times total:
    // row, col, 4 diagonals). We want exactly one net change at (r,c),
    // so subtract extra 5*delta.
    attacked[r][c] -= 5 * delta;
}

// Return number of ways to place k_left queens in rows [row..n-1]
long long dfs(int row, int k_left) {
    // If we've placed all queens, one valid configuration
    if (k_left == 0) return 1;
    // No more rows but still queens to place: invalid
    if (row == n) return 0;
    // Prune: not enough rows remain to place one queen per row
    if (k_left > n - row) return 0;

    long long ways = 0;
    // Option 1: place no queen in this row
    ways += dfs(row + 1, k_left);

    // Option 2: place exactly one queen in this row, try each column
    for (int c = 0; c < n; c++) {
        if (attacked[row][c] == 0) {
            // place queen
            markQueen(row, c, +1);
            ways += dfs(row + 1, k_left - 1);
            // backtrack
            markQueen(row, c, -1);
        }
    }
    return ways;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> k;
    attacked.assign(n, vector<int>(n, 0));

    cout << dfs(0, k) << "\n";
    return 0;
}
```

5. Python Implementation with Detailed Comments  
This variant uses bitmasks for columns and diagonals plus memoization for speed.

```python
import sys
sys.setrecursionlimit(10**7)
from functools import lru_cache

def count_ways(n, k):
    # ALL columns mask: lower n bits = 1
    ALL = (1 << n) - 1

    @lru_cache(None)
    def dfs(row, placed, cols, d1, d2):
        # placed = number of queens so far
        # row = next row index
        # cols = bitmask of occupied columns
        # d1   = bitmask of main-diagonals under attack (row+col)
        # d2   = bitmask of anti-diagonals under attack (row-col + (n-1))
        
        # If we've placed k queens, any remaining rows are empty
        if placed == k:
            return 1
        # If out of rows but not enough queens placed
        if row == n:
            return 0
        # Prune: even if we place one queen per remaining row we can't reach k
        if placed + (n - row) < k:
            return 0
        
        ways = 0
        # Option 1: skip this row (no queen here)
        # Shift diagonals for the next row:
        #   main-diagonal mask shifts left by 1
        #   anti-diagonal mask shifts right by 1
        ways += dfs(row+1, placed,
                    cols,
                    (d1 << 1) & ALL, 
                    (d2 >> 1))
        
        # Option 2: place a queen in any free column
        attacked = cols | d1 | d2
        free = (~attacked) & ALL
        while free:
            # pick the lowest-set bit
            bit = free & -free
            free -= bit
            ways += dfs(row+1,
                        placed+1,
                        cols | bit,
                        ((d1 | bit) << 1) & ALL,
                        (d2 | bit) >> 1)
        return ways

    return dfs(0, 0, 0, 0, 0)

if __name__ == "__main__":
    n, k = map(int, sys.stdin.readline().split())
    print(count_ways(n, k))
```

Explanation of the bitmask fields:  
- `cols` has 1-bits in columns already occupied by queens.  
- `d1` (main diagonals) has 1-bits where row+col is under attack. To move from one row to the next, shift `d1` left by 1.  
- `d2` (anti-diagonals) has 1-bits where row−col+(n−1) is under attack; shift it right by 1 when going down.  
We combine them to find `attacked` positions, then iterate over each free bit to place the next queen. Memoization avoids recomputing identical states.