code: def find_valid_adjustment_sets(
      graph: nx.DiGraph,
      action_nodes: List[str],
      outcome_nodes: List[str],
      observed_nodes: List[str],
      backdoor_paths: List,
      bdoor_graph: nx.DiGraph,
      dseparation_algo: str,
      backdoor_sets: List,
      filt_eligible_variables: List,
      backdoor_adjustment: BackdoorAdjustment,
      max_iterations: int,
  ):
      num_iterations = 0
      found_valid_adjustment_set = False
      is_all_observed = set(graph.nodes) == set(observed_nodes)
      # If `minimal-adjustment` method is specified, start the search from the set with minimum size. Otherwise, start from the largest.
      set_sizes = (
          range(1, len(filt_eligible_variables) + 1, 1)
          if backdoor_adjustment == BackdoorAdjustment.BACKDOOR_MIN
          else range(len(filt_eligible_variables), 0, -1)
      )
      for size_candidate_set in set_sizes:
          for candidate_set in itertools.combinations(
              filt_eligible_variables, size_candidate_set
          ):
              check = check_valid_backdoor_set(
                  graph,
                  action_nodes,
                  outcome_nodes,
                  candidate_set,
                  backdoor_paths=backdoor_paths,
                  new_graph=bdoor_graph,
                  dseparation_algo=dseparation_algo,
              )
              logger.debug(
                  "Candidate backdoor set: {0}, is_dseparated: {1}".format(
                      candidate_set, check["is_dseparated"]
                  )
              )
              if check["is_dseparated"]:
                  backdoor_sets.append({"backdoor_set": candidate_set})
                  found_valid_adjustment_set = True
              num_iterations += 1
              if (
                  backdoor_adjustment
                  == BackdoorAdjustment.BACKDOOR_EXHAUSTIVE
                  and num_iterations > max_iterations
              ):
                  logger.warning(
                      f"Max number of iterations {max_iterations} reached."
                  )
                  break
          # If the backdoor method is `maximal-adjustment` or `minimal-adjustment`, return the first found adjustment set.
          if (
              backdoor_adjustment
              in {
                  BackdoorAdjustment.BACKDOOR_DEFAULT,
                  BackdoorAdjustment.BACKDOOR_MAX,
                  BackdoorAdjustment.BACKDOOR_MIN,
              }
              and found_valid_adjustment_set
          ):
              break
          # If all variables are observed, and the biggest eligible set
          # does not satisfy backdoor, then none of its subsets will.
          if (
              backdoor_adjustment
              in {
                  BackdoorAdjustment.BACKDOOR_DEFAULT,
                  BackdoorAdjustment.BACKDOOR_MAX,
              }
              and is_all_observed
          ):
              break
          if num_iterations > max_iterations:
              logger.warning(
                  f"Max number of iterations {max_iterations} reached. Could not find a valid backdoor set."
              )
              break
      return backdoor_sets, found_valid_adjustment_set
  
imports: import itertools
  import logging
  from enum import Enum
  from typing import Dict, List, Optional, Union
  import networkx
  import sympy
  import sympy.stats
  from dowhy.causal_identifier.efficient_backdoor import EfficientBackdoor
  from dowhy.causal_identifier.identified_estimand import IdentifiedEstimand
  from dowhy.graph import check_dseparation, check_valid_backdoor_set, check_valid_frontdoor_set, check_valid_mediation_set, do_surgery, get_all_directed_paths, get_backdoor_paths, get_descendants, get_instruments, has_directed_path
  from dowhy.utils.api import parse_state
label_desc: Use image node_id 8 for calling a global function with example usage: find_valid_adjustment_sets(graph, action_nodes, outcome_nodes, observed_nodes, backdoor_paths, bdoor_graph, dseparation_algo, backdoor_sets, filt_eligible_variables, backdoor_adjustment, max_iterations) and returns: backdoor_sets,  found_valid_adjustment_set