def preprocess_model1(sudoku):
  """
      Returns variables and constraints
      a variable is a set of its domain
      a constraint is a set of variables that it should not be equal to
  """
  #create variables
  row, column = sudoku.shape
  variables = {}
  constraints = {}

  # Create variables with domains and constraints
  for i in range(row):
    for j in range(column):
      # Create variable name
      cell_name = '%d,%d' % (i, j)
      var = None
      # if domain empty give full domain
      if sudoku[i, j] == 0:
        var = {1, 2, 3, 4, 5, 6, 7, 8, 9}
      # Else give domain to variable
      else:  
        var = {sudoku[i, j]}

      # Add variable to dictonary  
      variables[cell_name] = var

      # Create constraints 
      cell_constraints = set()
      # Create rows constraints
      for ii in range(row):
        if ii != i:
          cell_constraints.add('%d,%d' % (ii, j))
      # Create colomn constraints    
      for jj in range(column):
        if jj != j:
          cell_constraints.add('%d,%d' % (i, jj))

      # Create rectangle constraints    
      rect_i = (i // 3) * 3
      rect_j = (j // 3) * 3
      for ii in range(rect_i, rect_i + 3):
        for jj in range(rect_j, rect_j + 3):
          if ii != i and jj != j:
            cell_constraints.add('%d,%d' % (ii, jj))

      # add constraints      
      constraints[cell_name] = list(cell_constraints)
        
  return variables, constraints