#include <stdio.h>
#include <string.h>

//保存信息条的结构体
typedef struct Erro_info{
    char name[50];
    int line;
    int count;
} Erro_info;

int main() {
    char buf[50] = {0};
    int line = 0;       
    int i = 0;
    int record_i = 0;
    Erro_info erro_info[100];

    //逐行循环读取每条信息
    while(scanf("%s %d", buf, &line) != EOF) {
        char name[50] = {0};
        int len = strlen(buf);
        int flag = 0;

        //解析文件名后,暂存文件名
        //文件名长度小于16
        for(i=len-1; i>=0; i--) {
            if(buf[i] == '\\') {
                break;
            }
        }
        if((i+1) < (len-16)) {
            strcpy(name, buf+len-16);
        }
        else {
            strcpy(name, buf+i+1);
        }

        //检查记录中是否已存在当前错误信息
        for(i = 0; i<record_i; i++) {
            if((!strcmp(name, erro_info[i].name))&&(line == erro_info[i].line)) {
                flag = 1;
                erro_info[i].count++;
                break;
            }
         }

        //否则,当前的信息是新的
        //将该条信息记录到结构体数组中
        if(flag == 0) {
            strcpy(erro_info[record_i].name, name);
            erro_info[record_i].line = line;
            erro_info[record_i].count = 1;
            record_i++;
        }
    }
    
    //输出
    //如果信息条数小于8,则输出全部信息
    //否则,输出最后8条信息
    if(record_i < 8) {
        for(i = 0; i < record_i; i++) {
            printf("%s %d %d\n", erro_info[i].name, erro_info[i].line, erro_info[i].count);
        }
    }
    else {
        for(i = record_i-8; i<record_i; i++) {
            printf("%s %d %d\n", erro_info[i].name, erro_info[i].line, erro_info[i].count);
        }
    }

    return 0;
}