WITH RECURSIVE
  Chains AS (
    SELECT *, giver_id AS start_id
    FROM SecretSanta
    UNION ALL
    SELECT SecretSanta.*, Chains.start_id
    FROM SecretSanta
    INNER JOIN Chains
      ON (
        SecretSanta.giver_id = Chains.receiver_id
        AND SecretSanta.giver_id != Chains.start_id) -- Avoid cycles.
  ),
  ChainSummary AS (
    SELECT
      start_id,
      COUNT(*) AS chain_length,
      SUM(gift_value) AS total_gift_value
    FROM Chains
    GROUP BY 1
  ),
  UniqueChains AS (
    SELECT DISTINCT chain_length, total_gift_value
    FROM ChainSummary
  )
SELECT
  RANK() OVER(
    ORDER BY chain_length DESC, total_gift_value DESC
  ) AS chain_id,
  chain_length,
  total_gift_value
FROM UniqueChains;