/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author champon
 */

#include <iostream>
#include <fstream>
#include <bits/stdc++.h>
#define se cout << "test ok" << endl;
#define sp << " " <<
#define enl "\n"
using namespace std;
using ll=long long;
using ld=long double;
using vi = vector<int>;
using vii = vector<vector<int>>;
using vl = vector<ll>;
using vll = vector<vector<ll>>;
using vlll = vector<vector<vector<ll>>>;
using vc = vector<char>;
using vcc = vector<vector<char>>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
ll mod = ll(1e9)+7;
ll inf = ll(1e18);
void bl(bool b, ostream& out=cout){ out << (b ? "Yes" : "No") << endl; }
void bl2(bool b, ostream& out=cout){ out << (b ? "YES" : "NO") << endl; }
template<typename T> inline bool chmax(T &a, T b){ if(a<b){a=b; return true;} return false; }
template<typename T> inline bool chmin(T &a, T b){ if(a>b){a=b; return true;} return false; }
int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dy[] = {0, 1, 0, -1, 1, -1, -1, 1};

#ifndef INCLUDE_DEBUG_HPP
#define INCLUDE_DEBUG_HPP

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

namespace dbg {
    using ll = long long;

    class Debug {
    public:
        Debug(){}
        template<typename T>
        void vd(vector<T> vec);
        template<typename T>
        void vd2(vector<vector<T>> vec);
        template<typename T>
        void ad(T *arr, ll n);
        template<typename T, size_t N>
        void ad2(T (&arr)[N], ll n);
        template<typename T>
        void md(T mp);
    };

    template<typename T>
    void Debug::vd(vector<T> vec) {
        for (auto vv : vec) cout << vv << " ";
        cout << endl;
    }

    template<typename T>
    void Debug::vd2(vector<vector<T>> vec) {
        for (auto vv : vec) {
            for (auto vvv : vv) cout << vvv << " ";
            cout << endl;
        }
    }

    template<typename T>
    void Debug::ad(T *arr, ll n) {
        for (int i = 0; i <= n; i++) cout << arr[i] << " ";
        cout << endl;
    }

    template<typename T, size_t N>
    void Debug::ad2(T (&arr)[N], ll n) {
        for (int i = 0; i <= N; i++) for (int j = 0; j <= n; j++) cout << arr[i][j] << " ";
        cout << endl;
    }

    template<typename T>
    void Debug::md(T mp) {
        cout << "key : value" << endl;
        for (auto const &m : mp) cout << m.first << " : " << m.second << endl;
        cout << endl;
    }

}

#endif //INCLUDE_DEBUG_HPP

using dbg::Debug;
Debug debug;

//
// Created by champon1020 on 2020/04/11.
//

#ifndef INCLUDE_KRUSKAL_HPP


#include <algorithm>
using namespace std;

namespace kruskal {

    using ll = long long;

    class Kruskal {
        struct edge {
            int u, v;
            ll cost;
            edge(int u, int v, ll cost):u(u), v(v), cost(cost){};
        };

        // >>> simple unionfind
        vector<ll> par;
        void init_uf(int n) {
            par.assign(n, 0);
            for(int i=0; i<n; i++){
                par[i] = i;
            }
        }

        ll find(ll x){
            if(par[x] == x) return x;
            else return par[x] = find(par[x]);
        }

        void unite(ll x, ll y){
            x = find(x);
            y = find(y);
            if(x == y) return;
            par[x] = y;
        }

        bool same(ll x, ll y){
            return find(x) == find(y);
        }
        // <<< unionfind

        static bool comp(const edge& e1, const edge& e2) {
            return e1.cost < e2.cost;
        }

    public:
        vector<edge> es;
        int v, e;   // v: 頂点数, e: 辺数
        Kruskal(int v, int e);
        void add(int u, int v, ll cost);
        ll compute();
    };

    Kruskal::Kruskal(int v, int e):v(v),e(e) {}

    void Kruskal::add(int from, int to, ll cost) {
        es.emplace_back(from, to, cost);
    }

    ll Kruskal::compute() {
        sort(es.begin(), es.end(), comp);
        init_uf(v);
        ll res = 0;
        for(auto ee : es){
            if(!same(ee.u, ee.v)){
                unite(ee.u, ee.v);
                res += ee.cost;
            }
        }
        return res;
    }
}

#define INCLUDE_KRUSKAL_HPP

#endif //INCLUDE_KRUSKAL_HPP


// verify
// https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/2/GRL_2_A
using kruskal::Kruskal;

class a {
public:
	void solve(std::istream& in, std::ostream& out) {
	    int n, e;
	    in >> n >> e;
	    ll s, t, w;
	    Kruskal kr(n, e);
	    for(int i=0; i<e; i++){
	        in >> s >> t >> w;
            kr.add(s, t, w);
	    }

	    out << kr.compute() << enl;
	}
};


int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
	a solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}



Measured memory_bytes: 4928