
import java.util.Vector;
import Heap;
import java.io.*;

/* I put all my classes that are related specifically to the University implementation
   inside the University class and file.  Note that all the nested classes are static,
   so they cannot access any non-static variables in University and they are not 
   associated with a specific instance of University.  I chose to make the nested 
   classes static so that there are few variables that are global to the University
   and all the parameters needed for each class must be passed into it.
*/


// As a default I declare any class with no subclasses final and any class that
// is not instantiated abstract.  These declarations are useful since they give
// extra information to the reader and to the compiler.

public final class University {

    public static void main(String[] arg) {
	University u = new University();
	
	try {
	    u.getInput(new MyInputStream(System.in));
	} catch (IOException e) {
	    System.out.println("Oh no!-- an exception in main");
	}
	
	u.runUniversity();
	u.simpleOutput();
    }
    
    private int totalDays;
    
    private int currDay;   // The current day's ID
    private int nextProj;  // The next project's ID
    
    private Professor[] faculty; // The Faculty
    private ProjectHeaps projectsReady; // Outstanding projects

    // These static variables are used by all the nested classes
    // to have a common concept of what a Department is.  I didn't
    // implement Department as a class (although you could), because 
    // there's no information to put in the class.

    private final static int deptCS = 0;
    private final static int deptMath = 1;
    private final static int deptPhysics = 2;     
    
    public University() { 
	currDay = 0;
	nextProj = 0;
	projectsReady = new ProjectHeaps();
    }
    
    // This method uses the input stream in to receive the data needed to
    // run a University simulation.
    
    public void getInput(MyInputStream in) throws IOException {
	totalDays = in.readInt();
	faculty = new Professor[in.readInt()];
	
	int a = in.readInt();
	int b = in.readInt();
	int c = in.readInt();
	
	int Am = in.readInt();
	AcademicProject.payFunc = new MultPayFunction(Am,a,b,c);
	
	int Im = in.readInt();
	IndustrialProject.payFunc = new MultPayFunction(Im,a,b,c);
	
	for (int i=0; i<faculty.length; i++) {
	    String name = in.readString();
	    char dept = in.readChar();
	    int cr = in.readInt();
	    int fu = in.readInt();
	    int ind = in.readInt();
	    
	    if (dept == 'C') {
		faculty[i] = new Professor(name,cr,fu,ind,deptCS);
	    } else if (dept == 'M') {
		faculty[i] = new Professor(name,cr,fu,ind,deptMath);
	    } else {
		faculty[i] = new Professor(name,cr,fu,ind,deptPhysics);
	    }
	}
	
    }
    
    // Returns a Vector of the projects that the 
    // professors picked to work on today.  Also
    // removes these projects from the heaps. 
    
    public Project[] pickProjects(int start) {
	Project[] ans = new Project[faculty.length];
	
	// One could speed this up by breaking this
	// for loop into two pieces, but I don't think
	// the speedup is worth the hassle 
	
	for (int i=0; i<faculty.length; i++) {
	    int c = (start + i) % faculty.length;
	    ans[c] = faculty[c].pickProject(projectsReady);

	    // This code can be used to print out projects as they are picked
	    //System.out.println(faculty[c].getName() + " " + ans[c].toString());
	}
	return ans;
    }
    
    // Generate projects consididering that the professors
    // picked the projects in p.  The new projects are
    // added to their respective heaps.  The projects picked 
    // by professor i is p[i] 
    
    public void genProjects(int start, Project[] p) {
	// This could also be spead up by breaking the loop
	// into two parts, but I doubt the speedup's worth the
	// hassle.
	
	for (int i=0; i<p.length; i++) {
	    int c = (start+i)%p.length;
	    nextProj = p[c].genProjects(projectsReady, nextProj, 
					faculty[c]);
	}
    }
    
    // Run the university for totalDays.  All the input should have
    // been received before this method is called.

    public void runUniversity() {
	for (; currDay<totalDays; currDay++) {
	    //System.out.println("Day " + currDay);
	    Project[] projectsPicked = pickProjects(currDay);
	    //System.out.println("Gen ");
	    genProjects(currDay, projectsPicked);	    
	}
    }
	
    // Output the data expected at the end of a University simulation.

    public void simpleOutput() {
	for (int i=0; i<faculty.length; i++) {
	    System.out.println(faculty[i].outString());
	}
    }


    // I couldn't find a standard input stream tokenizer that
    // I liked, so I made this simple input stream
    // that reads in integers and strings using spaces
    // and newlines as delimiters

    // You can argue that this class belongs outside of University,
    // but I don't think it's general enough to be used by any other
    // Java classes.
    
    
    private static final class MyInputStream {
	private InputStream in;
	
	public MyInputStream(InputStream in0) {
	    in = in0;
	}

	int readInt() throws IOException {
	    return Integer.valueOf(readString()).intValue();	    
	}

	String readString() throws IOException {
	    int currByte = in.read();

	    // Skip any preceding spaces 
	    while (currByte == (int) ' ' || currByte == (int) '\n') {
		
		currByte = in.read();
	    }

	    String str = "";

	    while ((currByte > 0) && (currByte != (int) ' ') && 
		   (currByte != (int) '\n')) {
	    
		str += (char) currByte;
		currByte = in.read();
	    }
	    return str;
	}
	
	char readChar() throws IOException {
	    return readString().charAt(0);
	}
	
    }
    
    // A simple class that implements the
    // function used to generate pay 
    
    abstract static private class PayFunction {
	private int a, b, c;
	
	public PayFunction(int a0, int b0, int c0) {
	    a = a0;
	    b = b0;
	    c = c0;
	}
	
	/* Generate the pay for a given project id */
	
	public int getPay(int id) {
	    return ((a*id + b) % c)+1;
	}
    }
    
    // A pay function with a multiple
    
    private static final class MultPayFunction extends PayFunction {
	private int mult;
	
	public MultPayFunction(int mult0, int a0, int b0, int c0) {
	    super(a0,b0,c0);
	    mult=mult0;
	}
	
	public int getPay(int id) {
	    return mult*super.getPay(id);
	}
    }
    
    // A simple structure for storing projects 
    // of different fields

    // See the Heap class in Heap.java and the Heap.Element
    // class in Heap.Element.java for more details.
    
    private static final class ProjectHeaps {
	
	public Heap cs;
	public Heap math;
	public Heap physics;
	
	public ProjectHeaps() {
	    cs = new Heap();
	    math = new Heap();
	    physics = new Heap();
	}
	
	// Returns the Heap associated with i, given the 
	// final static variables in University

	public Heap getDept(int i) {
	    if (i == deptCS) {
		return cs;
	    } else if (i== deptMath) {
		return math;
	    } else {
		return physics;
	    }
	}
    }
    
    // Here's the Professor class.  Professors' store information that will eventually
    // be printed and pick projects.  Note that in my implementation, the projects, not
    // the Professors generate projects.  Certainly, it's reasonable to have Professors
    // generate projects.  However, since the projects generated is more dependent on 
    // the project a Professor is working on, than it is on the project, I opted to
    // have the Projects generate projects.

    // I used to have a class for each field that a Professor could be in,
    // but I find it cleaner to just use a variable to represent a 
    // Professor's field of study

    private static final class Professor {
	
	protected String name;
	
	// These will be modified at times by Project.genProjects() 
	public int crazy, fund, indust;  

	protected int dollarsMade;
	protected int ideaDollars;
	protected int deptId;
	
	Professor(String name0, int crazy0, int fund0, int indust0, int deptId0) {
	    name = name0;
	    crazy = crazy0;
	    fund = fund0;
	    indust = indust0;
	    dollarsMade = 0;
	    ideaDollars = 0;
	    deptId = deptId0;
	}
	
	// A useful function for debugging

	public String getName() {
	    return name;
	}

	// Return a Professor's field as an integer

	public int getDept() {
	    return deptId;
	}

	// This method removes and returns the Project picked by this Professor 
	// given the Heaps in projectsReady.  Exactly what Project is picked
	// depends on the department the Professor is in.

	public Project pickProject(ProjectHeaps projectsReady) {
	    
	    Heap bestHeap = null;
	    Heap.Element bestElem = null; // Note that any project has a higher priority than null

	    // Also not that we can look at the project heaps in any order, since project 
	    // priorities are never equal. 

	    // Start with the CS project, which is applicable for the math and cs depts
	    if (deptId != deptPhysics) {
		bestHeap = projectsReady.cs;
		bestElem = bestHeap.getTop();
	    }
	    
	    Heap.Element currElem = null;

	    // Then try the math project, which is applicable for math, cs, and physics depts
	    currElem = projectsReady.math.getTop();

	    if (currElem != null && currElem.HigherPriority(bestElem)) {
		bestHeap = projectsReady.math;
		bestElem = currElem;
	    }
	    
	    // Then try the physics, which is applicable for the cs and physics depts
	    if (deptId != deptMath) {
		currElem = projectsReady.physics.getTop();
		if (currElem != null && currElem.HigherPriority(bestElem)) {
		    bestHeap = projectsReady.physics;
		    bestElem = currElem;
		}
	    }
		
	    if (bestElem == null) {
		// No project found
		return new EmptyProject();
	    }

	    // A project was found update both the cash for this
	    // professor and the ideaDollors for the project creator

	    Project ans = (Project) bestHeap.removeTop();
	    dollarsMade += ans.getPay();
	    ans.getCreator().ideaDollars += ans.getPay();
	    return ans;
	}

	// Returns a string with the dollars paid and idea dollars in
	// it, which is ready to be output to the screen.

	public String outString() {
	    return name + " " + dollarsMade + " " + ideaDollars;
	}
    }
    
    // The Project implementation. Here is the only thing in this whole file
    // that has a real interesting class layout.  Project is an abstract class
    // that has the subclasses IndustrialProject and AcademicProject.  
    // AcademicProject is also an abstract class, with subclasses. 

    // Projects store data that is necessary for a Professor to pick his or her
    // Project and have the method genProjects(), which generates projects given
    // a Professor (that is working on this project).

    private static abstract class Project implements Heap.Element {
	protected int id;
	protected int pay;
	protected Professor creator;
	
	// I use an integer to represent 
	// the department.  This isn't very object
	// oriented but I didn't want to make 9 classes
	// for Projects.
	protected int deptID; 
   
	// This constructor is used as a base for the Projects that
	// are instanciated 
	
	Project(int id0, int pay0, Professor creator0, int deptID0) {
	    
	    id = id0;
	    pay = pay0;
	    creator = creator0;
	    deptID = deptID0;

	    // Use this code for printing Projects as they are generated
	    //if (creator0 != null) 
	    //System.out.println(toString());
	}

	public String toString() {
	    return "Project ID: " + id + " Dept: " + deptID + " " +
		creator.getName() + " " + pay;
	}
	
	// Need accessor functions for pay and the creating professor

	public int getPay() {
	    return pay;
	}

	public Professor getCreator() {
	    return creator;
	}

	// Add the proper projects to the heaps and return
	// what the id of the next project should be. 

	// In the base case, the proper projects to generate
	// is the number of Crazy, Fundamental, and Industrial projects
	// given by the input for the Professor working on this (possibly
	// empty) project.

	public int genProjects(ProjectHeaps projects, 
			       int nextProj,
			       Professor picker) {
	    
	    int i;
	    Heap deptHeap = projects.getDept(picker.getDept());
	    int newDeptID = picker.getDept();
	    for (i=0; i<picker.crazy; i++, nextProj++) {
		deptHeap.insert(new CrazyProject(nextProj, picker, newDeptID));
	    }
	    
	    for (i=0; i<picker.fund; i++, nextProj++) {
		deptHeap.insert(new FundamentalProject(nextProj, picker, 
						       newDeptID));
	    }
	    
	    for (i=0; i<picker.indust; i++, nextProj++) {
		deptHeap.insert(new IndustrialProject(nextProj, picker,
						      newDeptID));
	    }
	    return nextProj;
	}
	
	// Needed for all Heap.Element's: this class says whether 
	// this instance is a higher priority than another Heap.Element
	
	public boolean HigherPriority(Heap.Element h) {
	    if (h == null) return true;
	    
	    Project p = (Project) h;
	    
	    if (pay != p.pay) {
		return (this.pay > p.pay);
	    } else {
		return (this.id < p.id);
	    } 
	}
	
    }
    
    // This class is used when a project is needed to represent that
    // a professor didn't pick a project 
    
    private static class EmptyProject extends Project {
	public EmptyProject() { 
	    super(-1,0,null,-1);
	}
	public String toString() {
	    return "";
	}
    }

    // This class represents Academic Projects, which share a 
    // certain pay multiple.  It has the subclasses FundamentalProject
    // and CrazyProject.
    
    private static abstract class AcademicProject extends Project {
	public static MultPayFunction payFunc;
	
	AcademicProject(int id0, Professor creator0, int deptID0) {
	    super(id0, payFunc.getPay(id0), creator0, deptID0);
	}
    }
    
    private static final class CrazyProject extends AcademicProject {
	public CrazyProject(int id0, Professor creator0, int deptID0) {
	    super(id0, creator0, deptID0);
	}

	public String toString() { return super.toString() + " Crazy"; }

	// We want to make sure that no industrial projects are generated
	public int genProjects(ProjectHeaps projects, 
			       int nextProj,
			       Professor picker) {
	    int oldIndust = picker.indust;
	    picker.indust = 0;
	    int ans = super.genProjects(projects, nextProj, picker);
	    picker.indust = oldIndust;
	    return ans;
	}
    }
    
    private static final class FundamentalProject extends AcademicProject {
	public FundamentalProject(int id0, Professor creator0, int deptID0) {
	    super(id0, creator0, deptID0);
	}

	public String toString() { return super.toString() + " Fund"; }

	// The following code is exactly like the code for Project.genProjects
	// except an additional industrial math project is generated if this
	// is a CS or physics project

	public int genProjects(ProjectHeaps projects, 
			       int nextProj,
			       Professor picker) {
	    
	    int i;
	    Heap deptHeap = projects.getDept(picker.getDept());
	    int newDeptID = picker.getDept();
	    for (i=0; i<picker.crazy; i++, nextProj++) {
		deptHeap.insert(new CrazyProject(nextProj, picker, newDeptID));
	    }
	    
	    for (i=0; i<picker.fund; i++, nextProj++) {
		deptHeap.insert(new FundamentalProject(nextProj, picker, 
						       newDeptID));
	    }

	    // We need to add the new math in front if we are adding
	    // Physics projects and behind if we are adding CS
	    // projects (it doesn't matter if we are adding Math Projects

	    if ((newDeptID != deptCS) && ((deptID == deptPhysics) ||
					  (deptID == deptCS))) {
		projects.math.insert(new IndustrialProject(nextProj, picker,
							   deptMath));
		nextProj++;
	    }	       
	    for (i=0; i<picker.indust; i++, nextProj++) {
		deptHeap.insert(new IndustrialProject(nextProj, picker,
						      newDeptID));
	    }
	    if ((newDeptID == deptCS) && ((deptID == deptPhysics) ||
					  (deptID == deptCS))) {
		projects.math.insert(new IndustrialProject(nextProj, picker,
							   deptMath));
		nextProj++;
	    }	
	    return nextProj;
	}
    }

    // Industrial Projects are like Academic projects in that they have
    // a common multiple.  However, unlike academic projects, industrial
    // projects can be instantiated.
    
    private static final class IndustrialProject extends Project {
	public static MultPayFunction payFunc;
	
	public IndustrialProject(int id0, Professor creator0, int deptID0) {
	    super(id0, payFunc.getPay(id0), creator0, deptID0);
	}

	public String toString() { return super.toString() + " Ind"; }

	// This code is exactly like Project.genProjects() except
	// it doesn't generate crazy projects and, if this is a math
	// or physics project, it generates an addition industrial CS
	// project.

	public int genProjects(ProjectHeaps projects, 
			       int nextProj,
			       Professor picker) {
	    
	    int i;
	    Heap deptHeap = projects.getDept(picker.getDept());
	    int newDeptID = picker.getDept();

	    for (i=0; i<picker.fund; i++, nextProj++) {
		deptHeap.insert(new FundamentalProject(nextProj, picker, 
						       newDeptID));
	    }

	    // Fortunately CS projects are always generated first,
	    // so we can put in the addition CS project before 
	    // the other industrial projects

	    if (deptID == deptMath || deptID == deptPhysics) {
		projects.cs.insert(new IndustrialProject(nextProj, picker,
							 deptCS));
		nextProj++;
	    }

	    for (i=0; i<picker.indust; i++, nextProj++) {
		deptHeap.insert(new IndustrialProject(nextProj, picker,
						      newDeptID));
	    }
	    return nextProj;
	}
    }
    
}

