using namespace std;
#define int long long 
#define inf 1000000005
#define Yes cout<<"Yes"<<"\n"
#define No cout<<"No"<<"\n"
#define Pair pair<int,int>
#define pqg(u) priority_queue<u,vector<u>,greater<u>>
//小根堆 
#define pq(u) priority_queue<u>
//大根堆 
#define st first
#define value second
//#define mol %= (int)1e9+7
/*bool cmp(int a,int b){
    return a>b;
}*/
void solve(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> dp(n+1,vector<int>(n+1,0));
    vector<vector<Pair>> edge(n+1);
    int sum=0;
    for(int i=0;i<m;i++){
        int x,y,w;
        cin>>x>>y>>w;
		edge[max(x,y)].emplace_back(min(x,y),w);
		sum+=w;
    }
    for(int len=2;len<=n;len++){
        for(int i=1;i<=n-len+1;i++){
        	dp[i][i+len-1]=max({dp[i][i+len-1],dp[i+1][i+len-1],dp[i][i+len-2]});
        	for(auto e:edge[i+len-1]){
        		if(e.st<i) continue;
        		int temp=e.value;
        		if(i<e.st-1){
                    temp+=dp[i][e.st-1];
                }
                if(e.st+1<i+len-2){
                    temp+=dp[e.st+1][i+len-2];
                }
        		dp[i][i+len-1]=max(dp[i][i+len-1],temp);
			}
            /*for(int k=i;k<i+len-1;k++){
                dp[i][i+len-1]=max(dp[i][i+len-1],dp[i][k]+dp[k+1][i+len-1]);
                if(edge[k][i+len-1]!=inf){
                    int temp=edge[k][i+len-1];
                    if(i<=k-1){
                        temp+=dp[i][k-1];
                    }
                    if(k+1<=i+len-2){
                        temp+=dp[k+1][i+len-2];
                    }
                        dp[i][i+len-1]=max(dp[i][i+len-1],temp);
                }
            }*/
        }
    }
 
    cout<<sum-dp[1][n]<<"\n";
}
int32_t main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t=1;
    //int t; cin>>t;
 
    while(t--){
        solve();
    } 
    return 0;
}

转化为覆盖1-n并且不相交的最大权值和,区间dp,连接不可以相交,可以不用当做环处理,区间dp不太熟,比赛时直接暴力的划分导致超时,但因为只需要考虑每个边的影响,因此不用遍历每一个分界点。