Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	io := NewIo()
	defer io.Flush()
	for {
		M, T, P, R := io.NextInt(), io.NextInt(), io.NextInt(), io.NextInt()
		if M == 0 {
			break
		}
		score := make([]struct{ num, time, index int }, T)
		submit := make([][]int, T)
		for i := 0; i < T; i++ {
			score[i].index = i + 1
			submit[i] = make([]int, P)
		}

		for i := 0; i < R; i++ {
			m, t, p, j := io.NextInt(), io.NextInt()-1, io.NextInt()-1, io.NextInt()
			if j == 0 {
				score[t].num++
				score[t].time += submit[t][p]*20 + m
			} else {
				submit[t][p]++
			}
		}
		sort.SliceStable(score, func(i, j int) bool {
			return score[i].num < score[j].num || score[i].num == score[j].num && score[i].time > score[j].time
		})

		for i := T - 1; i > 0; i-- {
			io.Printf("%d", score[i].index)
			if score[i].num == score[i-1].num && score[i].time == score[i-1].time {
				io.Printf("=")
			} else {
				io.Printf(",")
			}
		}
		io.Println(score[0].index)
	}
}

// I/O template
type Io struct {
	reader    *bufio.Reader
	writer    *bufio.Writer
	tokens    []string
	nextToken int
}

func NewIo() *Io {
	return &Io{
		reader: bufio.NewReader(os.Stdin),
		writer: bufio.NewWriter(os.Stdout),
	}
}

func (io *Io) Flush() {
	err := io.writer.Flush()
	if err != nil {
		panic(err)
	}
}

func (io *Io) NextLine() string {
	var buff []byte
	for {
		line, isPrefix, err := io.reader.ReadLine()
		if err != nil {
			panic(err)
		}
		buff = append(buff, line...)
		if !isPrefix {
			break
		}
	}
	return string(buff)
}

func (io *Io) Next() string {
	for io.nextToken >= len(io.tokens) {
		line := io.NextLine()
		io.tokens = strings.Fields(line)
		io.nextToken = 0
	}
	s := io.tokens[io.nextToken]
	io.nextToken++
	return s
}

func (io *Io) NextInt() int {
	i, err := strconv.Atoi(io.Next())
	if err != nil {
		panic(err)
	}
	return i
}

func (io *Io) NextFloat() float64 {
	i, err := strconv.ParseFloat(io.Next(), 64)
	if err != nil {
		panic(err)
	}
	return i
}

func (io *Io) Println(a ...interface{}) {
	fmt.Fprintln(io.writer, a...)
}

func (io *Io) Printf(format string, a ...interface{}) {
	fmt.Fprintf(io.writer, format, a...)
}

func (io *Io) PrintIntSlice(a []int) {
	b := []interface{}{}
	for _, x := range a {
		b = append(b, x)
	}
	io.Println(b...)
}

func (io *Io) PrintStringSlice(a []string) {
	b := []interface{}{}
	for _, x := range a {
		b = append(b, x)
	}
	io.Println(b...)
}

func Log(name string, value interface{}) {
	fmt.Fprintf(os.Stderr, "%s=%+v\n", name, value)
}

func ExampleIo() {
	io := NewIo()
	defer io.Flush()
	a := make([]int, 0, 3)
	a[0], a[1], a[2] = io.NextInt(), io.NextInt(), io.NextInt()
	io.Println(a)
	io.PrintIntSlice(a)
	Log("io", a)
}

C++: #include<cstdio>
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<set>

using namespace std;

#define reps(i,f,n) for(int i=f;i<int(n);i++)
#define rep(i,n) reps(i,0,n)

typedef pair<int,int> pii;
typedef pair<pii,int> piii;

piii mk(int a, int b, int c){
	return piii(pii(a,b), c);
}

int main(){
	A:;
	
	int teemwrong[55][11]={0};
	int teemcost[11]={0};
	int teemac[11]={0};
	
	int M,T,P,R;
	cin>>M>>T>>P>>R;
	
	if(M==0&&T==0&&R==0&&P==0)return 0;
	
	rep(i,R){
		int m,t,p,j;
		cin>>m>>t>>p>>j;
		
		if(j==0){
			teemac[t]++;
			teemcost[t]+=m+teemwrong[t][p]*20;
		}else{
			teemwrong[t][p]++;
		}
	}
	
	vector<piii> rank;
	reps(i,1,T+1){
		rank.push_back(mk(teemac[i], -teemcost[i], i));
	}
	
	sort(rank.begin(),rank.end());
	reverse(rank.begin(),rank.end());
	
	rep(i,rank.size()){
		if(i!=0){
			if(rank[i].first==rank[i-1].first)printf("=");
			else printf(",");
		}
		printf("%d",rank[i].second);
	}puts("");
	
	
	goto A;
}

C++: #include <bits/stdc++.h>

using namespace std;

#define fst(t) std::get<0>(t)
#define snd(t) std::get<1>(t)
#define thd(t) std::get<2>(t)
#define fth(t) std::get<3>(t)
#define unless(p) if(!(p))
#define until(p) while(!(p))

using ll = long long;
using P3 = std::tuple<int,int,int>;

const int dx[8] = {-1, 1, 0, 0, -1, -1, 1, 1}, dy[8] = {0, 0, -1, 1, -1, 1, -1, 1};

P3 ps[60];
bool solved[60][20];
int WAs[60][20];

int main(){
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    while(true){
        int M, T, P, R;
        std::cin >> M >> T >> P >> R;
        if(!M){break;}
    
        for(int i=1;i<=T;++i){
            ps[i] = std::make_tuple(0, 0, 0);
        }
        memset(solved, 0, sizeof(solved));
        memset(WAs, 0, sizeof(WAs));
    
        for(int i=0;i<R;++i){
            int tid, pid, t, c;

            std::cin >> t >> tid >> pid >> c;

            if(solved[tid][pid]){continue;}
            if(c == 0){
                ++fst(ps[tid]);
                snd(ps[tid]) += WAs[tid][pid] * 20 + t;
                solved[tid][pid] = true;
            }else{
                ++WAs[tid][pid];
            }
        }

        for(int i=1;i<=T;++i){
            fst(ps[i]) = -fst(ps[i]);
            thd(ps[i]) = -i;
        }

        sort(ps+1, ps+1+T);

        for(int i=1,j=1;i<=T;i=j){
            if(i > 1){
                std::cout << ",";
            }
            
            while(j <= T && std::make_tuple(fst(ps[j]), snd(ps[j])) == std::make_tuple(fst(ps[i]), snd(ps[i]))){
                if(j > i){std::cout << "=";}
                std::cout << (-thd(ps[j]));
                ++j;
            }
        }

        std::cout << std::endl;
    }
}

C++: #iniclude<iostream>
using namespace std;

int main(){
	while(true){
		int M, T, P, R;
 		cin >> M >> T >> P >> R;
	
		if(M==0 && T==0 && P==0 && R==0)
			break;
		
		int CP[50], TT[50], PT[50][10];
		for(int i=0;	i<T; i++){
			CP[i] = TT[i] = 0;
			for(int j=0; j<P; j++)
				PT[i][j] = 0;
		}

		for(int i=0; i<R; i++){
			int m, t, p, r;
			cin >> m >> t >> p >> r;
			
			if(j==0){
				CP[t-1]++;
				TT[t-1] += (m+PT[t-1[p-1]);
			}
			else{
				PT[t-1][p-1] += 20;
			}
		}
	
		int tnow, tpre = -1;
		bool flg[50];
			flg[i] = false;
				
		for(int i=0; i<T; i++){
			tnow = -1;
			for(int j=0; j<T; j++){
				if(flg[j])
					continue;
				if(tnow==-1){
					tnow = j;
				}
				else{
					if(CP[j]>CP[tnow] || (CP[j]==CP[tnow] && TT[j]==TT[tnow])){
					}
				}
			}
			
			if(tpre!=-1){
				if(CP[tnow]==CP[tpre] && tt[tnow]==TT[tpre])
					cout << '=';
				else
					cout << ',';
				}
				cout << tnow+1;
				
				flg [tnow] = true;
				tpre = tnow;

			}
		cout << endl;
	}
	return 0;
}

C++: #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

#define rep(i,n) for(int i=0; i<n; i++)
const int MAX_TEAMS = 50;
const int MAX_PROBLEMS = 10;

struct Team {
	int num;
	int solved;
	int missed[MAX_PROBLEMS];
	int penalty;
	int lastTime;
	Team() : num(-1), solved(0), penalty(0), lastTime(0) {
		memset( missed, 0, sizeof(missed) );
	}
};

bool comp( const Team& l, const Team& r ) {
	if( l.solved != r.solved )  return ( l.solved > r.solved );
	else if( l.lastTime+l.penalty!=r.lastTime+r.penalty )  return ( l.lastTime+l.penalty < r.lastTime+r.penalty );
	else  return ( l.num > r.num );
}

bool compScore( const Team& l, const Team& r ) {
	if( l.solved != r.solved )  return true;
	else if( l.lastTime+l.penalty!=r.lastTime+r.penalty )  return true;
	else  return false;
}

int main() {
	int M, T, P, R;
	while( scanf("%d %d %d %d", &M, &T, &P, &R), M||T||P||R ) {
		Team teams[MAX_TEAMS];
		rep(i,T) {  teams[i].num = i+1;  }
		rep(i,R) {
			int m, t, p, j;
			scanf("%d %d %d %d", &m, &t, &p, &j);
			if(j==0) {
				teams[t-1].lastTime += m;
				teams[t-1].penalty += teams[t-1].missed[p-1] * 20;
				teams[t-1].solved++;
			}
			else{
				teams[t-1].missed[p-1]++;
			}
		}
		sort( teams, teams+T, comp );

		printf("%d", teams[0].num);
		rep(i,T-1) {
			if( compScore( teams[i], teams[i+1] ) ) {
				printf(",");
			} else {
				printf("=");
			}
			printf("%d", teams[i+1].num);
		}
		printf("\n");
	}
	return 0;
}