1 #include<cstdio>
2 #include<cstdlib>
3 #include<cmath>
4 #include<cstring>
5 #include<algorithm>
6 #include<iostream>
7 #include<vector>
8 #include<map>
9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 150000+1000
14 #define eps 1e-10
15 #define ll long long
16 #define pa pair<int,int>
17 #define for0(i,n) for(int i=0;i<=n;i++)
18 #define for1(i,n) for(int i=1;i<=n;i++)
19 #define for2(i,x,y) for(int i=x;i<=y;i++)
20 using namespace std;
21 inline int read()
22 {
23 int x=0,f=1;char ch=getchar();
24 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
25 while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}
26 return x*f;
27 }
28 struct rec{int x,y,a,b;}e[maxn];
29 int n,m,ans,fa[maxn],c[maxn][2],sta[maxn],f[maxn],next[maxn],mx[maxn],v[maxn];
30 bool rev[maxn];
31 inline bool isroot(int x)
32 {
33 return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
34 }
35 inline void pushup(int x)
36 {
37 mx[x]=x;
38 if(v[mx[c[x][0]]]>v[mx[x]])mx[x]=mx[c[x][0]];
39 if(v[mx[c[x][1]]]>v[mx[x]])mx[x]=mx[c[x][1]];
40 }
41 inline void rotate(int x)
42 {
43 int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;
44 if(!isroot(y))c[z][c[z][1]==y]=x;
45 fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
46 c[y][l]=c[x][r];c[x][r]=y;
47 pushup(y);pushup(x);
48 }
49 inline void pushdown(int x)
50 {
51 if(!rev[x])return;
52 rev[x]^=1;rev[c[x][0]]^=1;rev[c[x][1]]^=1;
53 swap(c[x][0],c[x][1]);
54 }
55 inline void splay(int x)
56 {
57 int top=0;sta[++top]=x;
58 for(int y=x;!isroot(y);y=fa[y])sta[++top]=fa[y];
59 for(;top;)pushdown(sta[top--]);
60 while(!isroot(x))
61 {
62 int y=fa[x],z=fa[y];
63 if(!isroot(y))
64 {
65 if(c[z][0]==y^c[y][0]==x)rotate(x);else rotate(y);
66 }
67 rotate(x);
68 }
69 }
70 inline void access(int x)
71 {
72 for(int y=0;x;x=fa[x])
73 {
74 splay(x);c[x][1]=y;pushup(x);y=x;
75 }
76 }
77 inline void makeroot(int x)
78 {
79 access(x);splay(x);rev[x]^=1;
80 }
81 inline int ask(int x,int y)
82 {
83 makeroot(x);access(y);splay(y);return mx[y];
84 }
85 inline void link(int x,int y)
86 {
87 makeroot(x);fa[x]=y;splay(x);
88 }
89 inline void cut(int x,int y)
90 {
91 makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;
92 }
93 inline bool cmp(rec x,rec y)
94 {
95 return x.a<y.a;
96 }
97 inline int find(int x)
98 {
99 return f[x]==x?x:f[x]=find(f[x]);
100 }
101 int main()
102 {
103 freopen("input.txt","r",stdin);
104 freopen("output.txt","w",stdout);
105 n=read();m=read();
106 for1(i,m)e[i].x=read(),e[i].y=read(),e[i].a=read(),e[i].b=read();
107 sort(e+1,e+m+1,cmp);
108 for1(i,m)v[n+i]=e[i].b,mx[i]=n+i;
109 for1(i,n)f[i]=i;
110 int x,y,z,xx,yy,ans=inf;
111 for1(i,m)
112 {
113 x=e[i].x,y=e[i].y;
114 xx=find(x);yy=find(y);
115 if(xx!=yy)
116 {
117 f[xx]=yy;
118 link(x,n+i);link(y,n+i);
119 }
120 else
121 {
122 z=ask(x,y);
123 if(e[i].b<v[z])
124 {
125 cut(e[z-n].x,z);cut(e[z-n].y,z);
126 link(x,n+i);link(y,n+i);
127 }
128 }
129 if(find(1)==find(n))ans=min(ans,v[ask(1,n)]+e[i].a);
130 }
131 printf("%d\n",ans==inf?-1:ans);
132 return 0;
133 }