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

#include<iostream>
#include<vector>
#include <chrono>
#include<map>
#include<cstring>
#include<queue>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;

#define     MX        200005
#define     mod       998244353
#define     ll        long long
#define     inf       1000000000
#define     ull       unsigned long long
#define     ld        long double
#define     mem(a,b)  memset(a,b,sizeof(a))
#define     fast()    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define     F         first
#define     S         second
#define     mp        make_pair
#define     PI        acos(-1)
#define     Base      402653189
int   dx[]      ={+1,-1,0,0};
int   dy[]      ={0,0,+1,-1};

int n,m;
vector<int>vt[MX];
pair<int,pair<int,int>>pr[MX];


int par[MX];
int siz[MX];

int findRoot(int node){
    while(node!=par[node]){
        par[node] = par[par[node]];
        node=par[node];
    }
    return node;
}

bool DSU(int u,int v){
    int root1 = findRoot(u);
    int root2 = findRoot(v);

    if(root1==root2) return false;

    if(siz[root1]>siz[root2]){
        siz[root1]+=siz[root2];
        par[root2]=root1;
    }
    else {
        siz[root2]+=siz[root1];
        par[root1]=root2;
    }
    return true;
}

set<int>st;
bool vis[MX];
vector<int>grp;
bool checked[MX];
bool zeros[MX];

int conCnt[MX];
int grpNum[MX];
int grpConCnt[MX];

void dfs(int node){
    if(checked[node]) return;
    checked[node]=true;

    if(st.count(node)) st.erase(node);
    grp.push_back(node);

    for(int i=0;i<vt[node].size();i++) vis[vt[node][i]]=true;
    vector<int>bad;
    for(auto it=st.begin();it!=st.end();it++) if(!vis[*it]) bad.push_back(*it);
    for(int i=0;i<bad.size();i++) {
        DSU(node,bad[i]);
        st.erase(bad[i]);
    }
    for(int i=0;i<vt[node].size();i++) vis[vt[node][i]]=false;

    for(int i=0;i<bad.size();i++) dfs(bad[i]);
}





int main(){
    fast();
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);

    ll xorSum=0;
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x,y,z;
        cin>>x>>y>>z;
        vt[x].push_back(y);
        vt[y].push_back(x);
        pr[i].F = z;
        pr[i].S.F =x;
        pr[i].S.S = y;
        xorSum^=z;
    }
    sort(pr+1,pr+m+1);
    for(int i=1;i<=n;i++) st.insert(i),par[i]=i,siz[i]=1;

    bool extra=false;
    for(int i=1;i<=n;i++){
        if(checked[i]) continue;
        dfs(i);
        //cout<<"grp "<<i<<endl;;
        if(grp.size()>1){
            ll rem=0;
            for(int j=0;j<grp.size();j++) {
                grpNum[grp[j]]=i;
                //cout<<grp[j]<<" ";
                rem+=(n-1-vt[grp[j]].size());
                zeros[grp[j]]=true;
            }
            if(rem>2*(grp.size()-1)) extra =true;
            //cout<<endl<<rem;
        }
        //cout<<endl;
        grp.clear();
    }
    //cout<<"extraa "<<extra<<endl;
    //cout<<xorSum<<endl;

    ll ans=0,add=INT_MAX;
    for(int i=1;i<=m;i++){
        if(DSU(pr[i].S.F,pr[i].S.S)) {
            ans+=pr[i].F;
            conCnt[pr[i].S.F]++;
            conCnt[pr[i].S.S]++;
            if(zeros[pr[i].S.F]) grpConCnt[grpNum[pr[i].S.F]]++;
            if(zeros[pr[i].S.S]) grpConCnt[grpNum[pr[i].S.S]]++;
        }
        else if (zeros[pr[i].S.F] && (conCnt[pr[i].S.F]==0 ||  conCnt[pr[i].S.F] != grpConCnt[grpNum[pr[i].S.F]])) add = min(add, 1LL*pr[i].F);
        else if (zeros[pr[i].S.S] && (conCnt[pr[i].S.S]==0 ||  conCnt[pr[i].S.S] != grpConCnt[grpNum[pr[i].S.S]])) add = min(add, 1LL*pr[i].F);
    }
    if(!extra) ans=min(ans+xorSum, ans+add);

    cout<<ans<<endl;















    return 0;
}
