keepLargestPairs :: [(Level, ((SetId, a), (SetId, b)))]
                    -> [(Level, ((SetId, a), (SetId, b)))]
keepLargestPairs ps =
  keep S.empty (reverse $ L.sortBy (comparing fst) ps) []
  where
    keep _ [] res = res
    keep seen (p@(_, ((aid, _), (bid, _))):ps) res =
      if S.member aid seen || S.member bid seen
      then keep seen ps res
      else keep (S.union seen (S.fromList [aid, bid]))
             ps
             (p:res)
keepLargestPairs :: [(Level, ((SetId, a), (SetId, b)))]
                    -> [(Level, ((SetId, a), (SetId, b)))]
keepLargestPairs ps =
  keep S.empty (reverse $ L.sortBy (comparing fst) ps) []
  where
    keep _ [] res = res
    keep seen (p@(_, ((aid, _), (bid, _))):ps) res =
      if S.member aid seen || S.member bid seen
      then keep seen ps res
      else keep (S.union seen (S.fromList [aid, bid]))
             ps
             (p:res)
keepLargestPairs ps =
  keep S.empty (reverse $ L.sortBy (comparing fst) ps) []
  where
    keep _ [] res = res
    keep seen (p@(_, ((aid, _), (bid, _))):ps) res =
      if S.member aid seen || S.member bid seen
      then keep seen ps res
      else keep (S.union seen (S.fromList [aid, bid]))
             ps
             (p:res)