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++: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>

using namespace std;

// repetition
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

// container util
#define all(x) (x).begin(), (x).end()

// debug
#define dump(x) cerr << #x << " = " << (x) << endl;
#define debug(x)                                         \
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" \
       << " " << __FILE__ << endl;

// typedef
typedef long long lint;
typedef unsigned long long ull;
typedef complex<long double> Complex;
typedef pair<int, int> P;
typedef tuple<int, int, int> TP;
typedef vector<int> vec;
typedef vector<vec> mat;

// constant
const int MOD = (int)1e9 + 7;
const int INF = (int)1e18;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const int ddx[] = {0, 1, 1, 1, 0, -1, -1, -1};
const int ddy[] = {1, 1, 0, -1, -1, -1, 0, 1};

// conversion
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T>
inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}

//
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
//

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

  int M, T, P, R;
  while (true) {
    cin >> M >> T >> P >> R;
    if (M == 0 && T == 0 && P == 0 && R == 0) break;
    //正解数、チームid、経過時間、問題番号、不正解数
    vector<tuple<int, int, int, map<int, int>>> rec(T);
    rep(i, T) get<1>(rec[i]) = i + 1;
    rep(i, R) {
      int m, t, p, j;
      cin >> m >> t >> p >> j;
      t--;
      if (j == 0) {
        get<0>(rec[t]) += 1;
        get<2>(rec[t]) += m + get<3>(rec[t])[p] * 20;
      } else {
        get<3>(rec[t])[p]++;
      }
    }

    vector<vector<pair<int, int>>> ans(11);
    rep(i, T) {
      int tt = get<2>(rec[i]);
      int id = get<1>(rec[i]);
      ans[get<0>(rec[i])].push_back(make_pair(tt, -id));
    }

    rep(i, 11) sort(all(ans[i]));
    int e = 0;
    rep(i, 11) {
      if (ans[i].size() == 0)
        e++;
      else
        break;
    }
    for (int i = 10; e <= i; i--) {
      for (int j = 0; j < ans[i].size(); j++) {
        cout << -ans[i][j].second;
        if (ans[i][j].first == ans[i][j + 1].first && j + 1 < ans[i].size())
          cout << "=";
        else {
          if (j + 1 != (int)ans[i].size()) cout << ",";
        }
      }
      if (ans[i].size() != 0 && e != i) cout << ",";
    }
    cout << "\n";
  }

  return 0;
}

C++: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

typedef vector<int> vi;

int M,T,P,R;
int m,t,p,j;
vi team[60];
int pena[60][20];

int main(){
  while(cin >> M >> T >> P >> R,M){
    for(int i=0;i<T;i++){
      team[i].resize(3);
      team[i][0] = team[i][1] = 0; team[i][2] = -i-1;
      for(int j=0;j<P;j++)pena[i][j] = 0;
    }

    for(int i=0;i<R;i++){
      cin >> m >> t >> p >> j;
      t--; p--;
      if(j==0){
	team[t][0]--;
	team[t][1] += pena[t][p]*20 + m;
      }else pena[t][p]++;
    }

    sort(team,team+T);

    for(int i=0;i<T;i++){
      cout << -team[i][2];
      if(i==T-1)cout << endl;
      else{
	if(team[i][0] == team[i+1][0] && team[i][1] == team[i+1][1])
	  cout << "=";
	else
	  cout << ",";
      }
    }
  }
}

C++: #include <iostream>
#include <utility>
#include <algorithm>
using namespace std;
typedef pair<int, int> P1;
typedef pair<P1, int> PP;

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 m[2003], t[2003], p[2003], j[2003];
        int last[52] {0};
        int sol[52][12];
        int miss[52][12];
        for(int it = 0; it < T; it++){
            for(int ip = 0; ip < P; ip++){
                sol[it][ip] = false;
                miss[it][ip] = 0;
            }
        }
        for(int i = 0; i < R; i++){
            cin >> m[i] >> t[i] >> p[i] >> j[i];
            t[i]--;
            p[i]--;
            if(j[i] == 0){
                sol[t[i]][p[i]] = true;
                last[t[i]] += m[i];
            }
            if(j[i] != 0){
                miss[t[i]][p[i]]++;
            }
        }
        int count[52] {0};
        PP num[52];
        for(int i = 0; i < T; i++){
            for(int k = 0; k < P; k++){
                if(sol[i][k]){
                    count[i]++;
                    last[i] += miss[i][k] * 20;
                }
            }
            last[i] = -last[i];
            num[i] = PP(P1(count[i], last[i]), i);
        }
        sort(num, num + T, greater<PP>());
        cout << num[0].second + 1;
        for(int i = 1; i < T; i++){
            if(num[i].first.first == num[i - 1].first.first && num[i].first.second == num[i - 1].first.second){
                cout << '=';
            }
            else cout << ',';
            cout << num[i].second + 1;
        }
        cout << endl;
    }
}