2 0
 6 8
1 4 1
1 5 1
1 6 1
2 4 1
2 5 1
2 6 1
3 5 1
3 6 1
 6 12
1 3 8763000
1 4 8763000
1 5 8763000
1 6 8763000
2 3 8763000
2 4 1
2 5 8763000
2 6 1
3 5 8763000
3 6 8763000
4 5 8763000
4 6 2

0
 0
 8763002

// 2021.04.23 - 20:06
// Code by LTb
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define fi first
#define se second
#define debug puts("QwQ");
inline int read() {
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void chmax(int &x,int y){x=max(x,y);}
inline void chmin(int &x,int y){x=min(x,y);}
inline void pls(int &x,int y,int Mod){x=(x+y>=Mod)?(x+y-Mod):(x+y);}
inline void red(int &x,int y,int Mod){x=(x-y<0)?(x-y+Mod):(x-y);}

const int MAXN = 200005;
int n, m;
struct Edge {
	int to, w;
};
vector<Edge> G[MAXN];

int sum;

int fa[MAXN], rk[MAXN];
inline int find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}

inline void merge(int x, int y) {
	int rx = find(x), ry = find(y);
	if (rk[rx] < rk[ry]) {
		fa[rx] = ry;
	} else {
		fa[ry] = rx;
		if (rk[rx] == rk[ry]) rk[rx]++;
	}
}

void dsu_init() {
	for (int i = 1; i <= n; i++) {
		rk[i] = 1;
		fa[i] = i;
	}
}

struct Edge2 {
	int x, y, w;
	bool operator < (const Edge2& b) const {
		return w < b.w;
	}
}es[MAXN * 2];

// -------- Solution 1 Begin -------- //

namespace sol1 {
struct Link {
	int nex, pre;
}lk[MAXN];

inline void del(int x) {
	lk[lk[x].pre].nex = lk[x].nex;
	lk[lk[x].nex].pre = lk[x].pre;
}

bool vis[MAXN];
void bfs() {
	queue<int> q;
	while (lk[0].nex) {
		q.push(lk[0].nex);
		del(lk[0].nex);

		while (!q.empty()) {
			int now = q.front();
			q.pop();

			for (auto i : G[now])
				vis[i.to] = true;

			int cur = lk[0].nex;
			while (cur) {
				if (!vis[cur]) {
					del(cur);
					merge(cur, now);
					q.push(cur);
				}
				cur = lk[cur].nex;
			}

			for (auto i : G[now])
				vis[i.to] = false;
		}
	}
}

int solve() {
	for (int i = 1; i <= n; i++) {
		lk[i].pre = i - 1;
		lk[i - 1].nex = i;
	}

	dsu_init();
	bfs();

	sort(es + 1, es + 1 + m);

	int ans = 0;
	for (int ii = 1; ii <= m; ii++) {
		auto i = es[ii];
		if (find(i.x) == find(i.y)) continue;
		ans += i.w;
		merge(i.x, i.y);
	}

	return ans;
}
}

// -------- Solution 1 End -------- //

// -------- Solution 2 Begin -------- //

namespace sol2 {

bool vis[MAXN];
vector<Edge2> a, b;
int siz = 0;

int solve2() {
	dsu_init();

	b = a;
	sort(b.begin(), b.end());

	int ans = 0;
	for (auto i : b) {
		if (find(i.x) == find(i.y)) continue;
		ans += i.w;
		merge(i.x, i.y);
	}

	return ans;
}

int solve() {
	int cnt = 0;
	for (int i = 1; i <= n; i++) {
		for (auto j : G[i])
			vis[j.to] = true;

		for (int j = i + 1; j <= n; j++) {
			if (!vis[j]) {
				a.push_back({i, j, 0});
				cnt++;
			}
		}

		for (auto j : G[i])
			vis[j.to] = false;
	}

	dsu_init();
	sort(es + 1, es + 1 + m);

	for (int ii = 1; ii <= m; ii++) {
		auto i = es[ii];
		if (find(i.x) == find(i.y)) continue;
		a.push_back(i);
		merge(i.x, i.y);
	}

	int ans = 1e18;
	for (int i = 0; i < cnt; i++) {
		a[i].w = sum;
		chmin(ans, solve2());
		a[i].w = 0;
	}

	return ans;
}
}

// -------- Solution 2 End -------- //


signed main()

{
	n = read(), m = read();
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read(), w = read();
		G[x].push_back({y, w});
		G[y].push_back({x, w});
		es[i] = {x, y, w};
		sum ^= w;
	}

	int tmpk = n * (n - 1) / 2;

	if (tmpk - m >= n)
		cout << sol1::solve() << endl;
	else
		cout << sol2::solve() << endl;
	return 0;
}