// https://omegaup.com/arena/problem/Arbol-abarcador-de-costo-minimo 
#include <algorithm> 
#include <iostream> 
#include <queue> 
#include <vector> 
 
struct pareja { 
   int vertice, costo; 
}; 
 
bool operator<(pareja a, pareja b) { 
   return a.costo > b.costo; 
} 
 
int main( ) { 
   int n, a; 
   std::cin >> n >> a; 
 
   std::vector<pareja> adyacencia[n]; 
   for (int i = 0; i < a; ++i) { 
      int x, y, c; 
      std::cin >> x >> y >> c; 
      adyacencia[x].push_back({ y, c }); 
      adyacencia[y].push_back({ x, c }); 
   } 
 
   std::priority_queue<pareja> cp; 
   cp.push({ 0, 0 }); 
   bool procesado[n] = { }; 
   int suma = 0; 
   do { 
      pareja actual = cp.top( ); 
      cp.pop( ); 
      if (!procesado[actual.vertice]) { 
         procesado[actual.vertice] = true; 
         suma += actual.costo; 
         for (pareja arista : adyacencia[actual.vertice]) { 
            cp.push({ arista.vertice, arista.costo }); 
         } 
      } 
   } while (!cp.empty( )); 
 
   std::cout << suma; 
}