let lists_shared (_equal: '-> '-> bool) (_lists: 'a list list) : 'a list =
  
  let rec do_lists_shared (shared: 'a list) (already_occured: 'a list) (lists: 'a list list) :
    'a list =
    
    match lists with
      | [] ->
          shared
          
      | head :: tail ->
          let (new_shared, new_already_occured) =
            List.fold_left
              (fun (fold_shared, fold_already_occured) element ->
                 if List.exists (_equal element) fold_already_occured then begin
                   if List.exists (_equal element) fold_shared then
                     (fold_shared, fold_already_occured)
                   else
                     (element :: fold_shared, fold_already_occured)
                 end
                 else
                   (fold_shared, element :: fold_already_occured)
              )
              (shared, already_occured)
              head
          in
            do_lists_shared new_shared new_already_occured tail
  in
    do_lists_shared [] [] _lists