<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:
        pass






















class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        R, C = len(mat), len(mat[0])

        hmap = defaultdict(list)
        for i in range(R) :
            for j in range(C) :
                hmap[mat[i][j]].append((i, j))
        
        dp = [[0 for j in range(C)] for i in range(R)]
        row_res, col_res = [0 for i in range(R)], [0 for j in range(C)]

        for num in sorted(hmap.keys()) :
            for i, j in hmap[num] :
                dp[i][j] = max(row_res[i], col_res[j]) + 1
            
            for i, j in hmap[num] :
                row_res[i] = max(row_res[i], dp[i][j])
                col_res[j] = max(col_res[j], dp[i][j])
        
        return max(max(row_res), max(col_res))



class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        
        vals = collections.defaultdict(list)
        for i in range(m):
            for j in range(n):
                vals[mat[i][j]].append((i, j))
        
        dp = [[0] * n for _ in range(m)]
        track_row = [0] * m
        track_col = [0] * n

        for num in sorted(vals.keys()):
            for i, j in vals[num]:
                dp[i][j] = max(track_row[i], track_col[j]) + 1
            
            for i, j in vals[num]:
                track_row[i] = max(dp[i][j], track_row[i])
                track_col[j] = max(dp[i][j], track_col[j])
        return max(max(track_row), max(track_col))
























class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        record_row = [0] * m
        record_col = [0] * n
        dp = [[0] * n for _ in range(m)]
        vals = collections.defaultdict(list)

        for y in range(m):
            for x in range(n):
                vals[mat[y][x]].append((y, x))
        
        for val in sorted(vals.keys()):
            for y, x in vals[val]:
                dp[y][x] = max(dp[y][x], record_row[y], record_col[x]) + 1
            
            for y, x in vals[val]:
                record_row[y] = max(dp[y][x], record_row[y])
                record_col[x] = max(dp[y][x], record_col[x])
        return max(max(record_row), max(record_col))




















class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        max_row = [0] * m
        max_col = [0] * n
        dp = [[0] * n for _ in range(m)]
        val2idx = collections.defaultdict(list)
        for y in range(m):
            for x in range(n):
                val2idx[mat[y][x]].append((y, x))

        for val in sorted(val2idx.keys()):
            for y, x in val2idx[val]:
                dp[y][x] = max(max_row[y], max_col[x]) + 1
            for y, x in val2idx[val]:
                max_row[y] = max(dp[y][x], max_row[y])
                max_col[x] = max(dp[y][x], max_col[x])
        return max(max(max_row), max(max_col))


class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        '''
        val2coords: val --> (y, x)
        row_max[y]: record maximum length from the row[y]
        col_max[x]: record maximum length from the col[x]
        dp[y][x]: record maximum length until [y][x] point
        '''
        val2coords = collections.defaultdict(list)
        m, n = len(mat), len(mat[0])
        for y in range(m):
            for x in range(n):
                val2coords[mat[y][x]].append((y, x))
        
        dp = [[0] * n for _ in range(m)]
        row_max = [0] * m
        col_max = [0] * n

        for val in sorted(val2coords.keys()):
            for y, x in val2coords[val]:
                dp[y][x] = max(dp[y][x], row_max[y]+1, col_max[x]+1)
            for y, x in val2coords[val]:
                row_max[y] = max(row_max[y], dp[y][x])
                col_max[x] = max(col_max[x], dp[y][x])
        return max(max(row_max), max(col_max))

























class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        dp = [[0] * n for _ in range(m)]
        max_row = [0] * m
        max_col = [0] * n

        val2coords = collections.defaultdict(list)
        for y in range(m):
            for x in range(n):
                val2coords[mat[y][x]].append((y, x))
        
        for val in sorted(val2coords.keys()):
            for y, x in val2coords[val]:
                dp[y][x] = max(dp[y][x], max_row[y]+1, max_col[x]+1)
            for y, x in val2coords[val]:
                max_row[y] = max(max_row[y], dp[y][x])
                max_col[x] = max(max_col[x], dp[y][x])
        return max(max(max_row), max(max_col))

class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        row_max = [0] * m
        col_max = [0] * n
        dp = [[0] * n for _ in range(m)]
        val2idx = collections.defaultdict(list)
        for y in range(m):
            for x in range(n):
                val2idx[mat[y][x]].append((y, x))
        
        for val in sorted(val2idx.keys()):
            for y, x in val2idx[val]:
                dp[y][x] = max(dp[y][x], row_max[y]+1, col_max[x]+1)

            for y, x in val2idx[val]:
                row_max[y] = max(row_max[y], dp[y][x])
                col_max[x] = max(col_max[x], dp[y][x])
        return max(max(row_max), max(col_max))




















class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        val2idx = collections.defaultdict(list)
        for y in range(m):
            for x in range(n):
                val2idx[mat[y][x]].append((y, x))
        
        dp = [[0] * n for _ in range(m)]
        max_row = [0] * m
        max_col = [0] * n

        for val in sorted(val2idx.keys()):
            for y, x in val2idx[val]:
                dp[y][x] = max(max_row[y], max_col[x]) + 1
            for y, x in val2idx[val]:
                max_row[y] = max(max_row[y], dp[y][x])
                max_col[x] = max(max_col[x], dp[y][x])
        return max(max(max_row), max(max_col))






















class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        dp = [[0] * n for _ in range(m)]
        val2idx = collections.defaultdict(list)
        for y in range(m):
            for x in range(n):
                val2idx[mat[y][x]].append((y, x))
        
        row = [0] * m
        col = [0] * n

        for val in sorted(val2idx.keys()):
            for y, x in val2idx[val]:
                dp[y][x] = max(row[y], col[x]) + 1
            for y, x in val2idx[val]:
                row[y] = max(row[y], dp[y][x])
                col[x] = max(col[x], dp[y][x])
        return max(max(row), max(col))





















class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        dp = [[0] * n for _ in range(m)]
        rows = [0] * m
        cols = [0] * n
        val2idx = collections.defaultdict(list)
        for y in range(m):
            for x in range(n):
                val2idx[mat[y][x]].append((y, x))
        
        for val in sorted(val2idx.keys()):
            for y, x in val2idx[val]:
                dp[y][x] = max(cols[x], rows[y]) + 1
            for y, x in val2idx[val]:
                cols[x] = max(cols[x], dp[y][x])
                rows[y] = max(rows[y], dp[y][x])
        return max(max(cols), max(rows))





















class Solution:
    def maxIncreasingCells(self, mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        val2idx = collections.defaultdict(list)
        for y in range(m):
            for x in range(n):
                val2idx[mat[y][x]].append((y, x))
        
        dp = [[0] * n for _ in range(m)]
        rows = [0] * m
        cols = [0] * n
        for val in sorted(val2idx.keys()):
            for y, x in val2idx[val]:
                dp[y][x] = max(cols[x], rows[y]) + 1
            
            for y, x in val2idx[val]:
                rows[y] = max(rows[y], dp[y][x])
                cols[x] = max(cols[x], dp[y][x])
        return max(max(rows), max(cols))
1619