private static function isRelated(Individual $target, $distance): bool
    {
        static $cache = null;

        $user_individual = self::getInstance($target->tree->getUserPreference(Auth::user(), 'gedcomid'), $target->tree);
        if ($user_individual) {
            if (!$cache) {
                $cache = [
                    0 => [$user_individual],
                    1 => [],
                ];
                foreach ($user_individual->facts(['FAMC', 'FAMS'], false, Auth::PRIV_HIDE) as $fact) {
                    $family = $fact->target();
                    if ($family instanceof Family) {
                        $cache[1][] = $family;
                    }
                }
            }
        } else {
            // No individual linked to this account? Cannot use relationship privacy.
            return true;
        }

        // Double the distance, as we count the INDI-FAM and FAM-INDI links separately
        $distance *= 2;

        // Consider each path length in turn
        for ($n = 0; $n <= $distance; ++$n) {
            if (array_key_exists($n, $cache)) {
                // We have already calculated all records with this length
                if ($n % 2 === 0 && in_array($target, $cache[$n], true)) {
                    return true;
                }
            } else {
                // Need to calculate these paths
                $cache[$n] = [];
                if ($n % 2 === 0) {
                    // Add FAM->INDI links
                    foreach ($cache[$n - 1] as $family) {
                        foreach ($family->facts(['HUSB', 'WIFE', 'CHIL'], false, Auth::PRIV_HIDE) as $fact) {
                            $individual = $fact->target();
                            // Don’t backtrack
                            if ($individual instanceof self && !in_array($individual, $cache[$n - 2], true)) {
                                $cache[$n][] = $individual;
                            }
                        }
                    }
                    if (in_array($target, $cache[$n], true)) {
                        return true;
                    }
                } else {
                    // Add INDI->FAM links
                    foreach ($cache[$n - 1] as $individual) {
                        foreach ($individual->facts(['FAMC', 'FAMS'], false, Auth::PRIV_HIDE) as $fact) {
                            $family = $fact->target();
                            // Don’t backtrack
                            if ($family instanceof Family && !in_array($family, $cache[$n - 2], true)) {
                                $cache[$n][] = $family;
                            }
                        }
                    }
                }
            }
        }

        return false;
    }