<p>Given a <strong>1-indexed</strong>&nbsp;<code>m x n</code> integer matrix <code>mat</code>, you can select any cell in the matrix as your <strong>starting cell</strong>.</p>

<p>From the starting cell, you can move to any other cell <strong>in the</strong> <strong>same row or column</strong>, but only if the value of the destination cell is <strong>strictly greater</strong> than the value of the current cell. You can repeat this process as many times as possible, moving from cell to cell until you can no longer make any moves.</p>

<p>Your task is to find the <strong>maximum number of cells</strong> that you can visit in the matrix by starting from some cell.</p>

<p>Return <em>an integer denoting the maximum number of cells that can be visited.</em></p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<p><strong class="example"><img alt="" src="https://assets.leetcode.com/uploads/2023/04/23/diag1drawio.png" style="width: 200px; height: 176px;" /></strong></p>

<pre>
<strong>Input:</strong> mat = [[3,1],[3,4]]
<strong>Output:</strong> 2
<strong>Explanation:</strong> The image shows how we can visit 2 cells starting from row 1, column 2. It can be shown that we cannot visit more than 2 cells no matter where we start from, so the answer is 2. 
</pre>

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

<p><strong class="example"><img alt="" src="https://assets.leetcode.com/uploads/2023/04/23/diag3drawio.png" style="width: 200px; height: 176px;" /></strong></p>

<pre>
<strong>Input:</strong> mat = [[1,1],[1,1]]
<strong>Output:</strong> 1
<strong>Explanation:</strong> Since the cells must be strictly increasing, we can only visit one cell in this example. 
</pre>

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

<p><strong class="example"><img alt="" src="https://assets.leetcode.com/uploads/2023/04/23/diag4drawio.png" style="width: 350px; height: 250px;" /></strong></p>

<pre>
<strong>Input:</strong> mat = [[3,1,6],[-9,5,7]]
<strong>Output:</strong> 4
<strong>Explanation:</strong> The image above shows how we can visit 4 cells starting from row 2, column 1. It can be shown that we cannot visit more than 4 cells no matter where we start from, so the answer is 4. 
</pre>

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

<ul>
	<li><code>m == mat.length&nbsp;</code></li>
	<li><code>n == mat[i].length&nbsp;</code></li>
	<li><code>1 &lt;= m, n &lt;= 10<sup>5</sup></code></li>
	<li><code>1 &lt;= m * n &lt;= 10<sup>5</sup></code></li>
	<li><code>-10<sup>5</sup>&nbsp;&lt;= mat[i][j] &lt;= 10<sup>5</sup></code></li>
</ul>

class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        unique = set()
        nrows,ncols = len(mat),len(mat[0])
        table = [[1 for _ in range(ncols)] for _ in range(nrows)]
        pq = sorted([(mat[r][c],r,c) for c in range(ncols) for r in range(nrows)], key=lambda x:x[0])
        rows = defaultdict(list) # row:[(val,row,col)]
        cols = defaultdict(list) # col:[(val,row,col)]
        for r in range(nrows):
            for c in range(ncols):
                val = mat[r][c]
                unique.add(val)
                rows[r].append((val,r,c))
                cols[c].append((val,r,c))
        for r in range(nrows): rows[r] = sorted(rows[r],key=lambda x:x[0])
        for c in range(ncols): cols[c] = sorted(cols[c],key=lambda x:x[0])
        max_steps = 0
        while pq:
            val,r,c = pq.pop()
            step = table[r][c]
            max_steps = max(max_steps, step)
            if max_steps == len(unique): break
            rows[r].pop()
            cols[c].pop()
            if rows[r]:
                if rows[r][0][0]<val:
                    r_idx = bisect.bisect_right(rows[r],val-1,key=lambda x:x[0])
                    if r_idx:
                        r_idx -= 1
                        p_val,p_row,p_col = rows[r][r_idx]
                        table[r][p_col] = max(table[r][p_col], step+1)
                        max_steps = max(max_steps, table[r][p_col])
                        if max_steps == len(unique): break
                        while r_idx and rows[r][r_idx-1][0]==p_val:
                            r_idx -= 1
                            _,p_row,p_col = rows[r][r_idx]
                            table[r][p_col] = max(table[r][p_col], step+1)
            if cols[c]:
                if cols[c][0][0]<val:
                    c_idx = bisect.bisect_right(cols[c],val-1,key=lambda x:x[0])
                    if c_idx:
                        c_idx -= 1
                        p_val,p_row,p_col = cols[c][c_idx]
                        table[p_row][c] = max(table[p_row][c], step+1)
                        max_steps = max(max_steps, table[p_row][c])
                        if max_steps == len(unique): break
                        while c_idx and cols[c][c_idx-1][0]==p_val:
                            c_idx -= 1
                            _,p_row,p_col = cols[c][c_idx]
                            table[p_row][c] = max(table[p_row][c], step+1)    
        return max_steps
2546