🔥 Most optimal solution. Beat 100%. 𝑂(𝑛+𝑚log(𝑚))
ApproachWe use a line sweep + max heap technique.
First, we group all queries by their start index using a hashmap edges.
We maintain a heap that stores the end
# Approach
We use a line sweep + max heap technique.

- First, we group all queries by their start index using a hashmap edges.
- We maintain a heap that stores the end indices of active queries, pushed as negative values to simulate a max-heap (since Python's heapq is a min-heap).
- We iterate through each index i in nums:
  - If any query starts at i, push its end into the heap.
  - Track how many active decrements are available at i using a prefix sum array lines and a running current counter.
  - While the available current is less than nums[i], we pop the latest-ending query from the heap to cover i, and mark its expiry in lines using lines[end + 1] -= 1.
  - If at any point no valid query can cover i, return -1.
- After processing all indices, the queries left in the heap are unused. We return their count as the maximum number of removable queries.

# Complexity
- Time complexity:
𝑂(𝑚+𝑛+𝑚+𝑚log𝑚) => O(𝑛+𝑚log𝑚)
  - 𝑂(𝑚) to build the edges map.
  - 𝑂(𝑛) to iterate through nums.
  - 𝑂(𝑚+𝑚log𝑚) for at most 𝑚 insertions and deletions in the heap. It's separated from n because it will add to current at most m times and push to heap at most m times

- Space complexity:
  - 𝑂(𝑛+𝑚)
  - 𝑂(𝑛) for the lines prefix sum array.
  - 𝑂(𝑚) for the edges map and heap storage.

# Code
```python3 []
# Line sweep + max heap
# TC: O(m + n + m + mlog(m)) => O(n + mlog(m))
# 1. m - to creat edges
# 2. n - loop nums
# 3. m + mlog(m) - separated from n because it will add to current 
#     at most m times and push to heap at most m times
# SC: O(n + m)
class Solution:
    def maxRemoval(self, nums: list[int], queries: list[list[int]]) -> int:
        n, edges = len(nums), defaultdict(list)
        for start, end in queries:
            edges[start].append(end)

        lines, heap, current = [0] * (n + 1), [], 0
        for num_index, num in enumerate(nums):
            if num_index in edges:
                for end in edges[num_index]: heappush(heap, -end)

            current += lines[num_index]
            while current < num:
                if not heap or -heap[0] < num_index: return -1
                end = -heappop(heap)
                current += 1
                lines[end + 1] -= 1

        return len(heap)

['Python3']