Ways to place 2 Non-Attacking Knights in chessboard

Last Updated : 6 Jun, 2026

Given two integers, n and m, denoting dimensions of a chessboard. The task is to count ways to place a black and a white knight on an n * m chessboard such that they do not attack each other. The knights have to be placed on different squares.

Note: A knight can move two squares horizontally and one square vertically (L shaped), or two squares vertically and one square horizontally (L shaped). The knights attack each other if one can reach the other in one move.

Examples:

Input: n = 2, m = 2
Output: 12
Explanation: The first Kniight can be placed in any of the 4 cells and the second knight can be be placed in any of the remaining 3 cells. For a Knight to attack. one dimension must be at least 3.

Input: n = 2, m = 3
Output: 26

Try It Yourself
redirect icon

[Naive Approach] Counting Valid Knight Moves – O(n * m) Time and O(1) Space

The idea is to count total ways to place two knights on the board and subtract the number of attacking pairs. For every cell, we calculate how many valid knight moves it can make (only in one direction set to avoid double counting).

  • Total ways two knights can be placed is (n*m)*(n*m - 1) [The first one at any square and the second on at any other square)
  • Traverse every cell and count valid knight moves using predefined directions
  • Each valid move contributes to attacking pairs count hence attacking positions increase by 2.
  • Return total pairs minus attacking pairs.
C++
#include <iostream>
using namespace std;

// Function returns the count
// of arrangements
int numOfWays(int n, int m)
{
    // A Knight can move in 8 directions, but 
    // we only take downward directions to avoid
    // counting same positions twice
    int x_axis[]{ -2, -1, 1, 2 };
    int y_axis[]{ 1, 2, 2, 1 };

    // Total ways to place two Knights
    long long total = m * n;
    total = total * (total - 1);    

    // Cunt attackig positions of a single
    // Knight
    long long ret = 0;
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            for (int k = 0; k < 4; ++k) {
                int x = i + x_axis[k], y = j + y_axis[k];
                if (x >= 0 && x < m && y >= 0 && y < n)
                   
                    // Since (i, j) and (x, y) are attacking
                    // positions for each other, we cannot
                    // place either of the two at any of these
                    ret += 2;
            }
        }
    }


    return total - ret;
}

// Driver code
int main()
{

    int n = 2, m = 3;

    cout << numOfWays(n, m) << endl;
    return 0;
}
Java
public class Main {
    // Function returns the count
    // of arrangements
    public static int numOfWays(int n, int m)
    {

        // A Knight can move in 8 directions, but
        // we only take downward directions to avoid
        // counting same positions twice
        int x_axis[] = { -2, -1, 1, 2 };
        int y_axis[] = { 1, 2, 2, 1 };

        // Total ways to place two Knights
        long total = m * n;
        total = total * (total - 1);

        // Count attacking positions of a single
        // Knight
        long ret = 0;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                for (int k = 0; k < 4; ++k) {
                    int x = i + x_axis[k], y
                                           = j + y_axis[k];
                    if (x >= 0 && x < m && y >= 0 && y < n)

                        // Since (i, j) and (x, y) are
                        // attacking positions for each
                        // other, we cannot place either of
                        // the two at any of these
                        ret += 2;
                }
            }
        }

        return (int)(total - ret);
    }

    // Driver code
    public static void main(String[] args)
    {
        int n = 2, m = 3;

        System.out.println(numOfWays(n, m));
    }
}
Python
def numOfWays(n, m):
    

    # A Knight can move in 8 directions, but 
    # we only take downward directions to avoid
    # counting same positions twice    
    x_axis = [-2, -1, 1, 2]
    y_axis = [1, 2, 2, 1]

    # Total ways to place two Knights
    total = m * n
    total = total * (total - 1)

    # Count attacking positions of a single
    # Knight
    ret = 0
    for i in range(m):
        for j in range(n):
            for k in range(4):
                x = i + x_axis[k]
                y = j + y_axis[k]
                if x >= 0 and x < m and y >= 0 and y < n:

                    # Since (i, j) and (x, y) are attacking
                    # positions for each other, we cannot
                    # place either of the two at any of these
                    ret += 2

    return total - ret

# Driver code
n = 2
m = 3

print(numOfWays(n, m))
C#
using System;

public class Program {
    
    // Function returns the count of arrangements
    public static int numOfWays(int n, int m)
    {

        // A Knight can move in 8 directions, but
        // we only take downward directions to avoid
        // counting same positions twice
        int[] x_axis = { -2, -1, 1, 2 };
        int[] y_axis = { 1, 2, 2, 1 };

        // Total ways to place two Knights
        long total = m * n;
        total = total * (total - 1);

        // Count attacking positions of a single
        // Knight
        long ret = 0;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                for (int k = 0; k < 4; ++k) {
                    int x = i + x_axis[k], y
                                           = j + y_axis[k];
                    if (x >= 0 && x < m && y >= 0 && y < n)

                        // Since (i, j) and (x, y) are
                        // attacking positions for each
                        // other, we cannot place either of
                        // the two at any of these
                        ret += 2;
                }
            }
        }

        return (int)(total - ret);
    }

    // Driver code
    public static void Main()
    {
        int n = 2, m = 3;

        Console.WriteLine(numOfWays(n, m));
    }
}
JavaScript
function numOfWays(n, m) {

    // A Knight can move in 8 directions, but 
    // we only take downward directions to avoid
    // counting same positions twice
    let x_axis = [-2, -1, 1, 2];
    let y_axis = [1, 2, 2, 1];

    // Total ways to place two Knights
    let total = m * n;
    total = total * (total - 1);

    // Count attacking positions of a single
    // Knight
    let ret = 0;
    for (let i = 0; i < m; ++i) {
        for (let j = 0; j < n; ++j) {
            for (let k = 0; k < 4; ++k) {
                let x = i + x_axis[k], y = j + y_axis[k];
                if (x >= 0 && x < m && y >= 0 && y < n)

                    // Since (i, j) and (x, y) are attacking
                    // positions for each other, we cannot
                    // place either of the two at any of these
                    ret += 2;
            }
        }
    }

    return total - ret;
}

// Driver code
let n = 2, m = 3;

console.log(numOfWays(n, m));

Output
26

[Optimal Approach] Using Mathematical Formula – O(1) Time and O(1) Space

The arrangements attacks where knight to move 2 steps in the horizontal direction and 1 step in the vertical. to 4 * (n - 2) * (m - 1) and similarly for 2 steps in the vertical direction and 1 step in the horizontal. Thus the answer will be Total possible arrangement - 4 * (n - 2) * (m - 1) - 4 * (n - 1) * (m - 2) which is (n*m)*(n*m - 1) - 4 * (n - 2) * (m - 1) - 4 * (n - 1) * (m - 2)

How does this work?

  • Consider knight to move 2 steps in the horizontal direction and 1 step in the vertical. So if we are at (i, j) after such moves we can reach at (i+2, j+1), (i+2, j-1), (i-2, j+1), (i-2, j-1). To have (i+2) inside the board we can have our positions 0 to n-3 i.e we have to leave the last two rows otherwise (i+2) will be out of the board. similarly for (i-2) range is possible if 2 to n-1.
  • Similarly for (j+1) range will be 0 to m-2, and for (j-1) range will be 1 to m-1 i.e one column less in each case.
  • So, arrangements in this case where attack possible equal to 4 * (n - 2) * (m - 1)
  • Similarly, if we consider two steps in vertical and one step in horizontal we will have one less row and two less col so that two knights can attack each other. We subtract this arrangement from total arrangements which is m * n * (n * n - 1). Hence the answer will be m * n * (m * n - 1) - 4 * (n - 2) * (m - 1) - 4 * (n - 1) * (m - 2)
C++
#include <iostream>
using namespace std;

// Function returns the count
// of arrangements
int numOfWays(int n, int m)
{

    // Total arrangements
    int ans = (n * m - 1) * n * m;

    if (n >= 1 && m >= 2) {
        
        // Attacks possible in one horizontal
        // and two vertical steps
        ans -= (4 * (n - 1) * (m - 2));
    }
    
    if (n >= 2 && m >= 1) {
        
        // Attacks possible in Two horizontal
        // and one vertical steps
        ans -= (4 * (n - 2) * (m - 1));
    }

    return ans;
}

// Driver code
int main()
{
    int n = 2, m = 3;
    cout << numOfWays(n, m) << endl;
    return 0;
}
Java
import java.util.*;

class GFG {

    // Function returns the count
    // of arrangements
    static int numOfWays(int n, int m)
    {

        // Total arrangements
        int ans = (n * m - 1) * n * m;

        if (n >= 1 && m >= 2) {
            // Attacks possible in one horizontal
            // and two vertical steps
            ans -= (4 * (n - 1) * (m - 2));
        }
        if (n >= 2 && m >= 1) {
            // Attacks possible in Two horizontal
            // and one vertical steps
            ans -= (4 * (n - 2) * (m - 1));
        }

        return ans;
    }

    // Driver code
    public static void main(String[] args)
    {

        int n = 2, m = 3;

        System.out.println(numOfWays(n, m));
    }
}
Python
# Function returns the count
# of arrangements
def numOfWays(n, m):

    # Total arrangements
    ans = (n * m - 1) * n * m

    if n >= 1 and m >= 2:
        # Attacks possible in one horizontal
        # and two vertical steps
        ans -= (4 * (n - 1) * (m - 2))

    if n >= 2 and m >= 1:
        # Attacks possible in Two horizontal
        # and one vertical steps
        ans -= (4 * (n - 2) * (m - 1))

    return ans


# Driver code
n, m = 2, 3
print(numOfWays(n, m))
C#
using System;

class GFG {

    // Function returns the count
    // of arrangements
    static int numOfWays(int n, int m)
    {

        int ans = (n * m - 1) * n * m;

        if (n >= 1 && m >= 2) {
            ans -= (4 * (n - 1) * (m - 2));
        }
        if (n >= 2 && m >= 1) {
            ans -= (4 * (n - 2) * (m - 1));
        }

        return ans;
    }

    // Driver code
    public static void Main()
    {

        int n = 2, m = 3;

        Console.WriteLine(numOfWays(n, m));
    }
}
JavaScript
// Function returns the count
// of arrangements
function numOfWays(n, m)
{

    // Total arrangements
    let ans = (n * m - 1) * n * m;

    if (n >= 1 && m >= 2) {
        // Attacks possible in one horizontal
        // and two vertical steps
        ans -= (4 * (n - 1) * (m - 2));
    }
    if (n >= 2 && m >= 1) {
        // Attacks possible in Two horizontal
        // and one vertical steps
        ans -= (4 * (n - 2) * (m - 1));
    }

    return ans;
}

// Driver code
let n = 2, m = 3;
console.log(numOfWays(n, m));

Output
26

 

Comment