Find whether there is path between two cells in matrix

Last Updated : 10 Jun, 2026

Given a grid mat[][] of size n × n containing integers 0, 1, 2, and 3, determine whether a path exists from the source cell to the destination cell. Movement is allowed in four directions: up, down, left, and right.

  • 1 represents the source cell
  • 2 represents the destination cell
  • 3 represents a blank cell through which movement is allowed
  • 0 represents a wall that cannot be traversed

There is exactly one source and one destination in the grid.

Examples:  

Input: mat[][] = {{0,3,1,0}, {3,0,3,3}, {2,3,0,3}, {0,3,3,3}};
Output: true
Explanation: A path exists from source 1 to destination 2 through valid cells 3.

2

Input: mat[][] = {{1,0,3}, {0,0,0}, {3,3,2}};
Output: false
Explanation: No path exists as the source 1 is blocked and cannot reach destination 2.

2056958328
Try It Yourself
redirect icon

[Naive Approach] DFS / Backtracking – O(n^2 × 4^(n^2)) Time and O(n^2) Space

The idea is to first locate the source cell in the matrix and then use Depth First Search (DFS) with recursion to explore all possible paths from the source to the destination. From each cell, we try moving in all four directions (up, down, left, right) while ensuring we only visit valid and unvisited cells. The traversal continues recursively until the destination cell is found or all possible paths are exhausted.

  • Find the source cell (value 1) in the matrix.
  • Use DFS (recursion) starting from the source.
  • Mark the current cell as visited.
  • If the destination (2) is found, return true.
  • Explore all 4 directions (up, down, left, right).
  • Continue only on valid and unvisited cells.
  • If any path reaches the destination, return true; otherwise return false.
C++
using namespace std;

// Function to check whether a cell is within matrix bounds
bool isSafe(int x, int y, int n) {
    return (x >= 0 && x < n && y >= 0 && y < n);
}

// DFS function to explore all possible paths
bool dfs(vector<vector<int>>& mat, int x, int y, vector<vector<bool>>& visited) {
    int n = mat.size();

    // If out of bounds, or wall, or already visited → invalid path
    if (!isSafe(x, y, n) || mat[x][y] == 0 || visited[x][y])
        return false;

    // If destination cell is found → return true
    if (mat[x][y] == 2)
        return true;

    // Mark current cell as visited
    visited[x][y] = true;

    // Explore all 4 directions (up, down, left, right)
    bool up = dfs(mat, x - 1, y, visited);
    bool down = dfs(mat, x + 1, y, visited);
    bool left = dfs(mat, x, y - 1, visited);
    bool right = dfs(mat, x, y + 1, visited);

    // If any direction leads to destination → return true
    return up || down || left || right;
}

bool isPathPossible(vector<vector<int>>& mat) {
    int n = mat.size();

    // Visited array to avoid revisiting same cell
    vector<vector<bool>> visited(n, vector<bool>(n, false));

    // Find the source cell (value = 1)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (mat[i][j] == 1) {
                return dfs(mat, i, j, visited);
            }
        }
    }

    return false;
}

int main() {

    vector<vector<int>> mat = {
        {0, 3, 1, 0},
        {3, 0, 3, 3},
        {2, 3, 0, 3},
        {0, 3, 3, 3}
    };

    // Check if path exists
    bool ans = isPathPossible(mat);

    cout << (ans ? "true" : "false") << endl;

    return 0;
}
Java
class GFG {

    // Function to check whether a cell is within matrix bounds
    static boolean isSafe(int x, int y, int n) {
        return (x >= 0 && x < n && y >= 0 && y < n);
    }

    // DFS function to explore all possible paths
    static boolean dfs(int[][] mat, int x, int y, boolean[][] visited) {
        int n = mat.length;

        // If out of bounds, or wall, or already visited → invalid path
        if (!isSafe(x, y, n) || mat[x][y] == 0 || visited[x][y])
            return false;

        // If destination cell is found → return true
        if (mat[x][y] == 2)
            return true;

        // Mark current cell as visited
        visited[x][y] = true;

        // Explore all 4 directions (up, down, left, right)
        boolean up = dfs(mat, x - 1, y, visited);
        boolean down = dfs(mat, x + 1, y, visited);
        boolean left = dfs(mat, x, y - 1, visited);
        boolean right = dfs(mat, x, y + 1, visited);

        // If any direction leads to destination → return true
        return up || down || left || right;
    }

    static boolean isPathPossible(int[][] mat) {
        int n = mat.length;

        // Visited array to avoid revisiting same cell
        boolean[][] visited = new boolean[n][n];

        // Find the source cell (value = 1)
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (mat[i][j] == 1) {
                    return dfs(mat, i, j, visited);
                }
            }
        }

        return false;
    }

    public static void main(String[] args) {

        int[][] mat = {
            {0, 3, 1, 0},
            {3, 0, 3, 3},
            {2, 3, 0, 3},
            {0, 3, 3, 3}
        };

        // Check if path exists
        boolean res = isPathPossible(mat);

        System.out.println(res);
    }
}
Python
# Function to check whether a cell is within matrix bounds
def isSafe(x, y, n):
    return (x >= 0 and x < n and y >= 0 and y < n)

# DFS function to explore all possible paths
def dfs(mat, x, y, visited):
    n = len(mat)

    # If out of bounds, or wall, or already visited → invalid path
    if not isSafe(x, y, n) or mat[x][y] == 0 or visited[x][y]:
        return False

    # If destination cell is found → return true
    if mat[x][y] == 2:
        return True

    # Mark current cell as visited
    visited[x][y] = True

    # Explore all 4 directions (up, down, left, right)
    up = dfs(mat, x - 1, y, visited)
    down = dfs(mat, x + 1, y, visited)
    left = dfs(mat, x, y - 1, visited)
    right = dfs(mat, x, y + 1, visited)

    # If any direction leads to destination → return true
    return up or down or left or right

def isPathPossible(mat):
    n = len(mat)

    # Visited array to avoid revisiting same cell
    visited = [[False for _ in range(n)] for _ in range(n)]

    # Find the source cell (value = 1)
    for i in range(n):
        for j in range(n):
            if mat[i][j] == 1:
                return dfs(mat, i, j, visited)

    return False


if __name__ == "__main__":

    mat = [
        [0, 3, 1, 0],
        [3, 0, 3, 3],
        [2, 3, 0, 3],
        [0, 3, 3, 3]
    ]

    # Check if path exists
    res = isPathPossible(mat)

    print(str(res).lower())
C#
using System;

class GFG
{
    // Function to check whether a cell is within matrix bounds
    static bool isSafe(int x, int y, int n)
    {
        return (x >= 0 && x < n && y >= 0 && y < n);
    }

    // DFS function to explore all possible paths
    static bool dfs(int[,] mat, int x, int y, bool[,] visited)
    {
        int n = mat.GetLength(0);

        // If out of bounds, or wall, or already visited → invalid path
        if (!isSafe(x, y, n) || mat[x, y] == 0 || visited[x, y])
            return false;

        // If destination cell is found → return true
        if (mat[x, y] == 2)
            return true;

        // Mark current cell as visited
        visited[x, y] = true;

        // Explore all 4 directions (up, down, left, right)
        bool up = dfs(mat, x - 1, y, visited);
        bool down = dfs(mat, x + 1, y, visited);
        bool left = dfs(mat, x, y - 1, visited);
        bool right = dfs(mat, x, y + 1, visited);

        // If any direction leads to destination → return true
        return up || down || left || right;
    }

    static bool isPathPossible(int[,] mat)
    {
        int n = mat.GetLength(0);

        // Visited array to avoid revisiting same cell
        bool[,] visited = new bool[n, n];

        // Find the source cell (value = 1)
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (mat[i, j] == 1)
                {
                    return dfs(mat, i, j, visited);
                }
            }
        }

        return false;
    }

    static void Main(string[] args)
    {
        int[,] mat = {
            {0, 3, 1, 0},
            {3, 0, 3, 3},
            {2, 3, 0, 3},
            {0, 3, 3, 3}
        };

        // Check if path exists
        bool res = isPathPossible(mat);

        Console.WriteLine(res.ToString().ToLower());
    }
}
JavaScript
// Function to check whether a cell is within matrix bounds
function isSafe(x, y, n) {
    return (x >= 0 && x < n && y >= 0 && y < n);
}

// DFS function to explore all possible paths
function dfs(mat, x, y, visited) {
    let n = mat.length;

    // If out of bounds, or wall, or already visited → invalid path
    if (!isSafe(x, y, n) || mat[x][y] == 0 || visited[x][y])
        return false;

    // If destination cell is found → return true
    if (mat[x][y] == 2)
        return true;

    // Mark current cell as visited
    visited[x][y] = true;

    // Explore all 4 directions (up, down, left, right)
    let up = dfs(mat, x - 1, y, visited);
    let down = dfs(mat, x + 1, y, visited);
    let left = dfs(mat, x, y - 1, visited);
    let right = dfs(mat, x, y + 1, visited);

    // If any direction leads to destination → return true
    return up || down || left || right;
}

// Main function to check if path exists from source to destination
function isPathPossible(mat) {
    let n = mat.length;

    // Visited array to avoid revisiting same cell
    let visited = Array.from({ length: n }, () => Array(n).fill(false));

    // Find the source cell (value = 1)
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            if (mat[i][j] == 1) {
                return dfs(mat, i, j, visited);
            }
        }
    }

    return false;
}

// Drive code
let mat = [
    [0, 3, 1, 0],
    [3, 0, 3, 3],
    [2, 3, 0, 3],
    [0, 3, 3, 3]
];

// Check if path exists
let res = isPathPossible(mat);

console.log(res);

Output
true

[Better Approach] BFS (Graph/Level Order Traversal) - O(n^2) Time and O(n^2) Space

The idea is to treat each cell of the matrix as a node in a graph and connect it with its adjacent cells (up, down, left, right) if movement is allowed. We first convert the matrix into a graph representation where each valid cell becomes a vertex. Then we perform Breadth First Search (BFS) starting from the source cell. If during traversal we reach the destination cell, we return true; otherwise, if BFS finishes without reaching it, we return false.

C++
using namespace std;

class Graph {
public:
    int V;
    vector<vector<int>> adj;

    // Constructor to initialize graph with V vertices
    Graph(int V) {
        this->V = V;
        adj.resize(V);
    }

    // Function to add edge between nodes
    void addEdge(int s, int d) {
        adj[s].push_back(d);
    }

    // BFS to check if path exists from source to destination
    bool BFS(int s, int d) {

        // If source is same as destination
        if (s == d) return true;

        vector<bool> visited(V, false);
        queue<int> q;

        // Start BFS from source node
        visited[s] = true;
        q.push(s);

        while (!q.empty()) {

            int node = q.front();
            q.pop();

            // Traverse all adjacent nodes
            for (int next : adj[node]) {

                // If destination is reached
                if (next == d) return true;

                // If not visited, mark and push to queue
                if (!visited[next]) {
                    visited[next] = true;
                    q.push(next);
                }
            }
        }

        // Destination not reachable
        return false;
    }
};

// Function to check boundary and valid cell
bool isSafe(int i, int j, int N, vector<vector<int>>& mat) {
    return (i >= 0 && i < N && j >= 0 && j < N && mat[i][j] != 0);
}

bool isPathPossible(vector<vector<int>>& mat) {

    int N = mat.size();

    // total nodes
    int V = N * N + 1;
    Graph g(V);

    int s = -1, d = -1;

    // node indexing starts from 1
    int k = 1;

    // Build graph from matrix
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {

            // If cell is not blocked
            if (mat[i][j] != 0) {

                // Right neighbor
                if (isSafe(i, j + 1, N, mat))
                    g.addEdge(k, k + 1);

                // Left neighbor
                if (isSafe(i, j - 1, N, mat))
                    g.addEdge(k, k - 1);

                // Down neighbor
                if (isSafe(i + 1, j, N, mat))
                    g.addEdge(k, k + N);

                // Up neighbor
                if (isSafe(i - 1, j, N, mat))
                    g.addEdge(k, k - N);
            }

            // Store source cell
            if (mat[i][j] == 1) s = k;

            // Store destination cell
            if (mat[i][j] == 2) d = k;

            k++;
        }
    }

    // Run BFS to check reachability
    return g.BFS(s, d);
}

int main() {

    vector<vector<int>> mat = {
        {0, 3, 0, 1},
        {3, 0, 3, 3},
        {2, 3, 3, 3},
        {0, 3, 3, 3}
    };

    cout << (isPathPossible(mat) ? "true" : "false") << endl;

    return 0;
}
Java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

class Graph {

    int V;
    List<List<Integer>> adj;

    // Constructor to initialize graph with V vertices
    Graph(int V) {
        this.V = V;
        adj = new ArrayList<>();
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<>());
        }
    }

    // Function to add edge between nodes
    void addEdge(int s, int d) {
        adj.get(s).add(d);
    }

    // BFS to check if path exists from source to destination
    boolean BFS(int s, int d) {

        // If source is same as destination
        if (s == d) return true;

        boolean[] visited = new boolean[V];
        Queue<Integer> q = new LinkedList<>();

        // Start BFS from source node
        visited[s] = true;
        q.add(s);

        while (!q.isEmpty()) {

            int node = q.poll();

            // Traverse all adjacent nodes
            for (int next : adj.get(node)) {

                // If destination is reached
                if (next == d) return true;

                // If not visited, mark and push to queue
                if (!visited[next]) {
                    visited[next] = true;
                    q.add(next);
                }
            }
        }

        // Destination not reachable
        return false;
    }
}

class GFG {

    // Function to check boundary and valid cell
    static boolean isSafe(int i, int j, int N, int[][] mat) {
        return (i >= 0 && i < N && j >= 0 && j < N && mat[i][j] != 0);
    }

    static boolean isPathPossible(int[][] mat) {

        int N = mat.length;

        // total nodes
        int V = N * N + 1;
        Graph g = new Graph(V);

        int s = -1, d = -1;

        // node indexing starts from 1
        int k = 1;

        // Build graph from matrix
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {

                // If cell is not blocked
                if (mat[i][j] != 0) {

                    // Right neighbor
                    if (isSafe(i, j + 1, N, mat))
                        g.addEdge(k, k + 1);

                    // Left neighbor
                    if (isSafe(i, j - 1, N, mat))
                        g.addEdge(k, k - 1);

                    // Down neighbor
                    if (isSafe(i + 1, j, N, mat))
                        g.addEdge(k, k + N);

                    // Up neighbor
                    if (isSafe(i - 1, j, N, mat))
                        g.addEdge(k, k - N);
                }

                // Store source cell
                if (mat[i][j] == 1) s = k;

                // Store destination cell
                if (mat[i][j] == 2) d = k;

                k++;
            }
        }

        // Run BFS to check reachability
        return g.BFS(s, d);
    }

    public static void main(String[] args) {

        int[][] mat = {
            {0, 3, 0, 1},
            {3, 0, 3, 3},
            {2, 3, 3, 3},
            {0, 3, 3, 3}
        };

        System.out.println(isPathPossible(mat));
    }
}
Python
from collections import deque

class Graph:

    # Constructor to initialize graph with V vertices
    def __init__(self, V):
        self.V = V
        self.adj = [[] for _ in range(V)]

    # Function to add edge between nodes
    def addEdge(self, s, d):
        self.adj[s].append(d)

    # BFS to check if path exists from source to destination
    def BFS(self, s, d):

        # If source is same as destination
        if s == d:
            return True

        visited = [False] * self.V
        q = deque()

        # Start BFS from source node
        visited[s] = True
        q.append(s)

        while q:

            node = q.popleft()

            # Traverse all adjacent nodes
            for next_node in self.adj[node]:

                # If destination is reached
                if next_node == d:
                    return True

                # If not visited, mark and push to queue
                if not visited[next_node]:
                    visited[next_node] = True
                    q.append(next_node)

        # Destination not reachable
        return False


# Function to check boundary and valid cell
def isSafe(i, j, N, mat):
    return (0 <= i < N and 0 <= j < N and mat[i][j] != 0)


def isPathPossible(mat):

    N = len(mat)

    # total nodes
    V = N * N + 1
    g = Graph(V)

    s = d = -1

    # node indexing starts from 1
    k = 1

    # Build graph from matrix
    for i in range(N):
        for j in range(N):

            # If cell is not blocked
            if mat[i][j] != 0:

                # Right neighbor
                if isSafe(i, j + 1, N, mat):
                    g.addEdge(k, k + 1)

                # Left neighbor
                if isSafe(i, j - 1, N, mat):
                    g.addEdge(k, k - 1)

                # Down neighbor
                if isSafe(i + 1, j, N, mat):
                    g.addEdge(k, k + N)

                # Up neighbor
                if isSafe(i - 1, j, N, mat):
                    g.addEdge(k, k - N)

            # Store source cell
            if mat[i][j] == 1:
                s = k

            # Store destination cell
            if mat[i][j] == 2:
                d = k

            k += 1

    # Run BFS to check reachability
    return g.BFS(s, d)


if __name__ == "__main__":

    mat = [
        [0, 3, 0, 1],
        [3, 0, 3, 3],
        [2, 3, 3, 3],
        [0, 3, 3, 3]
    ]

    print(str(isPathPossible(mat)).lower())
C#
using System;
using System.Collections.Generic;

class Graph {

    public int V;
    public List<List<int>> adj;

    // Constructor to initialize graph with V vertices
    public Graph(int V) {
        this.V = V;
        adj = new List<List<int>>();
        for (int i = 0; i < V; i++) {
            adj.Add(new List<int>());
        }
    }

    // Function to add edge between nodes
    public void AddEdge(int s, int d) {
        adj[s].Add(d);
    }

    // BFS to check if path exists from source to destination
    public bool BFS(int s, int d) {

        // If source is same as destination
        if (s == d) return true;

        bool[] visited = new bool[V];
        Queue<int> q = new Queue<int>();

        // Start BFS from source node
        visited[s] = true;
        q.Enqueue(s);

        while (q.Count > 0) {

            int node = q.Dequeue();

            // Traverse all adjacent nodes
            foreach (int next in adj[node]) {

                // If destination is reached
                if (next == d) return true;

                // If not visited, mark and push to queue
                if (!visited[next]) {
                    visited[next] = true;
                    q.Enqueue(next);
                }
            }
        }

        // Destination not reachable
        return false;
    }
}

class GFG {

    // Function to check boundary and valid cell
    static bool IsSafe(int i, int j, int N, int[,] mat) {
        return (i >= 0 && i < N && j >= 0 && j < N && mat[i,j] != 0);
    }

    static bool IsPathPossible(int[,] mat) {

        int N = mat.GetLength(0);

        // total nodes
        int V = N * N + 1;
        Graph g = new Graph(V);

        int s = -1, d = -1;

        // node indexing starts from 1
        int k = 1;

        // Build graph from matrix
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {

                // If cell is not blocked
                if (mat[i,j] != 0) {

                    // Right neighbor
                    if (IsSafe(i, j + 1, N, mat))
                        g.AddEdge(k, k + 1);

                    // Left neighbor
                    if (IsSafe(i, j - 1, N, mat))
                        g.AddEdge(k, k - 1);

                    // Down neighbor
                    if (IsSafe(i + 1, j, N, mat))
                        g.AddEdge(k, k + N);

                    // Up neighbor
                    if (IsSafe(i - 1, j, N, mat))
                        g.AddEdge(k, k - N);
                }

                // Store source cell
                if (mat[i,j] == 1) s = k;

                // Store destination cell
                if (mat[i,j] == 2) d = k;

                k++;
            }
        }

        // Run BFS to check reachability
        return g.BFS(s, d);
    }

    public static void Main() {

        int[,] mat = {
            {0, 3, 0, 1},
            {3, 0, 3, 3},
            {2, 3, 3, 3},
            {0, 3, 3, 3}
        };

        Console.WriteLine(IsPathPossible(mat));
    }
}
JavaScript
class Graph {

    constructor(V) {
        // Constructor to initialize graph with V vertices
        this.V = V;
        this.adj = Array.from({ length: V }, () => []);
    }

    // Function to add edge between nodes
    addEdge(s, d) {
        this.adj[s].push(d);
    }

    // BFS to check if path exists from source to destination
    BFS(s, d) {

        // If source is same as destination
        if (s === d) return true;

        let visited = Array(this.V).fill(false);
        let q = [];

        // Start BFS from source node
        visited[s] = true;
        q.push(s);

        while (q.length > 0) {

            let node = q.shift();

            // Traverse all adjacent nodes
            for (let next of this.adj[node]) {

                // If destination is reached
                if (next === d) return true;

                // If not visited, mark and push to queue
                if (!visited[next]) {
                    visited[next] = true;
                    q.push(next);
                }
            }
        }

        // Destination not reachable
        return false;
    }
}

// Function to check boundary and valid cell
function isSafe(i, j, N, mat) {
    return (i >= 0 && i < N && j >= 0 && j < N && mat[i][j] !== 0);
}

function isPathPossible(mat) {

    let N = mat.length;

    // total nodes
    let V = N * N + 1;
    let g = new Graph(V);

    let s = -1, d = -1;

    // node indexing starts from 1
    let k = 1;

    // Build graph from matrix
    for (let i = 0; i < N; i++) {
        for (let j = 0; j < N; j++) {

            // If cell is not blocked
            if (mat[i][j] !== 0) {

                // Right neighbor
                if (isSafe(i, j + 1, N, mat))
                    g.addEdge(k, k + 1);

                // Left neighbor
                if (isSafe(i, j - 1, N, mat))
                    g.addEdge(k, k - 1);

                // Down neighbor
                if (isSafe(i + 1, j, N, mat))
                    g.addEdge(k, k + N);

                // Up neighbor
                if (isSafe(i - 1, j, N, mat))
                    g.addEdge(k, k - N);
            }

            // Store source cell
            if (mat[i][j] === 1) s = k;

            // Store destination cell
            if (mat[i][j] === 2) d = k;

            k++;
        }
    }

    // Run BFS to check reachability
    return g.BFS(s, d);
}

// Driver code
let mat = [
    [0, 3, 0, 1],
    [3, 0, 3, 3],
    [2, 3, 3, 3],
    [0, 3, 3, 3]
];

console.log(isPathPossible(mat));

Output
true

[Expected Approach ] BFS (Matrix Traversal without Visited Array) - O(n²) Time and O(1) Space

This approach directly performs BFS on the matrix without using a separate visited array. Instead, visited cells are marked by modifying their values in the matrix.

  • Find the source cell (value 1) and push it into a queue
  • Define four possible movement directions (up, down, left, right)
  • Perform BFS traversal using the queue
  • For each popped cell, check if it is the destination (2) and return true
  • Explore all valid neighboring cells (within bounds and not a wall 0)
  • Mark visited cells by updating their value (e.g., change to 1)
  • Push valid neighbors into the queue
  • If BFS finishes without finding the destination, return false
C++
#include <bits/stdc++.h>
using namespace std;

// Function to check whether the cell is within matrix bounds
bool isValid(int x, int y, int n, int m)
{
    return (x >= 0 && x < n && y >= 0 && y < m);
}

bool isPathPossible(vector<vector<int>> &mat)
{
    int n = mat.size();
    int m = mat[0].size();

    // queue for BFS traversal
    queue<pair<int, int>> q;

    // push source cell(s)
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (mat[i][j] == 1)
            {
                q.push({i, j});
            }
        }
    }

    int dx[4] = {-1, 0, 1, 0};
    int dy[4] = {0, -1, 0, 1};

    while (!q.empty())
    {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();

        // explore 4 directions
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];

            // check boundary
            if (isValid(nx, ny, n, m))
            {

                // destination found
                if (mat[nx][ny] == 2)
                    return true;

                // visit valid path cell
                if (mat[nx][ny] == 3)
                {

                    // mark visited
                    mat[nx][ny] = 1;
                    q.push({nx, ny});
                }
            }
        }
    }

    return false;
}

int main()
{

    vector<vector<int>> mat = {{0, 3, 0, 1}, {3, 0, 3, 3}, {2, 3, 0, 3}, {0, 3, 3, 3}};

    cout << (isPathPossible(mat) ? "true" : "false") << endl;

    return 0;
}
Java
import java.io.*;
import java.util.*;


class GFG {

// Function to check whether the cell is within matrix bounds
    static boolean isValid(int x, int y, int n, int m) {
        return (x >= 0 && x < n && y >= 0 && y < m);
    }

    static boolean isPathPossible(int[][] mat) {

        int n = mat.length;
        int m = mat[0].length;

        // queue for BFS traversal
        Queue<int[]> q = new LinkedList<>();

        // push source cell(s)
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 1) {
                    q.add(new int[]{i, j});
                }
            }
        }

        int[] dx = {-1, 0, 1, 0};
        int[] dy = {0, -1, 0, 1};

        while (!q.isEmpty()) {
            int[] cell = q.poll();
            int x = cell[0];
            int y = cell[1];

            // explore 4 directions
            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];

                // check boundary
                if (isValid(nx, ny, n, m)) {

                    // destination found
                    if (mat[nx][ny] == 2)
                        return true;

                    // visit valid path cell
                    if (mat[nx][ny] == 3) {

                        // mark visited
                        mat[nx][ny] = 1;
                        q.add(new int[]{nx, ny});
                    }
                }
            }
        }

        return false;
    }

    public static void main(String[] args) {

        int[][] mat = {
            {0, 3, 0, 1},
            {3, 0, 3, 3},
            {2, 3, 0, 3},
            {0, 3, 3, 3}
        };

        System.out.println(isPathPossible(mat));
    }
}
Python
from collections import deque

# Function to check whether the cell is within matrix bounds
def isValid(x, y, n, m):
    return (x >= 0 and x < n and y >= 0 and y < m)

def isPathPossible(mat):
    n = len(mat)
    m = len(mat[0])

    # queue for BFS traversal
    q = deque()

    # push source cell(s)
    for i in range(n):
        for j in range(m):
            if mat[i][j] == 1:
                q.append((i, j))

    dx = [-1, 0, 1, 0]
    dy = [0, -1, 0, 1]

    while q:
        x, y = q.popleft()

        # explore 4 directions
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]

            # check boundary
            if isValid(nx, ny, n, m):

                # destination found
                if mat[nx][ny] == 2:
                    return True

                # visit valid path cell
                if mat[nx][ny] == 3:

                    # mark visited
                    mat[nx][ny] = 1
                    q.append((nx, ny))

    return False


mat = [
    [0, 3, 0, 1],
    [3, 0, 3, 3],
    [2, 3, 0, 3],
    [0, 3, 3, 3]
]

print(str(isPathPossible(mat)).lower())
C#
using System;
using System.Collections.Generic;

class GFG
{
    // Function to check whether the cell is within matrix bounds
    static bool isValid(int x, int y, int n, int m)
    {
        return (x >= 0 && x < n && y >= 0 && y < m);
    }

    static bool isPathPossible(int[][] mat)
    {
        int n = mat.Length;
        int m = mat[0].Length;

        // queue for BFS traversal
        Queue<Tuple<int, int>> q = new Queue<Tuple<int, int>>();

        // push source cell(s)
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (mat[i][j] == 1)
                {
                    q.Enqueue(Tuple.Create(i, j));
                }
            }
        }

        int[] dx = { -1, 0, 1, 0 };
        int[] dy = { 0, -1, 0, 1 };

        while (q.Count > 0)
        {
            var cell = q.Dequeue();
            int x = cell.Item1;
            int y = cell.Item2;

            // explore 4 directions
            for (int i = 0; i < 4; i++)
            {
                int nx = x + dx[i];
                int ny = y + dy[i];

                // check boundary
                if (isValid(nx, ny, n, m))
                {
                    // destination found
                    if (mat[nx][ny] == 2)
                        return true;

                    // visit valid path cell
                    if (mat[nx][ny] == 3)
                    {
                        // mark visited
                        mat[nx][ny] = 1;
                        q.Enqueue(Tuple.Create(nx, ny));
                    }
                }
            }
        }

        return false;
    }

    static void Main()
    {
        int[][] mat = new int[][]
        {
            new int[] {0, 3, 0, 1},
            new int[] {3, 0, 3, 3},
            new int[] {2, 3, 0, 3},
            new int[] {0, 3, 3, 3}
        };

        Console.WriteLine(isPathPossible(mat).ToString().ToLower());
    }
}
JavaScript
// Function to check whether the cell is within matrix bounds
function isValid(x, y, n, m) {
    return (x >= 0 && x < n && y >= 0 && y < m);
}

function isPathPossible(mat) {

    let n = mat.length;
    let m = mat[0].length;

    // queue for BFS traversal
    let q = [];

    // push source cell(s)
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            if (mat[i][j] === 1) {
                q.push([i, j]);
            }
        }
    }

    let dx = [-1, 0, 1, 0];
    let dy = [0, -1, 0, 1];

    while (q.length > 0) {
        let [x, y] = q.shift();

        // explore 4 directions
        for (let i = 0; i < 4; i++) {
            let nx = x + dx[i];
            let ny = y + dy[i];

            // check boundary
            if (isValid(nx, ny, n, m)) {

                // destination found
                if (mat[nx][ny] === 2)
                    return true;

                // visit valid path cell
                if (mat[nx][ny] === 3) {

                    // mark visited
                    mat[nx][ny] = 1;
                    q.push([nx, ny]);
                }
            }
        }
    }

    return false;
}

// Driver code
let mat = [
    [0, 3, 0, 1],
    [3, 0, 3, 3],
    [2, 3, 0, 3],
    [0, 3, 3, 3]
];

console.log(isPathPossible(mat).toString());

Output
true
Comment