input: from typing import List
  
  def max_valid_points(points: List[List[int]], tags: str) -> int:
      """
      Given a 2D list of points and a string of tags where points[i] represents the coordinates of point i, and tags[i] is the tag of point i,
      write a function to determine the maximum number of points that can be enclosed in a valid square.
  
      A valid square is one that is centered at the origin (0, 0), has sides parallel to the coordinate axes, and ensures no two points within it share the same tag.
  
      Return the count of the maximum points in such a square.
  
      Note:
  
      A point is within the square's boundary if it is on or inside the square.
      The side length of the square can be zero.
  
      Examples:
      >>> points = [[2,2],[-1,-2],[-4,4],[-3,1],[3,-3]], tags = "abdca"
      2
      >>> points = [[1,1],[-2,-2],[-2,2]], tags = "abb"
      1
      >>> points = [[1,1],[-1,-1],[2,-2]], tags = "ccd"
      0
  
      Constraints:
      1 <= len(tags), len(points) <= 100000
      len(points[i]) == 2
      -1000000000 <= points[i][0], points[i][1] <= 1000000000
      len(tags) == len(points)
      Points have distinct coordinates.
      Tags consist only of lowercase English letters.
      """
output:     max_count = 0
      n = len(points)
      
      def is_valid_square(side_length):
          tag_set = set()
          count = 0
          for i in range(n):
              x, y = points[i]
              if -side_length / 2 <= x <= side_length / 2 and -side_length / 2 <= y <= side_length / 2:
                  if tags[i] in tag_set:
                      return False
                  tag_set.add(tags[i])
                  count += 1
          return True if count > 0 else False
  
      lo, hi = 0, 2 * 10**9
      while lo <= hi:
          mid = (lo + hi) // 2
          if is_valid_square(mid):
              max_count = max(max_count, len(set(tags[i] for i in range(n) if -mid / 2 <= points[i][0] <= mid / 2 and -mid / 2 <= points[i][1] <= mid / 2)))
              hi = mid - 1
          else:
              lo = mid + 1
              
      return max_count