#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <fstream>
#include <map>
using namespace std;

struct STUDENT {
    string name;
    double p1, p2, avg;
    vector<int> options;
};

STUDENT getInfor (string str) {
    STUDENT a;
    vector <int> commaPos;
    for (int i = 0; i < str.length(); i++) {
        if (str[i] == ',') commaPos.push_back(i);
    }
    commaPos.push_back(str.length());
    int i = 0;
    a.name = str.substr(1, commaPos[i] - 2);
    a.p1 = stod(str.substr(commaPos[i] + 1, commaPos[i + 1] - commaPos[i] - 1));
    i++;
    a.p2 = stod(str.substr(commaPos[i] + 1, commaPos[i + 1] - commaPos[i] - 1));
    i++;
    a.avg = (a.p1 + a.p2) / 2;
    while (commaPos[i] != str.length()) {
        (a.options).push_back(stoi(str.substr(commaPos[i] + 1, commaPos[i + 1] - commaPos[i] - 1)));
        i++;
    }
    return a;
}

bool higher (STUDENT a, STUDENT b) {
    if (a.avg > b.avg) return true;
    if (a.avg == b.avg) {
        if (a.p1 > b.p1) return true;
        else if (a.p1 == b.p1) {
            if (a.p2 > b.p2) return true;
        }
    }
    return false;
}

bool lower (STUDENT a, STUDENT b) {
    if (a.avg < b.avg) return true;
    if (a.avg == b.avg) {
        if (a.p1 < b.p1) return true;
        else if (a.p1 == b.p1) {
            if (a.p2 < b.p2) return true;
        }
    }
    return false;
}

int partition (vector<STUDENT>& a, int l, int r) {
    STUDENT p = a[l];
    int i = l, j = r + 1;
    while (true) {
        do i++; while (higher(a[i], p) && i <= r);
        do j--; while (lower(a[j], p));
        if (i >= j) break;
        swap(a[i], a[j]);
    }
    swap(a[l], a[j]);
    return j;
}

void quickSort (vector<STUDENT>& a, int l, int r) {
    if (l < r) {
        int s = partition(a, l, r);
        quickSort(a, l, s - 1);
        quickSort(a, s + 1, r);
    }
}

void getList (vector<vector<STUDENT> >& finalList, vector<STUDENT> listOfStudents, vector<int> slots) {
    for (auto x : listOfStudents) {
        bool ac = false;
        for (auto op : x.options) {
            if (finalList[op].size() < slots[op] || ((finalList[op].back()).avg == x.avg && (finalList[op].back()).p1 == x.p1 && (finalList[op].back()).p2 == x.p2)) {
                ac = true;
                finalList[op].push_back(x);
                break;
            }
        }
        if (ac == false) {
            finalList[0].push_back(x);
        }
    }
}


int main () {
    int m;
    cout << "Enter m: ";
    cin >> m;
    cout << "Pairs option maximum number of admitted candidates, separated by blanks: " << endl;
    vector<int> slots(m + 1);
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        slots[a] = b;
    }
    cin.ignore();
    cout << "Note: Ctrl + D on Mac/ Linux or Ctrl + Z on Windows to stop." << endl;
    vector<STUDENT> listOfStudents;
    string data;
    while(getline(cin, data)) {
        STUDENT tmp = getInfor(data);
        listOfStudents.push_back(tmp);
    }

    vector<vector<STUDENT>> listByOptions(m+1);

    quickSort(listOfStudents, 0, listOfStudents.size() - 1);
    
    getList(listByOptions, listOfStudents, slots);

    for (int i = 1; i <= m; i++) {
        if (listByOptions[i].size() != 0) {
            cout << "Successful candidates for option " << i << endl;
        }
        for (int j = 0; j < listByOptions[i].size(); j++) {
            cout << j + 1 << ". " << listByOptions[i][j].name << " " << fixed << setprecision(2) << listByOptions[i][j].avg << endl;
        }
    }   
    if (listByOptions[0].size() != 0) {
        cout << "Unsuccessful candidates" << endl;
        for (int j = 0; j < listByOptions[0].size(); j++) {
            cout << j + 1 << ". " << listByOptions[0][j].name << " " << fixed << setprecision(2) << listByOptions[0][j].avg << endl;
        }        
    }
    
}