#include<iostream>
#include<map>
#include<set>
#include<vector>
using namespace std;


map<string, int>strToInt;
map<int, string>intToStr;
int weights_array[2000];
int name_index;
int father[2000];

void init_Config() {
    strToInt.clear();
    intToStr.clear();
    fill(weights_array, weights_array + 1001, 0);
    name_index = 0;
    for (int i = 0; i < 1001; i++) {
        father[i] = i;
    }
}
struct block {
    int block_index = 0; //团伙id,某个连通分量的成员ID
    int sum_weights = 0; //团伙权重
    int head_of_weights = 0; //团后头目的权重
    int head_of_gang = 0; //团伙头目的id
    int count = 0;
    block() {
        block_index = 0;
        sum_weights = 0;
        head_of_weights = 0;
        head_of_gang = 0;
        count = 0;
    }
    block(int a, int b, int c, int d, int e) {
        block_index = a;
        sum_weights = b;
        head_of_weights = c;
        head_of_gang = d;
        count = e;
    }

};
struct person {
    string name;
    int num;
    person(string a, int b) {
        name = a;
        num = b;
    }
};
int findFather(int x) {
    if (x != father[x]) father[x] = findFather(father[x]);
    return father[x];
}
void unionFather(int x, int y) {
    int x_father = findFather(x);
    int y_father = findFather(y);
    father[y_father] = father[x_father];
}

int transStrToInt(string str) {
    if (strToInt.find(str) != strToInt.end()) {
        return strToInt[str];
    } else {
        strToInt[str] = name_index;
        intToStr[name_index] = str;
        name_index++;
        return strToInt[str];

    }
}


int main() {
    int N, K;
    while (scanf("%d %d", &N, &K) != EOF) {
        init_Config();
        string name1, name2;
        int weight;
        for (int i = 0; i < N; i++) {
            cin >> name1 >> name2 >> weight;
            int name1int = transStrToInt(name1);
            int name2int = transStrToInt(name2);
            //无向图添加双向
            weights_array[name1int] += weight;
            weights_array[name2int] += weight;
            unionFather(name1int, name2int);
        }
        map<int, block>result;
        for (int gang_id = 0; gang_id < name_index; gang_id++) {
            int block_index = findFather(gang_id);
            if (result.find(block_index) == result.end()) {
                result[block_index] = block(block_index, weights_array[gang_id],
                                            weights_array[gang_id], gang_id, 1);
            } else {
                result[block_index].block_index = block_index;
                result[block_index].sum_weights += weights_array[gang_id];
                result[block_index].count++;
                if (result[block_index].head_of_weights < weights_array[gang_id]) {
                    result[block_index].head_of_weights = weights_array[gang_id];
                    result[block_index].head_of_gang = gang_id;
                }
            }

        }
        int count = 0;
        vector<person>head_of_gang;
        for (auto iter = result.begin(); iter != result.end(); iter++) {
            if (iter->second.count > 2 && iter->second.sum_weights / 2 > K) {
                count++;
                head_of_gang.push_back(person(intToStr[iter->second.head_of_gang],
                                              iter->second.count));
            }
        }
        cout << count << endl;
        for (auto iter : head_of_gang) {
            cout << iter.name << " " << iter.num << endl;
        }
        //printf("");

    }
}