input: from typing import List
  from functools import lru_cache as cache
  def count_permutations(n: int, constraints: List[List[int]]) -> int:
      """
      You are given an integer n and a 2D array constraints, where constraints[i] = [end_i, cnt_i] represents the end index and the inversion count of each constraint.
  
      A pair of indices (i, j) from an integer array nums is called an inversion if:
  
      i < j and nums[i] > nums[j]
      Return the count of permutations perm of [0, 1, 2, ..., n - 1] such that for all constraints[i], perm[0..endi] has exactly cnti inversions.
  
      Since the answer may be very large, return it modulo 10^9 + 7.
  
      Examples:
      >>> n = 3, constraints = [[2,2],[0,0]]
      2
      >>> n = 3, constraints = [[2,2],[1,1],[0,0]]
      1
  
      Constraints:
      2 <= n <= 300
      1 <= constraints.length <= n
      constraints[i] = [end_i, cnt_i]
      0 <= end_i <= n - 1
      0 <= cnt_i <= 400
      The input is generated such that there is at least one i such that end_i == n - 1.
      The input is generated such that all endi are unique
      """
output:     
      MOD = 10**9 + 7
  
      @cache(None)
      def dp(end_i, inv_count, mask):
          if inv_count < 0:
              return 0
          if end_i == -1:
              return int(inv_count == 0)
          
          perms = 0
          for i in range(n):
              if mask & (1 << i):
                  continue
                  
              new_mask = mask | (1 << i)
              new_inv_count = inv_count
              for j in range(i):
                  if mask & (1 << j):
                      new_inv_count -= 1
                      
              perms += dp(end_i - 1, new_inv_count, new_mask)
              perms %= MOD
              
          return perms
      
      max_end = max(end_i for end_i, _ in constraints)
      inv_counts_at_max_end = {}
      for e, cnt in constraints:
          if e <= max_end:
              inv_counts_at_max_end[e] = cnt
              
      result = dp(max_end, inv_counts_at_max_end.get(max_end, 0), 0)
      
      for e, inv_count in inv_counts_at_max_end.items():
          if e != max_end:
              sub_result = dp(e, inv_count, 0)
              result *= sub_result
              result %= MOD
      
      return result
  