class Solution:
  def minOrAfterOperations(self, nums: list[int], k: int) -> int:
    MAX_BIT = 30
    ans = 0
    prefixMask = 0  # Grows like: 10000 -> 11000 -> ... -> 11111
    for i in range(MAX_BIT, -1, -1):
      # Add the i-th bit to `prefixMask` and attempt to "turn off" the
      # currently added bit within k operations. If it's impossible, then we
      # add the i-th bit to the answer.
      prefixMask |= 1 << i
      if self._getMergeOps(nums, prefixMask, ans) > k:
        ans |= 1 << i
    return ans
  def _getMergeOps(self, nums: list[int], prefixMask: int, target: int) -> int:
    """
    Returns the number of merge operations to turn `prefixMask` to the target
    by ANDing `nums`.
    """
    mergeOps = 0
    ands = prefixMask
    for num in nums:
      ands &= num
      if (ands | target) == target:
        ands = prefixMask
      else:
        mergeOps += 1  # Keep merging the next num
    return mergeOps