static class Synonyms { Map> synMap = new TreeMap>(); void addSynonym(S a, S b) { L la = synMap.get(a), lb = synMap.get(b); if (la == null && lb == null) { L l = litlist(a, b); synMap.put(a, l); synMap.put(b, l); } else if (la == lb) { // nothing to do, they're already synonyms } else if (lb == null) { la.add(b); synMap.put(b, la); } else if (la == null) { lb.add(a); synMap.put(a, lb); } else mergeLists(la, lb); } void mergeLists(L la, L lb) { for (S b : lb) { la.add(b); synMap.put(b, la); } } // returns null or a list L getSynonyms(S x) { ret synMap.get(x); } }