<p>There is an <code>m x n</code> rectangular island that borders both the <strong>Pacific Ocean</strong> and <strong>Atlantic Ocean</strong>. The <strong>Pacific Ocean</strong> touches the island&#39;s left and top edges, and the <strong>Atlantic Ocean</strong> touches the island&#39;s right and bottom edges.</p>

<p>The island is partitioned into a grid of square cells. You are given an <code>m x n</code> integer matrix <code>heights</code> where <code>heights[r][c]</code> represents the <strong>height above sea level</strong> of the cell at coordinate <code>(r, c)</code>.</p>

<p>The island receives a lot of rain, and the rain water can flow to neighboring cells directly north, south, east, and west if the neighboring cell&#39;s height is <strong>less than or equal to</strong> the current cell&#39;s height. Water can flow from any cell adjacent to an ocean into the ocean.</p>

<p>Return <em>a <strong>2D list</strong> of grid coordinates </em><code>result</code><em> where </em><code>result[i] = [r<sub>i</sub>, c<sub>i</sub>]</code><em> denotes that rain water can flow from cell </em><code>(r<sub>i</sub>, c<sub>i</sub>)</code><em> to <strong>both</strong> the Pacific and Atlantic oceans</em>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/06/08/waterflow-grid.jpg" style="width: 400px; height: 400px;" />
<pre>
<strong>Input:</strong> heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
<strong>Output:</strong> [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]
<strong>Explanation:</strong> The following cells can flow to the Pacific and Atlantic oceans, as shown below:
[0,4]: [0,4] -&gt; Pacific Ocean 
&nbsp;      [0,4] -&gt; Atlantic Ocean
[1,3]: [1,3] -&gt; [0,3] -&gt; Pacific Ocean 
&nbsp;      [1,3] -&gt; [1,4] -&gt; Atlantic Ocean
[1,4]: [1,4] -&gt; [1,3] -&gt; [0,3] -&gt; Pacific Ocean 
&nbsp;      [1,4] -&gt; Atlantic Ocean
[2,2]: [2,2] -&gt; [1,2] -&gt; [0,2] -&gt; Pacific Ocean 
&nbsp;      [2,2] -&gt; [2,3] -&gt; [2,4] -&gt; Atlantic Ocean
[3,0]: [3,0] -&gt; Pacific Ocean 
&nbsp;      [3,0] -&gt; [4,0] -&gt; Atlantic Ocean
[3,1]: [3,1] -&gt; [3,0] -&gt; Pacific Ocean 
&nbsp;      [3,1] -&gt; [4,1] -&gt; Atlantic Ocean
[4,0]: [4,0] -&gt; Pacific Ocean 
       [4,0] -&gt; Atlantic Ocean
Note that there are other possible paths for these cells to flow to the Pacific and Atlantic oceans.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> heights = [[1]]
<strong>Output:</strong> [[0,0]]
<strong>Explanation:</strong> The water can flow from the only cell to the Pacific and Atlantic oceans.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>m == heights.length</code></li>
	<li><code>n == heights[r].length</code></li>
	<li><code>1 &lt;= m, n &lt;= 200</code></li>
	<li><code>0 &lt;= heights[r][c] &lt;= 10<sup>5</sup></code></li>
</ul>

class Solution {
public:

#define F first
#define S second

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

        vector<vector<int>> board;

    bool check(int x, int y) {
        int m=board.size();
        int n=board[0].size();
        return (x >= 0 && y >= 0 && x < m && y < n);
    }

/*
    bool flowP(vector<vector<int>>& board, int x, int y){
        int m=board.size();
        int n=board[0].size();

            if(x==0 || y==0) return true;
            
            for(int i=0; i<2; i++){
                if(inBoard(board, x+dx[i], y+dy[i]) && flowP(board, x+dx[i], y+dy[i]) && board[x][y]>= board[x+dx[i]][y+dy[i]]) return true; 
            }

        return false;

        }

    bool flowA(vector<vector<int>>& board, int x, int y){
            long long m=board.size();
        long long n=board[0].size();
            if(x==m-1 || y==n-1) return true;

            for(int i=2; i<4; i++){
              if(inBoard(board, x+dx[i], y+dy[i]) && flowA(board, x+dx[i], y+dy[i]) && board[x][y]>= board[x+dx[i]][y+dy[i]]) return true; 
            }

        return false;

        }
        */

vector<pair<int, int>> neighbors(pair<int, int> node)
    {
    vector<pair<int, int>> ans;
    for(int k=0; k<4; k++) {
        if(check(node.F + dx[k], node.S + dy[k]))
            ans.push_back({node.F + dx[k], node.S + dy[k]});
    }
    return ans;
}


void bfs(pair<int, int> sc, vector<vector<bool>>& vis)
{
    vis[sc.F][sc.S]=1;
    //dis[sc.F][sc.S]=0;
    queue<pair<int, int>> q;
    q.push(sc);
    while(!q.empty()) {
        pair<int, int> node=q.front();
        q.pop();
        for(auto v:neighbors(node)) {
            if(!vis[v.F][v.S] && (board[node.F][node.S]<= board[v.F][v.S])) {
                vis[v.F][v.S]=1;
                //dis[v.F][v.S]=dis[node.F][node.S]+1;
                q.push(v);
            }
        }
    }
}

 vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {

    board=matrix;
    if (matrix.empty() || matrix[0].empty()) return {};

    vector<vector<int>> res;
        int m=board.size();
        int n=board[0].size();
        vector<vector<bool>> pacific;
        vector<vector<bool>> atlantic;
        
    pacific= vector<vector<bool>> (m, vector<bool> (n, false));
    atlantic= vector<vector<bool>> (m, vector<bool> (n, false));
            
        for(int i=0; i<n; i++){
            pacific[0][i] = true;
            atlantic[m-1][i] = true;
        }

        for(int i=0; i<m; i++){
            pacific[i][0] = true;
            atlantic[i][n-1] = true;
        }

        for(int i=0; i<m; i++){
            bfs({i, 0}, pacific);
            bfs({i, n-1}, atlantic);
        }

        for(int j=0; j<n; j++){
            bfs({0, j}, pacific);
            bfs({m-1, j}, atlantic);
        }


for(int i=0; i<m; i++){
    for(int j=0; j<n; j++){
        if(pacific[i][j] && atlantic[i][j]) res.push_back({i, j});
    }
}

            return res;
        
    }
};
41200