1 #include <algorithm>
2 #include <cstring>
3 #include <cstdio>
4
5 #define LL long long
6 #define max(a,b) (a>b?a:b)
7 #define min(a,b) (a<b?a:b)
8 inline void read(int &x)
9 {
10 x=0; register char ch=getchar();
11 for(; ch>‘9‘||ch<‘0‘; ) ch=getchar();
12 for(; ch>=‘0‘&&ch<=‘9‘; ch=getchar()) x=x*10+ch-‘0‘;
13 }
14 const int N(100000+5);
15 const int M(200000+5);
16 int n,m,head[N],sumedge;
17 struct Edge {
18 int v,next,w;
19 Edge(int v=0,int next=0,int w=0):v(v),next(next),w(w){}
20 }edge[N<<1];
21 struct Road {
22 int u,v,w;
23 bool operator < (const Road x)const
24 {
25 return w<x.w;
26 }
27 Road(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
28 }road[M];
29 inline void ins(int u,int v,int w)
30 {
31 edge[++sumedge]=Edge(v,head[u],w);
32 head[u]=sumedge;
33 }
34
35 int fa[N];
36 int find(int x)
37 {
38 return x==fa[x]?x:fa[x]=find(fa[x]);
39 }
40 inline LL K_for_get_road()
41 {
42 int cnt=0;
43 LL ret=0;
44 std::sort(road+1,road+m+1);
45 for(int i=1; i<=n; ++i) fa[i]=i;
46 for(int fx,fy,i=1; i<=m; ++i)
47 {
48 fx=find(road[i].u),fy=find(road[i].v);
49 if(fx==fy) continue;
50 fa[fx]=fy; ret+=(LL)road[i].w;
51 ins(road[i].u,road[i].v,road[i].w);
52 ins(road[i].v,road[i].u,road[i].w);
53 if(++cnt==n-1) return ret;
54 }
55 return ret;
56 }
57
58 LL val[N],ans;
59 int s,t,pre[N];
60 void DFS(int u)
61 {
62 for(int x,v,i=head[u]; i; i=edge[i].next)
63 {
64 v=edge[i].v;
65 if(v==pre[u]) continue;
66 val[v]=val[u]+(LL)edge[i].w;
67 pre[v]=u; DFS(v);
68 }
69 }
70 void Get(int u)
71 {
72 if(pre[u]) Get(pre[u]);
73 ans=min(ans,max(val[u],val[t]-val[u]));
74 }
75
76 int Presist()
77 {
78 read(n),read(m);
79 for(int u,v,w,i=1; i<=m; ++i)
80 read(u),read(v),read(w),road[i]=Road(u,v,w);
81 printf("%lld\n",K_for_get_road());
82
83 DFS(s=1);
84 for(int i=1; i<=n; ++i) if(val[i]>val[s]) s=i;
85 memset(val,0,sizeof(val));
86 memset(pre,0,sizeof(pre));
87 DFS(s);t=1;
88 for(int i=1; i<=n; ++i) if(val[i]>val[t]) t=i;
89 ans=val[t]; Get(t);
90 printf("%lld\n",ans);
91 return 0;
92 }
93
94 int Aptal=Presist();
95 int main(){;}