Mr. Brown;

[spoiler connected components: quick find quick union algorithm]

```
declare
type char_array is table of varchar2 (20) index by varchar2 (20);
type arr_elems is table of sys.ku $ _ vcnt index by varchar2 (20);
root char_array;
root_elems arr_elems;
n varchar2 (20);
l integer: = dbms_utility.get_time ();
procedure print (v in varchar2) is
begin
dbms_output.put_line (to_char ((dbms_utility.get_time-l)/100, ' 0999.99 ') || ' ' || v);
l: = dbms_utility.get_time ();
end;
function get_root (n varchar2) return varchar2 is
begin
if root.exists (n) then
return root (n);
else
return null;
end if;
end;
procedure update_root (old_root varchar2, new_root varchar2) is
i pls_integer;
begin
if old_root! =new_root then
root_elems (new_root): =root_elems (new_root) multiset union all root_elems (old_root);
for i in 1. root_elems (old_root).count
loop
root (root_elems (old_root) (i)): =new_root;
end loop;
root_elems (old_root).delete;
end if;
end;
procedure add_elem (p_root varchar2, p_elem varchar2) is
begin
if not root_elems.exists (p_root) then
root_elems (p_root): =sys.ku $ _ vcnt (p_elem);
else
root_elems (p_root).extend ();
root_elems (p_root) (root_elems (p_root).count): =p_elem;
end if;
end;
procedure add_link (p varchar2, q varchar2) is
r1 varchar2 (20);
r2 varchar2 (20);
new_root varchar2 (20);
begin
r1: = get_root (p);
r2: = get_root (q);
if r1 is null or r2 is null then
new_root: = coalesce (r1, r2, p);
if r1 is null then add_elem (new_root, p); root (p): =new_root; end if;
if r2 is null then add_elem (new_root, q); root (q): =new_root; end if;
else
new_root: = least (r1, r2);
root (p): =new_root;
root (q): =new_root;
update_root (greatest (r1, r2), new_root);
end if;
end;
begin
print (' start ');
for r in (
==> with v (p, q) as (
==> select ' the Circle 1 ', ' Boris ' from dual union all
==> select ' the Circle 1 ', ' Artem ' from dual union all
==> select ' the Circle 3 ', ' Denis ' from dual union all
==> select ' the Circle 3 ', ' Evgenie ' from dual union all
==> select ' the Circle 2 ', ' Victor ' from dual union all
==> select ' the Circle 2 ', ' Artem ' from dual union all
==> select ' the Circle 4 ', ' Vladimir ' from dual union all
==> select ' the Circle 4 ', ' Stanislav ' from dual union all
==> select ' the Circle 1 ', ' Andrey ' from dual union all
==> select ' the Circle 1 ', ' Victor ' from dual
==>)
==> select *
==> from v
)
loop
add_link (r.p, r.q);
end loop;
print (' processed ');
print (' groups: ');
n: = root_elems.first ();
while n is not null loop
for i in 1. root_elems (n).count loop
dbms_output.put (', ' || root_elems (n) (i));
end loop;
dbms_output.put_line (' ');
n: = root_elems.next (n);
end loop;
end;
```

[/spoiler]

In the selected you substitute the request dataful