#!/usr/bin/perl -w

use v5.38;
use experimental 'for_list';

=for comment

convert the input to .dot format:

strict graph g {
ggk -- { tkd };
vcd -- { nhn };
xhj -- { mft rtg hvp sgl };
hgx -- { dxq stc cfn };
...
}

Then run

neato -Tsvg 49in.dot

and find the components and their edges.

=cut

my %g;
while (<>) {
	my ($n1, @ns) = /\w+/g;
	for my $n (@ns) {
		$g{$n}{$n1} = 1;
		$g{$n1}{$n} = 1;
	}
}

sub walk {
	my ($node, $seen) = @_;
	my @q = $node;
	my $visited;
	while (@q) {
		my ($n, $d) = shift @q;
		next if $seen->{$n}++;
		$visited++;
		for my $n1 (keys %{ $g{$n} }) {
			push @q, $n1;
		}
	}
	return $visited;
}

sub comps {
	my %seen;
	my $m = 1;
	my $comps;
	while (%seen != keys %g) {
		my $prev = 0;
		for my $n (keys %g) {
			next if $seen{$n};
			$m *= walk($n, \%seen);
			$comps++;
		}
	}
	say "$comps mul=$m" if $comps > 1;
	return $comps;
}

for my ($n1, $n2) (qw(rrz pzq jtr mtq ddj znv)) {
	delete $g{$n1}{$n2};
	delete $g{$n2}{$n1};
}

comps();
