/*
* Problem :: 3758 / KCPC
*
* Kind :: Sorting
*
* Insight
* - 최종 점수가 높을 수록 순위가 높다
* 최종 점수가 같을 경우, 풀이를 제출한 횟수가 적은 팀의 순위가 높다
* 최종 점수도 같고 제출 횟수도 같은 경우, 마지막 제출 시간이 더 빠른 팀의 순위가 높다
* + 위의 조건대로 정렬하면 된다
* Team 이라는 구조체를 선언하고 배열로 만들어준후 정보를 입력받고 정렬해주자
*
* Point
* - 한 문제에 대한 풀이를 여러번 제출 시
* 그 중 최고 점수가 그 문제에 대한 최종 점수가 된다
* + Map 자료구조를 활용해주자
*
* - 정렬시에 Map 자료구조를 매번 순회하면서 최종 점수를 구하는 것은 비효율적이다
* + 각 팀의 최종 점수를 담고 있는 변수를 선언하고 활용하자
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <map>
#include <algorithm>
#include <tuple>
using namespace std;
#define endl '\n'
// Set up : Global Variables
struct Team { int id; map<int,int> board; int score{}, cnt{}, last{}; };
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int T; cin >> T;
while (T--) {
int n, k, t, m;
cin >> n >> k >> t >> m;
Team TM[n+1]; /* 각 팀의 정보를 담고 있는 Team 구조체 배열 */
for (int i=1; i<=n; i++) { TM[i].id = i; } /* 각 팀의 id 초기화 */
for (int o=0; o<m; o++) {
int i, j, s;
cin >> i >> j >> s;
Team &tm = TM[i]; /* ID 가 i 인 팀의 정보 */
tm.cnt++; /* 제출회숫 증가 */
tm.last = o; /* 마지막 제출 시간 갱신 */
if (tm.board[j] < s) { /* 현재 팀의 j 번 최종 점수가
* 이번 제출에 획득한 점수 s 보다 작다면 */
tm.score += s - tm.board[j]; /* 현재 팀의 최종 점수 갱신 */
tm.board[j] = s; /* 현재 팀의 j 번 최종 점수 갱신 */
}
}
// Process
/* 문제의 조건에 따라 Team 구조체 배열 정렬 */
sort(TM+1, TM+(n+1), [](Team &u, Team &v){
auto tu = make_tuple(-u.score, u.cnt, u.last);
auto tv = make_tuple(-v.score, v.cnt, v.last);
return tu < tv;
});
/* ID 가 t 인 팀의 인덱스 찾기 */
int ans = find_if(TM+1, TM+(n+1), [t](const Team &tm){
return tm.id == t;
}) - TM;
// Control : Output
cout << ans << endl;
}
}
// Helper Functions
/* None */