sclass DoubleKeyedMap {
new Map> map1;
new Map> map2;
L getA(A a) { ret values(map1.get(a)); }
L getB(B b) { ret values(map2.get(b)); }
C get(A a, B b) { ret mapGet(map1.get(a), b); }
C get(Pair p) { ret p == null ? null : get(p.a, p.b); }
void put(A a, B b, C c) {
mapGetOrCreateHashMap(map1, a).put(b, c);
mapGetOrCreateHashMap(map2, b).put(a, c);
}
}