#include <stdio.h>
#include "Fields.h"
#include <list>
#include <map>
#include <string>

using namespace std;

class Vertex;

class Edge {
public:
  Edge(Vertex *vtx1, Vertex *vtx2) {
    v1 = vtx1;
    v2 = vtx2;
  }
  Vertex *getVertex1() { return v1; }
  Vertex *getVertex2() { return v2; }

protected:
    Vertex *v1;
    Vertex *v2;
};

class Vertex {
protected:
  string name;
  list<Edge *> edges;
  int nincident;
  list<Edge *>::iterator edgesIter;
public:
  Vertex(string n) {
    name = n;
    nincident = 0;
  }
  string getName() { return name; }
  int getNumIncident() { return nincident; }
  void firstEdge() { edgesIter = edges.begin(); }
  void nextEdge() { edgesIter++; }
  bool endOfEdges() { return edgesIter == edges.end(); }
  Edge *getEdge() { return *edgesIter; }

  void addEdge(Edge *e) { 
    edges.push_back(e); 
    e->getVertex2()->nincident++;
  }

  void deleteEdge() {
    Edge *e = getEdge();
    e->getVertex2()->nincident--;
    edgesIter = edges.erase(edgesIter);
  }
};

main()
{
  Fields *f;
  map<string, Vertex *> g;
  Vertex *v;
  Vertex *v2;
  Edge *e;
  string s;

  v = 0;

  f = new Fields();

  while (f->get_line() >= 0) {
    if (f->get_NF() > 0) {
      if (f->get_field(0) == "CLASS") {
        if (f->get_NF() != 2) {
          fprintf(stderr, "%d: CLASS name\n", f->get_line_number());
          exit(1);
        } 
        s = f->get_field(1);
	v = g[s];
        if (v == 0) {
	  v = new Vertex(s);
          g[s] = v;
        } 
      } else if (f->get_field(0) == "PREREQ") {
        if (f->get_NF() != 2) {
          fprintf(stderr, "%d: PREREQ class\n", f->get_line_number());
          exit(1);
        } 
        if (v == 0) {
          fprintf(stderr, "%d: PREREQ -- no current vertex\n", 
                  f->get_line_number());
          exit(1);
        } 
        s = f->get_field(1);
	v2 = g[s];
        if (v2 == 0) {
	  v2 = new Vertex(s);
          g[s] = v2;
        } 
        e = new Edge(v2, v);
        v2->addEdge(e);
    
      } else {
          fprintf(stderr, "%d: lines must be CLASS or PREREQ\n", 
                   f->get_line_number());
          exit(1);
      }
    }
  }

  map<string, Vertex *>::iterator vertices;
  for (vertices = g.begin(); vertices != g.end(); vertices++) {
    v = vertices->second;
    printf("Class %s\n", v->getName().c_str());
    for (v->firstEdge(); !v->endOfEdges(); v->nextEdge()) {
      e = v->getEdge();
      printf("   is a prereq for %s\n", e->getVertex2()->getName().c_str());
    }
    printf("\n");
  }
}

