#include<iostream>
#include<algorithm>
using namespace std;
const int MAX = 1000;
int v, n; // 頂點數與邊數
int flag[MAX/2]; // 連通分量標識符
struct Edge {
int v, w;
int weight;
}Edge[MAX], MST[MAX/2];
// 邊權重排序
bool cmp(struct Edge e1, struct Edge e2) {
return e1.weight < e2.weight;
}
void InitGraph() {
cin>>v>>n;
for (int i = 0; i < v; i++) {
flag[i] = i;
}
for (int i = 0; i < n; i++) {
cin>>Edge[i].v>>Edge[i].w>>Edge[i].weight;
}
sort(Edge, Edge + n, cmp);
}
// 判別連通分量是否連通
int Find(int p){
return flag[p];
}
void Union(int p, int q){
int pID = Find(p), qID = Find(q);
if (pID == qID)
return;
for (int i = 0; i < n; i++)
if (flag[i] == pID)
flag[i] = qID;
}
bool connected(int i, int j){
return Find(i) == Find(j);
}
// 克魯斯卡爾算法
void Kruskal() {
int numS = v, i = 0; // numS爲連通分量個數
cout<<"MST"<<endl;
while (numS > 1) {
int v = Edge[i].v, w = Edge[i].w;
if (!connected(v, w)) {
Union(v, w);
cout<<Edge[i].v<<" "<<Edge[i].w<<" "<<Edge[i].weight<<endl;
numS--;
}
i++;
}
}
int main() {
InitGraph();
Kruskal();
return 0;
}
// 測試樣例
6 10
0 1 6
0 2 1
0 3 5
1 2 5
1 4 3
2 3 5
2 4 6
2 5 4
3 5 2
4 5 6
// 測試結果
MST
0 2 1
3 5 2
1 4 3
2 5 4
1 2 5