#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 26;
// 成员
typedef struct Person
{
char name[5]; //名字
int weight; //权重
int parent; //parent保存集合的根节点下标,根节点的parent保存集合成员个数
Person()
{
parent = -1;
weight = 0;
}
} Person;
// 帮派
typedef struct gang
{
char head[5]; //头目
int number; //成员数量
} gang;
Person p[N];
int sum[N]; //保存每个集合的总权重
//字典排序函数
bool cmp(gang a, gang b)
{
return strcmp(a.head, b.head) < 0;
}
//并查集函数
int FindRoot(int x)
{
int a = x;
while (p[x].parent >= 0)
{
x = p[x].parent;
}
while (p[a].parent >= 0)
{
int z = a;
a = p[a].parent;
p[z].parent = x;
}
return x;
}
void Union(int no1, int no2, int weight)
{
int p1 = FindRoot(no1), p2 = FindRoot(no2);
//如果是同一个集合也要加上权重
if (p1 == p2)
{
sum[p1] += weight;
return;
}
if (p[p1].parent > p[p2].parent)
{
p[p2].parent += p[p1].parent;
p[p1].parent = p2;
sum[p2] = sum[p1] + sum[p2] + weight;
}else{
//根结点p1的parent保存集合成员个数
p[p1].parent += p[p2].parent;
//p2的parent保存集合的根节点下标
p[p2].parent = p1;
//合并的过程,顺便加上集合的总权重
sum[p1] = sum[p1] + sum[p2] + weight;
}
}
int main()
{
int n, k;
while (scanf("%d%d", &n, &k) != EOF)
{
getchar(); //用于消除缓冲区回车防止字符串输入出错
int i;
memset(sum, 0, sizeof(sum));
while (n--)
{
char name1[5], name2[5];
int weight, no1, no2;
scanf("%s%s%d", name1, name2, &weight);
getchar(); //用于消除缓冲区同上
no1 = name1[0] - 'A', no2 = name2[0] - 'A'; //由名字找到这个人下标
//保存该人的名字,每遇到这个人就要加上一次权重
strcpy(p[no1].name, name1), p[no1].weight += weight;
strcpy(p[no2].name, name2), p[no2].weight += weight;
//合并有联系的人
Union(no1, no2, weight);
}
int ans = 0; //保存帮派数目
gang g[10]; //结果数组,26个人帮派最多有8个,10的数组够了
for (i = 0; i < N; i++)
{
if (p[i].parent < -2 && sum[i] > k)
{ //人数超过2人,总权重大于k则为帮派
g[ans].number = -p[i].parent; //保存下帮派人数
int parent = i; //根节点存一下,其实有点多余,可以直接用i
int max = i; //权重最大者下标,初始为根节点
for (int j = 0; j < N; j++)
{
if (FindRoot(j) == parent && p[j].weight > p[max].weight)
max = j; //如果属于此集合且权重更大,替换一下
}
strcpy(g[ans].head, p[max].name); //把头目名字存进来
ans++; //接着存下一个帮派
}
}
printf("%d\n", ans); //输出帮派数目
sort(g, g + ans, cmp); //按字典sort一下
for (i = 0; i < ans; i++)
printf("%s %d\n", g[i].head, g[i].number); //输出头目名字和帮派人数
}
return 0;
}