#include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include <queue> #include <stack> using namespace std; const int INF=0xfffffff; int Map[33][33]; int degree[33]; int dp[1<<16]; int n,m; int sum; int Min(int a,int b) { return a>b?b:a; } void floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ if(i!=j||j!=k||k!=i){ Map[i][j]=Min(Map[i][j],Map[i][k]+Map[k][j]);//由于图是连同的。预处理之后 两两点之间都有边直接相连 } } } int dfs(int x) { //cout<<x<<endl; // system("pause"); if(x==0) return 0; if(dp[x]) return dp[x]; int ans=INF; for(int i=0;i<n-1;i++) if(x&(1<<i)){ for(int j=i+1;j<n;j++) if(x&(1<<j)){ int cc=dfs(x-(1<<i)-(1<<j))+Map[i+1][j+1];//度数为奇数的点互相连 最小值 // cout<<Map[i+1][j+1]<<endl;system("pause"); ans=Min(ans,cc); } } return dp[x]=ans; } int main() { while(~scanf("%d%d",&n,&m),n){ sum=0; memset(degree,0,sizeof(degree)); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) Map[i][j]=INF; for(int i=0;i<m;i++){ int a;int b;int c; scanf("%d%d%d",&a,&b,&c); sum+=c; degree[a]++;degree[b]++; if(c<Map[a][b]) Map[a][b]=Map[b][a]=c; } int x=0; floyd(); for(int i=1;i<=n;i++) if(degree[i]&1) x|=(1<<(i-1)); sum+=dfs(x); cout<<sum<<endl; } return 0; }