<p>You are given an <code>m x n</code> binary matrix <code>grid</code>.</p>

<p>A row or column is considered <strong>palindromic</strong> if its values read the same forward and backward.</p>

<p>You can <strong>flip</strong> any number of cells in <code>grid</code> from <code>0</code> to <code>1</code>, or from <code>1</code> to <code>0</code>.</p>

<p>Return the <strong>minimum</strong> number of cells that need to be flipped to make <strong>all</strong> rows and columns <strong>palindromic</strong>, and the total number of <code>1</code>&#39;s in <code>grid</code> <strong>divisible</strong> by <code>4</code>.</p>

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

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">grid = [[1,0,0],[0,1,0],[0,0,1]]</span></p>

<p><strong>Output:</strong> <span class="example-io">3</span></p>

<p><strong>Explanation:</strong></p>

<p><img src="https://assets.leetcode.com/uploads/2024/08/01/image.png" style="width: 400px; height: 105px;" /></p>
</div>

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

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">grid = [[0,1],[0,1],[0,0]]</span></p>

<p><strong>Output:</strong> <span class="example-io">2</span></p>

<p><strong>Explanation:</strong></p>

<p><img alt="" src="https://assets.leetcode.com/uploads/2024/07/08/screenshot-from-2024-07-09-01-37-48.png" style="width: 300px; height: 104px;" /></p>
</div>

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

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">grid = [[1],[1]]</span></p>

<p><strong>Output:</strong> <span class="example-io">2</span></p>

<p><strong>Explanation:</strong></p>

<p><img alt="" src="https://assets.leetcode.com/uploads/2024/08/01/screenshot-from-2024-08-01-23-05-26.png" style="width: 200px; height: 70px;" /></p>
</div>

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

<ul>
	<li><code>m == grid.length</code></li>
	<li><code>n == grid[i].length</code></li>
	<li><code>1 &lt;= m * n &lt;= 2 * 10<sup>5</sup></code></li>
	<li><code>0 &lt;= grid[i][j] &lt;= 1</code></li>
</ul>

class Solution:
    def minFlips(self, grid: List[List[int]]) -> int:
        # https://leetcode.com/problems/minimum-number-of-flips-to-make-binary-grid-palindromic-ii/solutions/5581114/counting-greedy-python3/
        def symmetric_pairs(i: int, j: int) -> set[tuple[int, int]]:
            return {(i, j), (i, N - j - 1), (M - i - 1, j), (M - i - 1, N - j - 1)}
    
        # Compute dimensions
        M, N = len(grid), len(grid[0])
    
        # Calculate the number of flips
        # 4 way symmetry - all 0s or all 1s
        # 2 way symmetry - based on odd / even count of (1, 1), (0, 1) / (1, 0) we decide
        # 1 cell symmetry - all 0s
    
        flips, tws10, tws11 = 0, 0, 0
        visited: set[tuple[int, int]] = set()
        for i in range(M):
            for j in range(N):
                if (i, j) not in visited:
                    ones, pairs = 0, symmetric_pairs(i, j)
                    for x, y in pairs:
                        if grid[x][y] == 1:
                            ones += 1
                        visited.add((x, y))
    
                    # Four cell symmetry
                    if len(pairs) == 4:
                        flips += min(ones, len(pairs) - ones)
    
                    # Single cell symmetry
                    elif len(pairs) == 1:
                        flips += ones
    
                    # Two cell symmetry
                    else:
                        # Count 1, 1
                        if ones == 2:
                            tws11 += 1
                        # Count 1, 0 / 0, 1
                        elif ones == 1:
                            tws10 += 1
    
        # If even number of 1, 1 pairs
        if tws11 % 2 == 0:
            # Change all (0, 1), (1, 0) to (0, 0)
            flips += tws10
        else:
            # If there is atleast a single (1, 0) pair change that to (1, 1)
            # Otherwise change the (single) (1, 1) to (0, 0)
            flips += tws10 if tws10 else 2
    
        return flips
81000