using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("300 10 8 5");
WillReturn.Add("50 5 2 1");
WillReturn.Add("70 5 2 0");
WillReturn.Add("75 1 1 0");
WillReturn.Add("100 3 1 0");
WillReturn.Add("150 3 2 0");
WillReturn.Add("240 5 5 7");
WillReturn.Add("50 1 1 0");
WillReturn.Add("60 2 2 0");
WillReturn.Add("70 2 3 0");
WillReturn.Add("90 1 3 0");
WillReturn.Add("120 3 5 0");
WillReturn.Add("140 4 1 0");
WillReturn.Add("150 2 4 1");
WillReturn.Add("180 3 5 4");
WillReturn.Add("15 2 2 1");
WillReturn.Add("20 2 2 1");
WillReturn.Add("25 2 2 0");
WillReturn.Add("60 1 1 0");
WillReturn.Add("120 5 5 4");
WillReturn.Add("15 5 4 1");
WillReturn.Add("20 5 4 0");
WillReturn.Add("40 1 1 0");
WillReturn.Add("40 2 2 0");
WillReturn.Add("120 2 3 4");
WillReturn.Add("30 1 1 0");
WillReturn.Add("40 2 1 0");
WillReturn.Add("50 2 2 0");
WillReturn.Add("60 1 2 0");
WillReturn.Add("120 3 3 2");
WillReturn.Add("0 1 1 0");
WillReturn.Add("1 2 2 0");
WillReturn.Add("300 5 8 0");
WillReturn.Add("0 0 0 0");
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int mT;
struct SubmitInfoDef
{
internal int Team;
internal int Time;
internal int Problem;
internal bool IsAC;
}
static List<SubmitInfoDef> mSubmitInfoList = new List<SubmitInfoDef>();
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
int RestSubmitCnt = 0;
foreach (string EachStr in InputList) {
SplitAct(EachStr);
if (RestSubmitCnt == 0) {
if (wkArr.All(pX => pX == 0)) {
break;
}
mT = wkArr[1];
RestSubmitCnt = wkArr[3];
mSubmitInfoList.Clear();
if (RestSubmitCnt == 0) {
Solve();
}
continue;
}
SubmitInfoDef WillAdd;
WillAdd.Time = wkArr[0];
WillAdd.Team = wkArr[1];
WillAdd.Problem = wkArr[2];
WillAdd.IsAC = (wkArr[3] == 0);
mSubmitInfoList.Add(WillAdd);
RestSubmitCnt--;
if (RestSubmitCnt == 0) {
Solve();
}
}
}
// チームごとの状況
class TeamInfoDef
{
internal int Team;
internal int ACCnt;
internal int WACnt;
internal int TimeSum;
}
static void Solve()
{
// 提出時間の昇順(提出時間が同じなら正解が後)
mSubmitInfoList = mSubmitInfoList.OrderBy(pX => pX.Time).ThenBy(pX => pX.IsAC).ToList();
// 状況[チーム]
var TeamInfoDict = new Dictionary<int, TeamInfoDef>();
for (int I = 1; I <= mT; I++) {
var WillAdd = new TeamInfoDef();
WillAdd.Team = I;
WillAdd.ACCnt = WillAdd.WACnt = WillAdd.TimeSum = 0;
TeamInfoDict[I] = WillAdd;
}
for (int I = 0; I <= mSubmitInfoList.Count - 1; I++) {
int CurrTeam = mSubmitInfoList[I].Team;
int CurrProblem = mSubmitInfoList[I].Problem;
// 不正解はcontinue;
if (mSubmitInfoList[I].IsAC == false) {
continue;
}
TeamInfoDict[CurrTeam].ACCnt++;
TeamInfoDict[CurrTeam].TimeSum += mSubmitInfoList[I].Time;
// WAの分を加算
for (int J = 0; J <= I - 1; J++) {
if (mSubmitInfoList[J].Team != CurrTeam) continue;
if (mSubmitInfoList[J].Problem != CurrProblem) continue;
TeamInfoDict[CurrTeam].WACnt++;
}
}
// TimeSumにペナルティを加算
foreach (int EachTeam in TeamInfoDict.Keys.ToArray()) {
TeamInfoDict[EachTeam].TimeSum += TeamInfoDict[EachTeam].WACnt * 20;
}
var ValuesList = TeamInfoDict.Values.ToList();
// 順位の降順にソート
ValuesList = ValuesList.OrderByDescending(pX => pX.ACCnt).
ThenBy(pX => pX.TimeSum).
ThenByDescending(pX => pX.Team).ToList();
var WillOutList = new List<string>();
while (ValuesList.Count > 0) {
var SameTeamList = new List<int>();
SameTeamList.Add(ValuesList[0].Team);
for (int I = 1; I <= ValuesList.Count - 1; I++) {
if (ValuesList[0].ACCnt != ValuesList[I].ACCnt) break;
if (ValuesList[0].TimeSum != ValuesList[I].TimeSum) break;
SameTeamList.Add(ValuesList[I].Team);
}
WillOutList.Add(IntEnumJoin("=", SameTeamList));
ValuesList.RemoveAll(pX => SameTeamList.Contains(pX.Team));
}
Console.WriteLine(string.Join(",", WillOutList.ToArray()));
}
// セパレータとInt型の列挙を引数として、結合したstringを返す
static string IntEnumJoin(string pSeparater, IEnumerable<int> pEnum)
{
string[] StrArr = Array.ConvertAll(pEnum.ToArray(), pX => pX.ToString());
return string.Join(pSeparater, StrArr);
}
}