/*
Copyright 2013 Marek "p2004a" Rusinowski
Computing MST - Borůvka's algorithm
*/
#include <cstdio>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
template <class T, class Compare = less<T> >
class LeftistHeap {
public:
class LeftistHeapNode {
public:
T value;
LeftistHeapNode *left, *right;
int s;
LeftistHeapNode(T vvalue, LeftistHeapNode *lleft, LeftistHeapNode *rright, int ss)
: value(vvalue), left(lleft), right(rright), s(ss) {}
LeftistHeapNode(const LeftistHeapNode &node) : value(node.value), left(NULL), right(NULL), s(node.s) {
if (node.left != NULL) left = new LeftistHeapNode(*node.left);
if (node.right != NULL) right = new LeftistHeapNode(*node.right);
}
~LeftistHeapNode() {
delete left;
delete right;
}
};
LeftistHeapNode *merge(LeftistHeapNode *h1, LeftistHeapNode *h2) {
if (h1 == NULL) return h2;
if (h2 == NULL) return h1;
if (!cmp(h1->value, h2->value)) swap(h1, h2);
if (h1->left == NULL) h1->left = h2;
else {
h1->right = merge(h1->right, h2);
if (h1->left->s < h1->right->s) swap(h1->left, h1->right);
h1->s = h1->right->s + 1;
}
return h1;
}
private:
LeftistHeapNode *root;
size_t heap_size;
Compare cmp;
public:
LeftistHeap() : root(NULL), heap_size(0) {}
LeftistHeap(const LeftistHeap &heap) : root(NULL), heap_size(heap.heap_size) {
if (heap.root != NULL) root = new LeftistHeapNode(*heap.root);
}
~LeftistHeap() {
delete root;
}
LeftistHeap &operator=(const LeftistHeap &heap) {
delete root;
root = new LeftistHeapNode(*heap.root);
heap_size = heap.heap_size;
return *this;
}
LeftistHeapNode *insert(T value) {
LeftistHeapNode *node = new LeftistHeapNode(value, NULL, NULL, 0);
root = merge(root, node);
++heap_size;
return node;
}
T top() {
if (root == NULL) throw "Cannot get min from empty heap";
return root->value;
}
T deltop() {
if (root == NULL) throw "Cannot del min from empty heap";
LeftistHeapNode *tmp = root;
root = merge(root->left, root->right);
--heap_size;
tmp->left = tmp->right = NULL;
T value = tmp->value;
delete tmp;
return value;
}
void merge(LeftistHeap &heap) {
root = merge(root, heap.root);
heap_size += heap.heap_size;
heap.root = NULL;
heap.heap_size = 0;
}
size_t size() {
return heap_size;
}
};
class FindUnion {
int *root, *rank;
public:
FindUnion(int n) {
root = new int [n];
rank = new int [n];
for (int i = 0; i < n; ++i) root[i] = i;
}
~FindUnion() {
delete root;
delete rank;
}
int find_set(int v) {
if (root[v] == v) return v;
root[v] = find_set(root[v]);
return root[v];
}
void union_sets(int v, int u) {
v = find_set(v);
u = find_set(u);
if (rank[v] < rank[u]) {
root[v] = u;
} else if (rank[v] > rank[u]) {
root[u] = v;
} else {
root[v] = u;
++rank[v];
}
}
};
int main() {
int n, m;
scanf("%d %d", &n, &m);
vector<LeftistHeap<pair<int, pair<int, int> > > > edges(n);
FindUnion fu(n);
for (int i = 0; i < m; ++i) {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
--a, --b;
edges[a].insert(make_pair(c, make_pair(a, b)));
edges[b].insert(make_pair(c, make_pair(b, a)));
}
vector<pair<int, int> > out;
for (int i = 1; i < n; ++i) {
int u, v = fu.find_set(i);
while ((u = fu.find_set(edges[v].top().second.second)) == v) {
edges[v].deltop();
}
out.push_back(edges[v].top().second);
fu.union_sets(u, v);
if (v != fu.find_set(v)) swap(u, v);
edges[v].merge(edges[u]);
}
for (vector<pair<int, int> >::iterator it = out.begin(); it != out.end(); ++it) {
printf("%d %d\n", it->first + 1, it->second + 1);
}
return 0;
}
LyoKICBDb3B5cmlnaHQgMjAxMyBNYXJlayAicDIwMDRhIiBSdXNpbm93c2tpCiAgQ29tcHV0aW5nIE1TVCAtIEJvcsWvdmthJ3MgYWxnb3JpdGhtCiovCiNpbmNsdWRlIDxjc3RkaW8+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBDb21wYXJlID0gbGVzczxUPiA+CmNsYXNzIExlZnRpc3RIZWFwIHsKIHB1YmxpYzoKICBjbGFzcyBMZWZ0aXN0SGVhcE5vZGUgewogICBwdWJsaWM6CiAgICBUIHZhbHVlOwogICAgTGVmdGlzdEhlYXBOb2RlICpsZWZ0LCAqcmlnaHQ7CiAgICBpbnQgczsKCiAgICBMZWZ0aXN0SGVhcE5vZGUoVCB2dmFsdWUsIExlZnRpc3RIZWFwTm9kZSAqbGxlZnQsIExlZnRpc3RIZWFwTm9kZSAqcnJpZ2h0LCBpbnQgc3MpCiAgICAgOiB2YWx1ZSh2dmFsdWUpLCBsZWZ0KGxsZWZ0KSwgcmlnaHQocnJpZ2h0KSwgcyhzcykge30KCiAgICBMZWZ0aXN0SGVhcE5vZGUoY29uc3QgTGVmdGlzdEhlYXBOb2RlICZub2RlKSA6IHZhbHVlKG5vZGUudmFsdWUpLCBsZWZ0KE5VTEwpLCByaWdodChOVUxMKSwgcyhub2RlLnMpIHsKICAgICAgaWYgKG5vZGUubGVmdCAhPSBOVUxMKSBsZWZ0ID0gbmV3IExlZnRpc3RIZWFwTm9kZSgqbm9kZS5sZWZ0KTsKICAgICAgaWYgKG5vZGUucmlnaHQgIT0gTlVMTCkgcmlnaHQgPSBuZXcgTGVmdGlzdEhlYXBOb2RlKCpub2RlLnJpZ2h0KTsKICAgIH0KCiAgICB+TGVmdGlzdEhlYXBOb2RlKCkgewogICAgICBkZWxldGUgbGVmdDsKICAgICAgZGVsZXRlIHJpZ2h0OwogICAgfQogIH07CgogIExlZnRpc3RIZWFwTm9kZSAqbWVyZ2UoTGVmdGlzdEhlYXBOb2RlICpoMSwgTGVmdGlzdEhlYXBOb2RlICpoMikgewogICAgaWYgKGgxID09IE5VTEwpIHJldHVybiBoMjsKICAgIGlmIChoMiA9PSBOVUxMKSByZXR1cm4gaDE7CiAgICBpZiAoIWNtcChoMS0+dmFsdWUsIGgyLT52YWx1ZSkpIHN3YXAoaDEsIGgyKTsKICAgIGlmIChoMS0+bGVmdCA9PSBOVUxMKSBoMS0+bGVmdCA9IGgyOwogICAgZWxzZSB7CiAgICAgIGgxLT5yaWdodCA9IG1lcmdlKGgxLT5yaWdodCwgaDIpOwogICAgICBpZiAoaDEtPmxlZnQtPnMgPCBoMS0+cmlnaHQtPnMpIHN3YXAoaDEtPmxlZnQsIGgxLT5yaWdodCk7CiAgICAgIGgxLT5zID0gaDEtPnJpZ2h0LT5zICsgMTsKICAgIH0KICAgIHJldHVybiBoMTsKICB9CgogcHJpdmF0ZToKICBMZWZ0aXN0SGVhcE5vZGUgKnJvb3Q7CiAgc2l6ZV90IGhlYXBfc2l6ZTsKICBDb21wYXJlIGNtcDsKCiBwdWJsaWM6CiAgTGVmdGlzdEhlYXAoKSA6IHJvb3QoTlVMTCksIGhlYXBfc2l6ZSgwKSB7fQoKICBMZWZ0aXN0SGVhcChjb25zdCBMZWZ0aXN0SGVhcCAmaGVhcCkgOiByb290KE5VTEwpLCBoZWFwX3NpemUoaGVhcC5oZWFwX3NpemUpIHsKICAgIGlmIChoZWFwLnJvb3QgIT0gTlVMTCkgcm9vdCA9IG5ldyBMZWZ0aXN0SGVhcE5vZGUoKmhlYXAucm9vdCk7CiAgfQoKICB+TGVmdGlzdEhlYXAoKSB7CiAgICBkZWxldGUgcm9vdDsKICB9CgogIExlZnRpc3RIZWFwICZvcGVyYXRvcj0oY29uc3QgTGVmdGlzdEhlYXAgJmhlYXApIHsKICAgIGRlbGV0ZSByb290OwogICAgcm9vdCA9IG5ldyBMZWZ0aXN0SGVhcE5vZGUoKmhlYXAucm9vdCk7CiAgICBoZWFwX3NpemUgPSBoZWFwLmhlYXBfc2l6ZTsKICAgIHJldHVybiAqdGhpczsKICB9CgogIExlZnRpc3RIZWFwTm9kZSAqaW5zZXJ0KFQgdmFsdWUpIHsKICAgIExlZnRpc3RIZWFwTm9kZSAqbm9kZSA9IG5ldyBMZWZ0aXN0SGVhcE5vZGUodmFsdWUsIE5VTEwsIE5VTEwsIDApOwogICAgcm9vdCA9IG1lcmdlKHJvb3QsIG5vZGUpOwogICAgKytoZWFwX3NpemU7CiAgICByZXR1cm4gbm9kZTsKICB9CgogIFQgdG9wKCkgewogICAgaWYgKHJvb3QgPT0gTlVMTCkgdGhyb3cgIkNhbm5vdCBnZXQgbWluIGZyb20gZW1wdHkgaGVhcCI7CiAgICByZXR1cm4gcm9vdC0+dmFsdWU7CiAgfQoKICBUIGRlbHRvcCgpIHsKICAgIGlmIChyb290ID09IE5VTEwpIHRocm93ICJDYW5ub3QgZGVsIG1pbiBmcm9tIGVtcHR5IGhlYXAiOwogICAgTGVmdGlzdEhlYXBOb2RlICp0bXAgPSByb290OwogICAgcm9vdCA9IG1lcmdlKHJvb3QtPmxlZnQsIHJvb3QtPnJpZ2h0KTsKICAgIC0taGVhcF9zaXplOwogICAgdG1wLT5sZWZ0ID0gdG1wLT5yaWdodCA9IE5VTEw7CiAgICBUIHZhbHVlID0gdG1wLT52YWx1ZTsKICAgIGRlbGV0ZSB0bXA7CiAgICByZXR1cm4gdmFsdWU7CiAgfQoKICB2b2lkIG1lcmdlKExlZnRpc3RIZWFwICZoZWFwKSB7CiAgICByb290ID0gbWVyZ2Uocm9vdCwgaGVhcC5yb290KTsKICAgIGhlYXBfc2l6ZSArPSBoZWFwLmhlYXBfc2l6ZTsKICAgIGhlYXAucm9vdCA9IE5VTEw7CiAgICBoZWFwLmhlYXBfc2l6ZSA9IDA7CiAgfQoKICBzaXplX3Qgc2l6ZSgpIHsKICAgIHJldHVybiBoZWFwX3NpemU7CiAgfQp9OwoKY2xhc3MgRmluZFVuaW9uIHsKICBpbnQgKnJvb3QsICpyYW5rOwogIAogcHVibGljOgogIEZpbmRVbmlvbihpbnQgbikgewogICAgcm9vdCA9IG5ldyBpbnQgW25dOwogICAgcmFuayA9IG5ldyBpbnQgW25dOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyArK2kpIHJvb3RbaV0gPSBpOwogIH0KICAKICB+RmluZFVuaW9uKCkgewogICAgZGVsZXRlIHJvb3Q7CiAgICBkZWxldGUgcmFuazsKICB9CiAKICBpbnQgZmluZF9zZXQoaW50IHYpIHsKICAgIGlmIChyb290W3ZdID09IHYpIHJldHVybiB2OwogICAgcm9vdFt2XSA9IGZpbmRfc2V0KHJvb3Rbdl0pOwogICAgcmV0dXJuIHJvb3Rbdl07CiAgfQogICAKICB2b2lkIHVuaW9uX3NldHMoaW50IHYsIGludCB1KSB7CiAgICB2ID0gZmluZF9zZXQodik7CiAgICB1ID0gZmluZF9zZXQodSk7CiAgICBpZiAocmFua1t2XSA8IHJhbmtbdV0pIHsKICAgICAgcm9vdFt2XSA9IHU7CiAgICB9IGVsc2UgaWYgKHJhbmtbdl0gPiByYW5rW3VdKSB7CiAgICAgIHJvb3RbdV0gPSB2OwogICAgfSBlbHNlIHsKICAgICAgcm9vdFt2XSA9IHU7CiAgICAgICsrcmFua1t2XTsKICAgIH0KICB9Cn07CgppbnQgbWFpbigpIHsKICBpbnQgbiwgbTsKICBzY2FuZigiJWQgJWQiLCAmbiwgJm0pOwogIHZlY3RvcjxMZWZ0aXN0SGVhcDxwYWlyPGludCwgcGFpcjxpbnQsIGludD4gPiA+ID4gZWRnZXMobik7CiAgRmluZFVuaW9uIGZ1KG4pOwogIGZvciAoaW50IGkgPSAwOyBpIDwgbTsgKytpKSB7CiAgICBpbnQgYSwgYiwgYzsKICAgIHNjYW5mKCIlZCAlZCAlZCIsICZhLCAmYiwgJmMpOwogICAgLS1hLCAtLWI7CiAgICBlZGdlc1thXS5pbnNlcnQobWFrZV9wYWlyKGMsIG1ha2VfcGFpcihhLCBiKSkpOwogICAgZWRnZXNbYl0uaW5zZXJ0KG1ha2VfcGFpcihjLCBtYWtlX3BhaXIoYiwgYSkpKTsKICB9CiAgCiAgdmVjdG9yPHBhaXI8aW50LCBpbnQ+ID4gb3V0OwogIGZvciAoaW50IGkgPSAxOyBpIDwgbjsgKytpKSB7CiAgICBpbnQgdSwgdiA9IGZ1LmZpbmRfc2V0KGkpOwogICAgd2hpbGUgKCh1ID0gZnUuZmluZF9zZXQoZWRnZXNbdl0udG9wKCkuc2Vjb25kLnNlY29uZCkpID09IHYpIHsKICAgICAgZWRnZXNbdl0uZGVsdG9wKCk7CiAgICB9CiAgICBvdXQucHVzaF9iYWNrKGVkZ2VzW3ZdLnRvcCgpLnNlY29uZCk7CiAgICBmdS51bmlvbl9zZXRzKHUsIHYpOwogICAgaWYgKHYgIT0gZnUuZmluZF9zZXQodikpIHN3YXAodSwgdik7CiAgICBlZGdlc1t2XS5tZXJnZShlZGdlc1t1XSk7CiAgfQogIAogIGZvciAodmVjdG9yPHBhaXI8aW50LCBpbnQ+ID46Oml0ZXJhdG9yIGl0ID0gb3V0LmJlZ2luKCk7IGl0ICE9IG91dC5lbmQoKTsgKytpdCkgewogICAgcHJpbnRmKCIlZCAlZFxuIiwgaXQtPmZpcnN0ICsgMSwgaXQtPnNlY29uZCArIDEpOwogIH0KICByZXR1cm4gMDsKfQo=