use std::collections::{BTreeSet, HashMap};
use std::iter::FromIterator;
fn f<'a>(a: &[&'a str]) -> Vec<Vec<&'a str>> { // '
fn g(mut a: Vec<BTreeSet<usize>>) -> Vec<BTreeSet<usize>> {
let comb = |n| (0..n).flat_map(move |i| (i + 1..n).map(move |j| (i, j)));
if let Some((i, j)) = comb(a.len()).find(|&(i, j)| !a[i].is_disjoint(&a[j])) {
g(a.iter().enumerate().filter_map(|(k, set)|
if k == i {
Some(BTreeSet::from_iter(a[i].union(&a[j]).cloned()))
} else if k == j {
None
} else {
Some(set.clone())
}
).collect())
} else {
a
}
}
let h = a.iter().map(|&s| s.split('=')).flatten().rev().enumerate().map(|(p, s)| (s, a.len() * 2 - p)).collect::<HashMap<_, _>>();
let a = a.iter().map(|&s| s.split('=').flat_map(|k| h.get(k)).cloned().collect::<BTreeSet<_>>()).collect();
let hi = h.iter().map(|(&k, &v)| (v, k)).collect::<HashMap<_, _>>();
g(a).iter().map(|set| set.iter().flat_map(|i| hi.get(i)).cloned().collect()).collect()
}
fn main() {
let v = ["a1=a2", "b1=b2", "b3=b2", "c1=c2", "e1=e2",
"a3=a4", "c3=c4", "e1=e3", "a2=a4", "c3=c1",
"b3=a4", "c2=d1", "a4=a5", "d2=c1", "b4=b3", "d3=c3"];
println!("{:?}", f(&v));
}
dXNlIHN0ZDo6Y29sbGVjdGlvbnM6OntCVHJlZVNldCwgSGFzaE1hcH07CnVzZSBzdGQ6Oml0ZXI6OkZyb21JdGVyYXRvcjsKZm4gZjwnYT4oYTogJlsmJ2Egc3RyXSkgLT4gVmVjPFZlYzwmJ2Egc3RyPj4geyAvLyAnCglmbiBnKG11dCBhOiBWZWM8QlRyZWVTZXQ8dXNpemU+PikgLT4gVmVjPEJUcmVlU2V0PHVzaXplPj4gewoJCWxldCBjb21iID0gfG58ICgwLi5uKS5mbGF0X21hcChtb3ZlIHxpfCAoaSArIDEuLm4pLm1hcChtb3ZlIHxqfCAoaSwgaikpKTsKCQlpZiBsZXQgU29tZSgoaSwgaikpID0gY29tYihhLmxlbigpKS5maW5kKHwmKGksIGopfCAhYVtpXS5pc19kaXNqb2ludCgmYVtqXSkpIHsKCQkJZyhhLml0ZXIoKS5lbnVtZXJhdGUoKS5maWx0ZXJfbWFwKHwoaywgc2V0KXwKCQkJCWlmIGsgPT0gaSB7CgkJCQkJU29tZShCVHJlZVNldDo6ZnJvbV9pdGVyKGFbaV0udW5pb24oJmFbal0pLmNsb25lZCgpKSkKCQkJCX0gZWxzZSBpZiBrID09IGogewoJCQkJCU5vbmUKCQkJCX0gZWxzZSB7CgkJCQkJU29tZShzZXQuY2xvbmUoKSkKCQkJCX0KCQkJKS5jb2xsZWN0KCkpCgkJfSBlbHNlIHsKCQkJYQoJCX0KCX0KICAgIGxldCBoID0gYS5pdGVyKCkubWFwKHwmc3wgcy5zcGxpdCgnPScpKS5mbGF0dGVuKCkucmV2KCkuZW51bWVyYXRlKCkubWFwKHwocCwgcyl8IChzLCBhLmxlbigpICogMiAtIHApKS5jb2xsZWN0Ojo8SGFzaE1hcDxfLCBfPj4oKTsKCWxldCBhID0gYS5pdGVyKCkubWFwKHwmc3wgcy5zcGxpdCgnPScpLmZsYXRfbWFwKHxrfCBoLmdldChrKSkuY2xvbmVkKCkuY29sbGVjdDo6PEJUcmVlU2V0PF8+PigpKS5jb2xsZWN0KCk7CglsZXQgaGkgPSBoLml0ZXIoKS5tYXAofCgmaywgJnYpfCAodiwgaykpLmNvbGxlY3Q6OjxIYXNoTWFwPF8sIF8+PigpOwoJZyhhKS5pdGVyKCkubWFwKHxzZXR8IHNldC5pdGVyKCkuZmxhdF9tYXAofGl8IGhpLmdldChpKSkuY2xvbmVkKCkuY29sbGVjdCgpKS5jb2xsZWN0KCkKfQpmbiBtYWluKCkgewogICAgbGV0IHYgPSBbImExPWEyIiwgImIxPWIyIiwgImIzPWIyIiwgImMxPWMyIiwgImUxPWUyIiwKICAgICAgICAgICAgICJhMz1hNCIsICJjMz1jNCIsICJlMT1lMyIsICJhMj1hNCIsICJjMz1jMSIsCiAgICAgICAgICAgICAiYjM9YTQiLCAiYzI9ZDEiLCAiYTQ9YTUiLCAiZDI9YzEiLCAiYjQ9YjMiLCAiZDM9YzMiXTsKICAgIHByaW50bG4hKCJ7Oj99IiwgZigmdikpOwp9
[["a1", "a2", "b1", "b2", "b3", "a3", "a4", "a5", "b4"], ["c1", "c2", "c3", "c4", "d1", "d2", "d3"], ["e1", "e2", "e3"]]