stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
/**

 * Created by hiramekun at 20:44 on 2019-12-08.

 */

#include <bits/stdc++.h>



using namespace std;

using ll = long long;

#define rep(i, n) for(ll i = 0; i < (ll)(n); i++)



int main() {

    ll h, w;

    cin >> h >> w;

//    vector<vector<ll>> a(h, vector<ll>(w)), b(h, vector<ll>(w));

    int a[h][w], b[h][w];

    rep(i, h) rep(j, w) cin >> a[i][j];

    rep(i, h) rep(j, w) cin >> b[i][j];



    ll max_diff = 2 * 80 * 160;

    vector<vector<vector<bool>>> dp(h, vector<vector<bool>>(w, vector<bool>(max_diff)));

//    bool dp[h][w][max_diff];

    rep(i, h) rep(j, w) rep(l, max_diff) dp[i][j][l] = false;



    ll mid = max_diff / 2;

    dp[0][0][b[0][0] - a[0][0] + mid] = true;

    dp[0][0][-b[0][0] + a[0][0] + mid] = true;



    rep(i, h) {

        rep(j, w) {

            rep(l, max_diff) {

                if (!dp[i][j][l]) continue;

                if (i + 1 <= h - 1) {

                    dp[i + 1][j][l + b[i + 1][j] - a[i + 1][j]] = true;

                    dp[i + 1][j][l - b[i + 1][j] + a[i + 1][j]] = true;

                }

                if (j + 1 <= w - 1) {

                    dp[i][j + 1][l + b[i][j + 1] - a[i][j + 1]] = true;

                    dp[i][j + 1][l - b[i][j + 1] + a[i][j + 1]] = true;

                }

            }

        }

    }

    ll ans = 1e18;

    rep(i, max_diff) {

        if (dp[h - 1][w - 1][i]) ans = min(ans, abs(i - mid));

    }

    cout << ans << '\n';

}

// Optimized solution to the same problem (faster):
/**

 * Created by hiramekun at 20:44 on 2019-12-08.

 */

#include <bits/stdc++.h>



using namespace std;

using ll = long long;

#define rep(i, n) for(ll i = 0; i < (ll)(n); i++)



int main() {

    ll h, w;

    cin >> h >> w;

//    vector<vector<ll>> a(h, vector<ll>(w)), b(h, vector<ll>(w));

    int a[h][w], b[h][w];

    rep(i, h) rep(j, w) cin >> a[i][j];

    rep(i, h) rep(j, w) cin >> b[i][j];



    ll max_diff = 2 * 80 * 160;

//    vector<vector<vector<bool>>> dp(h, vector<vector<bool>>(w, vector<bool>(max_diff)));

    bool dp[h][w][max_diff];

    rep(i, h) rep(j, w) rep(l, max_diff) dp[i][j][l] = false;



    ll mid = max_diff / 2;

    dp[0][0][b[0][0] - a[0][0] + mid] = true;

    dp[0][0][-b[0][0] + a[0][0] + mid] = true;



    rep(i, h) {

        rep(j, w) {

            rep(l, max_diff) {

                if (!dp[i][j][l]) continue;

                if (i + 1 <= h - 1) {

                    dp[i + 1][j][l + b[i + 1][j] - a[i + 1][j]] = true;

                    dp[i + 1][j][l - b[i + 1][j] + a[i + 1][j]] = true;

                }

                if (j + 1 <= w - 1) {

                    dp[i][j + 1][l + b[i][j + 1] - a[i][j + 1]] = true;

                    dp[i][j + 1][l - b[i][j + 1] + a[i][j + 1]] = true;

                }

            }

        }

    }

    ll ans = 1e18;

    rep(i, max_diff) {

        if (dp[h - 1][w - 1][i]) ans = min(ans, abs(i - mid));

    }

    cout << ans << '\n';

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;



int main(){

    int h, w;

    cin >> h >> w;

    vector<vector<int>> A(h, vector<int>(w)), B(h, vector<int>(w));

    for (int i = 0; i < h; i++)

        copy_n(istream_iterator<int>(cin), w, A[i].begin());



    for (int i = 0; i < h; i++)

        copy_n(istream_iterator<int>(cin), w, B[i].begin());



    const int sup = 1e5;

    vector<vector<bitset<sup>>> M(h + 1, vector<bitset<sup>>(w + 1));



    M[0][0][sup / 2] = true;

    for (int i = 0; i < h; i++){

        for (int j = 0; j < w; j++){

            int c = abs(A[i][j] - B[i][j]);

            M[i + 1][j] |= M[i][j] << c;

            M[i + 1][j] |= M[i][j] >> c;

            M[i][j + 1] |= M[i][j] << c;

            M[i][j + 1] |= M[i][j] >> c;

        }

    }



    int ans = 1e9;

    for (int k = 0; k < sup; k++){

        if (M[h - 1][w][k])

            ans = min(ans, abs(k - sup / 2));

    }



    cout << ans << endl;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>



using namespace std;



int main(){

    int h, w;

    cin >> h >> w;

    vector<vector<int>> A(h, vector<int>(w)), B(h, vector<int>(w));

    for (int i = 0; i < h; i++)

        copy_n(istream_iterator<int>(cin), w, A[i].begin());



    for (int i = 0; i < h; i++)

        copy_n(istream_iterator<int>(cin), w, B[i].begin());



    const int sup = 160 * 160 + 1;

    vector<vector<bitset<sup>>> M(h + 1, vector<bitset<sup>>(w + 1));



    M[0][0][sup / 2] = true;

    for (int i = 0; i < h; i++){

        for (int j = 0; j < w; j++){

            int c = abs(A[i][j] - B[i][j]);

            M[i + 1][j] |= M[i][j] << c;

            M[i + 1][j] |= M[i][j] >> c;

            M[i][j + 1] |= M[i][j] << c;

            M[i][j + 1] |= M[i][j] >> c;

        }

    }



    int ans = 1e9;

    for (int k = 0; k < sup; k++){

        if (M[h - 1][w][k])

            ans = min(ans, abs(k - sup / 2));

    }



    cout << ans << endl;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include "bits/stdc++.h"

#define rep(i,n) for(int i=0;i<n;i++)

using namespace std;



using ll = long long;

const ll MOD = 1e9 + 7;

const int INF = 1e9;



int main() {

    int H, W;

    cin >> H >> W;

    vector<vector<int>> A(H, vector<int>(W)), B(H, vector<int>(W));

    rep(i, H) rep(j, W) cin >> A[i][j];

    rep(i, H) rep(j, W) cin >> B[i][j];

    vector<vector<vector<int>>> s(H + 1, vector<vector<int>>(W + 1, vector<int>(12800, 0)));

    s[1][1][abs(A[0][0] - B[0][0])] = 1;

    rep(i, H) {

        rep(j, W) {

            //cout << i << j << endl;

            if (i == 0 && j == 0) continue;

            rep(k, 12800) {

                if (s[i][j + 1][k] == 0) continue;

                s[i + 1][j + 1][k + abs(A[i][j] - B[i][j])] = 1;

                s[i + 1][j + 1][abs(k - abs(A[i][j] - B[i][j]))] = 1;

            }

            rep(k, 12800) {

                if (s[i + 1][j][k] == 0) continue;

                s[i + 1][j + 1][k + abs(A[i][j] - B[i][j])] = 1;

                s[i + 1][j + 1][abs(k - abs(A[i][j] - B[i][j]))] = 1;

            }

            //cout << "30" << endl;

        }

    }

    //cout << "end" << endl;

    rep(i, 12800) {

        if (s[H][W][i] == 1) {

            cout << i << endl;

            return 0;

        }

    }

}

// Optimized solution to the same problem (faster):
#include "bits/stdc++.h"

#define rep(i,n) for(int i=0;i<n;i++)

using namespace std;



using ll = long long;



int main() {

    int H, W;

    cin >> H >> W;

    vector<vector<int>> A(H, vector<int>(W)), B(H, vector<int>(W));

    rep(i, H) {

        rep(j, W) {

            cin >> A[i][j];

        }

    }

    rep(i, H) {

        rep(j, W) {

            cin >> B[i][j];

        }

    }

    vector<vector<vector<bool>>> s(H + 1, vector<vector<bool>>(W + 1, vector<bool> (12800, false)));

    s[0][1][0] = true;

    s[1][0][0] = true;

    rep(i, H) {

        rep(j, W) {

            rep(k, 12800) {

                if (s[i][j + 1][k] || s[i + 1][j][k]) {

                    s[i + 1][j + 1][abs(k + A[i][j] - B[i][j])] = true;

                    s[i + 1][j + 1][abs(k - A[i][j] + B[i][j])] = true;

                }

            }

        }

    }

    rep(i, 12800) {

        if (s[H][W][i]) {

            cout << i << "\n";

            return 0;

        }

    }

    /*

    rep(i, H) {

        cout << "i=" << i << "\n";

        rep(j, W) {

            cout << "j=" << j << " s=";

            for (auto k : s[i + 1][j + 1]) {

                cout << k << " ";

            }

            cout << "\n";

        }

    }

    */

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

const int N=85,low=80*80*3;

int a[N][N],b[N][N];

bitset<N*N*10>dp[N][N];

int mx[N][N];

int n,m;

int main()

{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        scanf("%d",&a[i][j]);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        scanf("%d",&b[i][j]);

    dp[1][1].set(a[1][1]-b[1][1]+low,1);

    dp[1][1].set(b[1][1]-a[1][1]+low,1);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

    {

        if(i==1&&j==1) continue;

        int x=abs(a[i][j]-b[i][j]);

        dp[i][j]=(dp[i-1][j]<<x)|(dp[i-1][j]>>x)|(dp[i][j-1]<<x)|(dp[i][j-1]>>x);

    }

    int ans=1e9;

    for(int i=0;i<=low*3;i++)

        if(dp[n][m][i])

        {

            ans=min(ans,abs(i-low));

        }

    printf("%d\n",ans);

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

const int N=85,low=81*81;

int a[N][N],b[N][N];

bitset<N*N*2>dp[N][N];

int mx[N][N];

int n,m;

int main()

{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        scanf("%d",&a[i][j]);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        scanf("%d",&b[i][j]);

    dp[1][1].set(a[1][1]-b[1][1]+low,1);

    dp[1][1].set(b[1][1]-a[1][1]+low,1);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

    {

        if(i==1&&j==1) continue;

        int x=abs(a[i][j]-b[i][j]);

        dp[i][j]=(dp[i-1][j]<<x)|(dp[i-1][j]>>x)|(dp[i][j-1]<<x)|(dp[i][j-1]>>x);

    }

    int ans=1e9;

    for(int i=0;i<=low*2;i++)

        if(dp[n][m][i])

        {

            ans=min(ans,abs(i-low));

        }

    printf("%d\n",ans);

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

const int N=85,low=80*80*3;

int a[N][N],b[N][N];

bitset<N*N*8>dp[N][N];

int mx[N][N];

int n,m;

int main()

{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        scanf("%d",&a[i][j]);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        scanf("%d",&b[i][j]);

    dp[1][1].set(a[1][1]-b[1][1]+low,1);

    dp[1][1].set(b[1][1]-a[1][1]+low,1);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

    {

        if(i==1&&j==1) continue;

        int x=abs(a[i][j]-b[i][j]);

        dp[i][j]=(dp[i-1][j]<<x)|(dp[i-1][j]>>x)|(dp[i][j-1]<<x)|(dp[i][j-1]>>x);

    }

    int ans=1e9;

    for(int i=0;i<=low*3;i++)

        if(dp[n][m][i])

        {

            ans=min(ans,abs(i-low));

        }

    printf("%d\n",ans);

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

const int N=85,low=81*81;

int a[N][N],b[N][N];

bitset<N*N*2>dp[N][N];

int mx[N][N];

int n,m;

int main()

{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        scanf("%d",&a[i][j]);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

        scanf("%d",&b[i][j]);

    dp[1][1].set(a[1][1]-b[1][1]+low,1);

    dp[1][1].set(b[1][1]-a[1][1]+low,1);

    for(int i=1;i<=n;i++)

        for(int j=1;j<=m;j++)

    {

        if(i==1&&j==1) continue;

        int x=abs(a[i][j]-b[i][j]);

        dp[i][j]=(dp[i-1][j]<<x)|(dp[i-1][j]>>x)|(dp[i][j-1]<<x)|(dp[i][j-1]>>x);

    }

    int ans=1e9;

    for(int i=0;i<=low*2;i++)

        if(dp[n][m][i])

        {

            ans=min(ans,abs(i-low));

        }

    printf("%d\n",ans);

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <vector>

#include <bitset>

#include <algorithm>

#include <cmath>



using namespace std;



int main(void) {

    int H, W;

    cin >> H >> W;

    vector< vector<int> > grid(H+2, vector<int>(W+2));

    for(int i=1; i<=H; i++) {

        for(int j=1; j<=W; j++) {

            int A;

            cin >> A;

            grid[i][j] += A;

        }

    }

    for(int i=1; i<=H; i++) {

        for(int j=1; j<=W; j++) {

            int B;

            cin >> B;

            grid[i][j] -= B;

        }

    }



    vector< vector< bitset<100'000> > > dp(H+2, vector< bitset<100'000> >(W+2));

    dp[1][1].set(50'000 + grid[1][1]);

    dp[1][1].set(50'000 - grid[1][1]);

    for(int i=1; i<=H; i++) {

        for(int j=1; j<=W; j++) {

            for(int k=100; k<=99'900; k++) {

                if(dp[i][j][k]) {

                    dp[i+1][j].set(k + grid[i+1][j]);

                    dp[i+1][j].set(k - grid[i+1][j]);

                    dp[i][j+1].set(k + grid[i][j+1]);

                    dp[i][j+1].set(k - grid[i][j+1]);

                }

            }

        }

    }



    int ans = numeric_limits<int>::max();

    for(int k=100; k<=99'900; k++) {

        if(dp[H][W][k]) {

            ans = min(ans, abs(50'000 - k));

        }

    }



    cout << ans << endl;

    return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <vector>

#include <bitset>

#include <algorithm>

#include <cmath>



using namespace std;



int main(void) {

    int H, W;

    cin >> H >> W;

    vector< vector<int> > grid(H+2, vector<int>(W+2));

    for(int i=1; i<=H; i++) {

        for(int j=1; j<=W; j++) {

            int A;

            cin >> A;

            grid[i][j] += A;

        }

    }

    for(int i=1; i<=H; i++) {

        for(int j=1; j<=W; j++) {

            int B;

            cin >> B;

            grid[i][j] -= B;

        }

    }



    vector< vector< bitset<20'000> > > dp(H+2, vector< bitset<20'000> >(W+2));

    dp[1][1].set(10'000 + grid[1][1]);

    dp[1][1].set(10'000 - grid[1][1]);

    for(int i=1; i<=H; i++) {

        for(int j=1; j<=W; j++) {

            for(int k=100; k<=19'900; k++) {

                if(dp[i][j][k]) {

                    dp[i+1][j].set(k + grid[i+1][j]);

                    dp[i+1][j].set(k - grid[i+1][j]);

                    dp[i][j+1].set(k + grid[i][j+1]);

                    dp[i][j+1].set(k - grid[i][j+1]);

                }

            }

        }

    }



    int ans = numeric_limits<int>::max();

    for(int k=100; k<=19'900; k++) {

        if(dp[H][W][k]) {

            ans = min(ans, abs(10'000 - k));

        }

    }



    cout << ans << endl;

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



int h, w;

int a[80][80];

bool dp[80][80][2 * 80 * 80 + 1];



int solve() {

  const int kmax = 2 * 80 * 80;

  for (int i = 0; i < h; ++i) {

    for (int j = 0; j < w; ++j) {

      int diff = a[i][j];

      if (i == 0 && j == 0) {

        dp[i][j][diff] = true;

      } else {

        for (int k = 0; k <= kmax; ++k) {

          for (int type : { 1, -1 }) {

            int pk = k + type * diff;

            if (pk < 0) pk = -pk;

            if (pk > kmax) continue;

            bool u = i == 0 ? false : dp[i - 1][j][pk];

            bool l = j == 0 ? false : dp[i][j - 1][pk];

            if (!u && !l) continue;

            dp[i][j][k] = true;

          }

        }

      }

    }

  }

  

  for (int k = 0; k <= kmax; ++k) {

    if (dp[h - 1][w - 1][k]) return k;

  }

  return 1e9;

}



void input() {

  cin >> h >> w;

  int tmp[80][80];

  for (int i = 0; i < h; ++i) {

    for (int j = 0; j < w; ++j) {

      cin >> tmp[i][j];

    }

  }

  for (int i = 0; i < h; ++i) {

    for (int j = 0; j < w; ++j) {

      int buf;

      cin >> buf;

      a[i][j] = abs(buf - tmp[i][j]);

    }

  }

}



int main() {

  input();

  cout << solve() << endl;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



using Bits = bitset<4 * 80 * 80 + 1>;

int h, w;

int a[80][80];

Bits dp[80][80];



int solve() {

  const int kmax = 2 * 80 * 80;

  for (int i = 0; i < h; ++i) {

    for (int j = 0; j < w; ++j) {

      int diff = a[i][j];

      if (i == 0 && j == 0) {

        dp[i][j][kmax + diff] = true;

        dp[i][j][kmax - diff] = true;

      } else {

        Bits sum;

        if (i > 0) {

          sum |= dp[i - 1][j] << diff;

          sum |= dp[i - 1][j] >> diff;

        }

        if (j > 0) {

          sum |= dp[i][j - 1] << diff;

          sum |= dp[i][j - 1] >> diff;

        }

        dp[i][j] = sum;

      }

    }

  }

  

  for (int k = 0; k <= kmax; ++k) {

    if (dp[h - 1][w - 1][kmax + k]) return k;

    if (dp[h - 1][w - 1][kmax - k]) return k;

  }

  return 1e9;

}



void input() {

  cin >> h >> w;

  int tmp[80][80];

  for (int i = 0; i < h; ++i) {

    for (int j = 0; j < w; ++j) {

      cin >> tmp[i][j];

    }

  }

  for (int i = 0; i < h; ++i) {

    for (int j = 0; j < w; ++j) {

      int buf;

      cin >> buf;

      a[i][j] = abs(buf - tmp[i][j]);

    }

  }

}



int main() {

  input();

  cout << solve() << endl;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<stdio.h>

#include<algorithm>

#include<iostream>

using namespace  std;

int fa[100010];

int n,m;

struct edge{

	int x,y,w;

	edge(int x=0,int y=0 ,int w=0 ):x(x),y(y),w(w){

	}

}a[100010];

int getfa(int x){

	if(x==fa[x]) return x;

	else return getfa(fa[x]);

}

bool cmp(edge a,edge b){

	return a.w<b.w;

}

int f(){

	int ans=0;

	sort(a,a+m,cmp);

	int cnt=n;

	for(int i=0;i<n;i++) fa[i]=i;

	for(int i=0;i<m;i++){

		int f1=getfa(a[i].x),

		f2=getfa(a[i].y);

		if(f1!=f2){

			ans+=a[i].w;

			cnt--;

			fa[f1]=f2;

			if(cnt==1) break;

		}

	}

	return ans;

}

int main(){

	scanf("%d%d",&n,&m);

	for(int i=0;i<m;i++){

		scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);

	}

	printf("%d\n",f());

	return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <stdio.h>

#include <vector>

#include <algorithm>

#define  MAXN 10010

using namespace std;

struct Edge

{

	int point1;

	int point2;

	int weight;

};

bool cmp(Edge &x, Edge &y)

{

	return x.weight < y.weight;

}

int pre[MAXN];

vector <Edge> vec;

int find(int x)

{//并查集

	int root = x;



	while (pre[root] != root)

		root = pre[root];//找根

	int t = x;

	while (pre[t] != root)

	{//路径压缩

		int temp = pre[t];

		pre[t] = root;

		t = temp;

	}



	return root;

}

int main()

{

	int n, m;

	int min_sum = 0;



	scanf("%d%d", &n, &m);//n是点数，m是边数

	for (int i = 0; i < n; i++)

		pre[i] = i;//初始化并查集

	for (int i = 0; i < m; i++)

	{//输入每条边的两个顶点及其权重

		Edge temp;



		scanf("%d%d%d", &temp.point1, &temp.point2, &temp.weight);

		vec.push_back(temp);

	}

	sort(vec.begin(), vec.end(), cmp);//按权重对边进行排序

	int coun = 0;

	for (int i = 0; i < m; i++)

	{//最多只有m条边

		int fx = find(vec[i].point1);

		int fy = find(vec[i].point2);



		if (fx != fy)

		{//如果这条边的两个顶点所在集合不相同就合并

			coun++;//成功合并后就多了一条边

			min_sum += vec[i].weight;

			pre[fx] = fy;//合并

			if (coun == n - 1)

				break;//krusal有n-1条边

		}

	}

	printf("%d\n", min_sum);

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <cstdio>

#include <iostream>

#include <algorithm>

#include <vector>

#include <queue>

using namespace std;

#define pb        emplace_back

#define fi        first

#define se        second

#define outl(x)   cout << (x) << '\n'

#define rep(i,n)     for(int i=0; i<(n); ++i)

typedef pair<int,int> pii;



int V, E;

vector<pii> G[100010];



int prim()

{

    vector<bool> used(V+1, false);

    priority_queue< pii, vector<pii>, greater<pii> > pq;

    int sum = 0;

    pq.emplace(pii(0,0));



    while ( !pq.empty() ) {

        const auto now = pq.top(); pq.pop();

        if (used[now.se]) continue;



        sum += now.fi;

        used[now.se] = true;

        for (const auto &e : G[now.se]) {

            pq.emplace(e);

        }

    }

    return sum;

}



signed main()

{

    cin.tie(0), ios::sync_with_stdio(false);



    cin >> V >> E;

    rep(i, E) {

        int s, t, w;

        cin >> s >> t >> w;

        G[s].pb(pii(w, t));

        G[t].pb(pii(w, s));

    }



    outl(prim());

}






// Optimized solution to the same problem (faster):
#include "bits/stdc++.h"

using namespace std;

using i64 = long long;

using pii = pair<i64, i64>;

template<class A, class B>inline bool chmax(A &a, const B &b){return b>a ? a=b,1 : 0;}

template<class A, class B>inline bool chmin(A &a, const B &b){return b<a ? a=b,1 : 0;}

constexpr int INF  = 0x3f3f3f3f;

constexpr i64 LINF = 0x3f3f3f3f3f3f3f3fLL;





struct Edge { // {{{

    int src, to;

    i64 cost;

    Edge(int src,  int to, i64 cost) : src(src), to(to), cost(cost) {}

    Edge(int to, i64 cost = 0) : Edge(-1, to, cost) {}

    Edge() {}

    bool operator< (const Edge &o) const { return cost < o.cost; }

    bool operator> (const Edge &o) const { return cost > o.cost; }

};

using Edges = vector<Edge>;

using WGraph = vector<vector<Edge>>;

using UGraph = vector<vector<int>>;

// }}}







struct UnionFind {

    vector<int> u;

    explicit UnionFind(int n): u(n+5, -1) {}

    int  size(int i)        { return (-u[root(i)]); }

    int  root(int x)        { return (u[x] < 0)? x : u[x] = root(u[x]); }

    bool same(int x, int y) { return root(x) == root(y); }

    bool unite(int x, int y){ return (x=root(x)) == (y=root(y))? false : (u[x]+=u[y], u[y]=x, true); }

};



i64 kruskal(Edges &es, int V)

{

    UnionFind uf(V);

    i64 costSum = 0;



    sort(es.begin(), es.end());

    for (const auto &e : es) {

        if (uf.unite(e.src, e.to)) costSum += e.cost;

    }



    return costSum;

}



void AOJ_GRL_2_A()

{

    int V, E;

    cin >> V >> E;



    Edges es(E);

    for (int i = 0; i < E; ++i) {

        int s, t, w;

        cin >> s >> t >> w;

        es[i] = Edge(s, t, w);

    }



    cout << kruskal(es, V) << endl;



}



signed main()

{

    ios::sync_with_stdio(false); cin.tie(nullptr);



    AOJ_GRL_2_A();



    return 0;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<vector>

#include<queue>

#include<algorithm>

using namespace std;



//Prim

struct edge{int to,cost;};



int main(){

  int V,E;

  vector<edge> G[10000];

  scanf("%d %d",&V,&E);

  for(int i=0;i<E;i++){

    int s,t,w;

    scanf("%d %d %d",&s,&t,&w);

    edge tmp;

    tmp.cost = w;

    tmp.to = t;

    G[s].push_back(tmp);

    tmp.to = s;

    G[t].push_back(tmp);

  }

  int ans = 0;

  bool used[V];

  fill(used,used+V,false);

  priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;

  q.push(make_pair(0,0));

  while(!q.empty()){

    pair<int,int> p = q.top();

    q.pop();

    int c = p.first;

    int v = p.second;

    if(used[v]) continue;

    used[v] = true;

    ans+=c;

    for(int i=0;i<G[v].size();i++){

      q.push(make_pair(G[v][i].cost,G[v][i].to));

    }

  }

  printf("%d\n",ans);

  return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<algorithm>

#include<vector>

#include<queue>

using namespace std;



typedef pair<int,int> pii;

const int INF =  1000000000;



int par[10000],rnk[10000];



void init(int n){

  for(int i=0;i<n;i++){

    par[i] = i;

    rnk[i] = 1;

  }

}

int find(int x){

  if(par[x]==x) return x;

  else return par[x] = find(par[x]);

}

bool same(int x,int y){

  return find(x)==find(y);

}

void unite(int x,int y){

  x = find(x);

  y = find(y);

  if(rnk[x]>rnk[y]) par[y] = x;

  else{

    par[x] = y;

    if(rnk[x]==rnk[y]) rnk[y]++;

  }

  return;

}



int main(){

  int V,E;

  vector<pair<int,pii> > es;

  scanf("%d %d",&V,&E);

  for(int i=0;i<E;i++){

    int s,t,w;

    scanf("%d %d %d",&s,&t,&w);

    es.push_back(make_pair(w,pii(s,t)));

  }

  int ans = 0;

  int cost[10000];

  fill(cost,cost+V,INF);

  sort(es.begin(),es.end());

  cost[0] = 0;

  init(V);

  for(int i=0;i<es.size();i++){

    if(!same(es[i].second.first,es[i].second.second)){

      ans += es[i].first;

      unite(es[i].second.first,es[i].second.second);

    }

  }

  printf("%d\n",ans);

  return 0;

}

// Fastest known solution for this problem: