use std::io::prelude::*;
use std::cmp;
#[macro_use] extern crate scan_fmt;
struct UnionFind {
p: Vec<Option<usize>>,
s: Vec<usize>,
}
impl UnionFind {
fn new(size: usize) -> UnionFind {
UnionFind {
p: vec![None; size],
s: vec![1; size],
}
}
fn unite(&mut self, u: usize, v: usize) -> bool {
let u = self.root(u);
let v = self.root(v);
if u == v { return false; }
if self.s[u] < self.s[v] {
self.s[u] += self.s[v];
self.p[v] = Some(u);
} else {
self.s[v] += self.s[u];
self.p[u] = Some(v);
}
return true;
}
fn root(&self, u: usize) -> usize {
match self.p[u] {
Some(v) => return self.root(v),
None => return u,
}
}
}
fn main() {
let mut size = 0usize;
let mut edges = vec![];
let stdin = std::io::stdin();
for line in stdin.lock().lines() {
let (u, v, w) = scan_fmt!(&line.unwrap(), "{} {} {}", usize, usize, i32);
let u = u.unwrap();
let v = v.unwrap();
let w = w.unwrap();
edges.push((u, v, w));
size = cmp::max(size, u+1);
size = cmp::max(size, v+1);
}
let size = size;
edges.sort_by(|e1, e2| e1.2.cmp(&e2.2));
let mut uf = UnionFind::new(size);
let mut ans = 0;
for e in edges {
let (i, j, w) = e;
if uf.unite(i,j) {
ans += w;
println!("{} {} {}", i, j, w);
}
}
println!("{}", ans);
}
dXNlIHN0ZDo6aW86OnByZWx1ZGU6Oio7CnVzZSBzdGQ6OmNtcDsKCiNbbWFjcm9fdXNlXSBleHRlcm4gY3JhdGUgc2Nhbl9mbXQ7CgpzdHJ1Y3QgVW5pb25GaW5kIHsKICAgIHA6IFZlYzxPcHRpb248dXNpemU+PiwKICAgIHM6IFZlYzx1c2l6ZT4sCn0KaW1wbCBVbmlvbkZpbmQgewogICAgZm4gbmV3KHNpemU6IHVzaXplKSAtPiBVbmlvbkZpbmQgewogICAgICAgIFVuaW9uRmluZCB7CiAgICAgICAgICAgIHA6IHZlYyFbTm9uZTsgc2l6ZV0sCiAgICAgICAgICAgIHM6IHZlYyFbMTsgc2l6ZV0sCiAgICAgICAgfQogICAgfQogICAgZm4gdW5pdGUoJm11dCBzZWxmLCB1OiB1c2l6ZSwgdjogdXNpemUpIC0+IGJvb2wgewogICAgICAgIGxldCB1ID0gc2VsZi5yb290KHUpOwogICAgICAgIGxldCB2ID0gc2VsZi5yb290KHYpOwogICAgICAgIGlmIHUgPT0gdiB7IHJldHVybiBmYWxzZTsgfQogICAgICAgIGlmIHNlbGYuc1t1XSA8IHNlbGYuc1t2XSB7CiAgICAgICAgICAgIHNlbGYuc1t1XSArPSBzZWxmLnNbdl07CiAgICAgICAgICAgIHNlbGYucFt2XSA9IFNvbWUodSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VsZi5zW3ZdICs9IHNlbGYuc1t1XTsKICAgICAgICAgICAgc2VsZi5wW3VdID0gU29tZSh2KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgZm4gcm9vdCgmc2VsZiwgdTogdXNpemUpIC0+IHVzaXplIHsKICAgICAgICBtYXRjaCBzZWxmLnBbdV0gewogICAgICAgICAgICBTb21lKHYpID0+IHJldHVybiBzZWxmLnJvb3QodiksCiAgICAgICAgICAgIE5vbmUgICAgPT4gcmV0dXJuIHUsCiAgICAgICAgfQogICAgfQp9CgpmbiBtYWluKCkgewogICAgbGV0IG11dCBzaXplID0gMHVzaXplOwogICAgbGV0IG11dCBlZGdlcyA9IHZlYyFbXTsKICAgIGxldCBzdGRpbiA9IHN0ZDo6aW86OnN0ZGluKCk7CgogICAgZm9yIGxpbmUgaW4gc3RkaW4ubG9jaygpLmxpbmVzKCkgewogICAgICAgIGxldCAodSwgdiwgdykgPSBzY2FuX2ZtdCEoJmxpbmUudW53cmFwKCksICJ7fSB7fSB7fSIsIHVzaXplLCB1c2l6ZSwgaTMyKTsKICAgICAgICBsZXQgdSA9IHUudW53cmFwKCk7CiAgICAgICAgbGV0IHYgPSB2LnVud3JhcCgpOwogICAgICAgIGxldCB3ID0gdy51bndyYXAoKTsKICAgICAgICBlZGdlcy5wdXNoKCh1LCB2LCB3KSk7CiAgICAgICAgc2l6ZSA9IGNtcDo6bWF4KHNpemUsIHUrMSk7CiAgICAgICAgc2l6ZSA9IGNtcDo6bWF4KHNpemUsIHYrMSk7CiAgICB9CiAgICBsZXQgc2l6ZSA9IHNpemU7CiAgICBlZGdlcy5zb3J0X2J5KHxlMSwgZTJ8IGUxLjIuY21wKCZlMi4yKSk7CgogICAgbGV0IG11dCB1ZiA9IFVuaW9uRmluZDo6bmV3KHNpemUpOwogICAgbGV0IG11dCBhbnMgPSAwOwoKICAgIGZvciBlIGluIGVkZ2VzIHsKICAgICAgICBsZXQgKGksIGosIHcpID0gZTsKICAgICAgICBpZiB1Zi51bml0ZShpLGopIHsKICAgICAgICAgICAgYW5zICs9IHc7CiAgICAgICAgICAgIHByaW50bG4hKCJ7fSB7fSB7fSIsIGksIGosIHcpOwogICAgICAgIH0KICAgIH0KICAgIHByaW50bG4hKCJ7fSIsIGFucyk7Cn0K