/*
分析:
不难,也不算果水,不过还是贴一下吧,不枉我晚上两点了在水题。。
并查集判环 + tree dp。
先用并查集判断每个集合是否有环,有环YES无环继续;
继续:无环,所以每个集合都是一个tree么,那么是tree就好办多了。、、
dfs,则
dis_max=max(dis_max,max(deep,dis[son_tree1]+dis[son_tree2]))。
大概00:30看到的这题,一开始用的tarjan判环(因为处理连通什么的,
额总喜欢用这个,所以虽然看到数据量觉得极有可能过不了而且同时也想到并查
集过的可能性坑定大很多,不过也还是用Tarjan写了下,不着哪儿写错了还真没
过囧~);
看表1点半了,有点儿想睡了,不过还是撑着换了个方法,用并查集来搞,
这次1Y了,而且代码还短好多= =I,看到Accepted的时候着实又突然精神了、不
困了,此时已经2点出头了。
其实也没什么,就是又忽然想起大一搞acm的时候了,那时候也会熬熬夜啊
什么的,而且每学期总会有几个月、实验室几乎除了我就没有人了,总会一个人
听着音乐敲着题,很享受那份静谧,这差不过是在这个大学校园里面、到目前为
止、我最最享受的了。。
而现在,院里也越来越重视acm了,实验室的人越来越多了,某种程度上这是
好事儿,不过当自己很享受的那份静谧很难再找到的时候,真的会很失落。。而
现在,突然深夜在宿舍敲代码的时候又有了一点儿那种感觉,所有就有点儿感触
了吧(只是敲代码什么的会很小心,怕吵到室友,所以没有那种轻松舒适感吧囧
。。)。
而且,有开始、就会有结束么,从一开始我就想好了,虽然会有一点儿遗憾,
不过自己也早已想好了、这又算什么呢,况且总归是要面对现实的。。。
不多说了,这些本来是退役的时候要说的。。
就这样吧,祝自己几个月后能达成自己的目标,依然是弱菜、也依然为自己
加油,加油~、running~!maybe,this is the last time.
2013-06-27
*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include"iostream"
#include"cstdio"
#include"stack"
#include"cstring"
using namespace std;
const int N=100005;
const int M=2000005;
int n,m,dis_max;
int flag[N],pre[N];
struct Edge{
int v,len,next;
}edge[M];
int tot,head[N];
int dfs(int k,int deep,int len)
{
flag[k]=1;
if(dis_max<deep)dis_max=deep;
if(head[k]==-1) return 0;
int j,v,temp,maxr=0;
int dis[2],cnt=0;
for(j=head[k];j!=-1;j=edge[j].next)
{
v=edge[j].v;
if(flag[v]) continue;
temp=dfs(v,deep+edge[j].len,edge[j].len);
if(maxr<temp) maxr=temp;
if(cnt<2) dis[cnt++]=temp;
else
{
int f;
if(dis[0]<dis[1]) f=0;
else f=1;
if(dis[f]<temp) dis[f]=temp;
}
}
if(cnt>=2 && dis_max<dis[0]+dis[1]) dis_max=dis[0]+dis[1];
return maxr+len;
}
int main()
{
int i;
int a,b,c,f1,f2,t1,t2,tt,cir;
while(scanf("%d%d",&n,&m)!=-1)
{
cir=tot=0;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++) pre[i]=i;
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
edge[tot].v=b;edge[tot].len=c;edge[tot].next=head[a];head[a]=tot++;
edge[tot].v=a;edge[tot].len=c;edge[tot].next=head[b];head[b]=tot++;
f1=a;
f2=b;
while(pre[f1]!=f1) f1=pre[f1];
while(pre[f2]!=f2) f2=pre[f2];
t1=a;
t2=b;
while(pre[t1]!=t1) {tt=pre[t1];pre[t1]=f1;t1=tt;}
while(pre[t2]!=t2) {tt=pre[t2];pre[t2]=f2;t2=tt;}
if(f1==f2) cir=1;
pre[f1]=f2;
}
if(cir) {printf("YES\n");continue;}
dis_max=0;
memset(flag,0,sizeof(flag));
for(i=1;i<=n;i++) if(!flag[i]) dfs(i,0,0);
cout<<dis_max<<endl;
}
return 0;
}