// Java program to find distance of nearest
// cell having 1 in a binary matrix.
import java.util.*;
 
class gfg {
 
  static int N = 3;
  static int M = 4;
  static int MAX = 500;
 
  // Making a class of graph with bfs function.
  static class graph {
 
    ArrayList<ArrayList<Integer> > g;
    int n, m;
 
    graph(int a, int b)
    {
      g = new ArrayList<>();
      n = a;
      m = b;
    }
 
    // Function to create graph with N*M nodes
    // considering each cell as a node and each
    // boundary as an edge.
    void createGraph()
    {
      int k = 1; // A number to be assigned to a cell
      for (int i = 0; i <= MAX; i++) {
        g.add(new ArrayList<>());
      }
 
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
          // If last row, then add edge on right
          // side.
          if (i == n) {
            // If not bottom right cell.
            if (j != m) {
              g.get(k).add(k + 1);
              g.get(k + 1).add(k);
            }
          }
 
          // If last column, then add edge toward
          // down.
          else if (j == m) {
            g.get(k).add(k + m);
            g.get(k + m).add(k);
          }
 
          // Else makes an edge in all four
          // directions.
          else {
            g.get(k).add(k + 1);
            g.get(k + 1).add(k);
            g.get(k).add(k + m);
            g.get(k + m).add(k);
          }
 
          k++;
        }
      }
    }
 
    // BFS function to find minimum distance
    void bfs(boolean visit[], int dist[],
             Queue<Integer> q)
    {
      while (!q.isEmpty()) {
        int temp = q.peek();
        q.remove();
 
        for (int i = 0; i < g.get(temp).size();
             i++) {
          if (visit[g.get(temp).get(i)] != true) {
            dist[g.get(temp).get(i)] = Math.min(
              dist[g.get(temp).get(i)],
              dist[temp] + 1);
 
            q.add(g.get(temp).get(i));
            visit[g.get(temp).get(i)] = true;
          }
        }
      }
    }
 
    // Printing the solution
    void print(int dist[])
    {
      for (int i = 1, c = 1; i <= n * m; i++, c++) {
        System.out.print(dist[i] + " ");
 
        if (c % m == 0)
          System.out.println();
      }
    }
  };
 
  // Find minimum distance
  static void findMinDistance(boolean mat[][])
  {
    // Creating a graph with nodes values assigned
    // from 1 to N x M and matrix adjacent.
    graph g1 = new graph(N, M);
    g1.createGraph();
 
    // To store minimum distance
    int dist[] = new int[MAX];
 
    // To mark each node as visited or not in BFS
    boolean visit[] = new boolean[MAX];
 
    // Initialising the value of distance and visit.
    for (int i = 1; i <= M * N; i++) {
      dist[i] = Integer.MAX_VALUE;
      visit[i] = false;
    }
 
    // Inserting nodes whose value in matrix
    // is 1 in the queue.
    int k = 1;
    Queue<Integer> q = new ArrayDeque<>();
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < M; j++) {
        if (mat[i][j]) {
          dist[k] = 0;
          visit[k] = true;
          q.add(k);
        }
        k++;
      }
    }
 
    // Calling for Bfs with given Queue.
    g1.bfs(visit, dist, q);
 
    // Printing the solution.
    g1.print(dist);
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int matrix[][] = { { 0, 0, 0, 1 },
                      { 0, 0, 1, 1 },
                      { 0, 1, 1, 0 } };
    boolean[][] mat = new boolean[N][M];
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < M; j++) {
        if (matrix[i][j] == 1)
          mat[i][j] = true;
      }
    }
     
    // Function call
    findMinDistance(mat);
  }
}
 
// This code is contributed by karandeep1234

Time complexity: quadratic
Space complexity: quadratic