// remove transitivity edges
// usage: read-graph < graph.txt notrans.txt

#include <map>
#include <vector>
#include <string>
#include <set>
using namespace std;

map<string, vector<string>> parents;
map<string, set<string>> parents_s;

map<string, set<string>> inferred;

int main(int argc, char **argv) {
  printf("reading graph\n");
  while(!feof(stdin)) {
    char b1[200], b2[200];
    b1[0] = 0;
    scanf("%s%s", b1, b2);
    if(b1[0]) parents[b1].push_back(b2);
    }

  printf("making sets\n");
  for(auto& b: parents) for(auto v: b.second) parents_s[b.first].emplace(v);

  printf("finding inferred\n");
  for(auto& b: parents) for(auto& s1: b.second) for(auto& s2: parents[s1])
    inferred[b.first].emplace(s2);

  printf("removing inferred\n");
  for(auto& b: inferred) for(auto& s: b.second) parents_s[b.first].erase(s);
  parents.clear();
  for(auto& b: parents_s) for(auto v: b.second) parents[b.first].emplace_back(v);

  printf("listing\n");
  for(auto& b: parents) if(b.second.size() > 1) {
    printf("%s: %d like %s %s\n", b.first.c_str(), int(b.second.size()), b.second[0].c_str(), b.second[1].c_str());
    }

  if(argc >= 2) {
    FILE *f = fopen(argv[1], "wt");
    for(auto& b: parents) for(auto& p: b.second)
      fprintf(f, "%s %s\n", b.first.c_str(), p.c_str());
    fclose(f);
    }

  return 0;
  }
