1 /**************************************************************
2 Problem: 3669
3 User: weeping
4 Language: C++
5 Result: Accepted
6 Time:6500 ms
7 Memory:48200 kb
8 ****************************************************************/
9
10 #include <bits/stdc++.h>
11
12 using namespace std;
13
14 struct node
15 {
16 int u,v,a,b;
17 node(){}
18 node(int x,int y,int z,int w){u=x,v=y,a=z,b=w;}
19 bool operator < (const node &ta) const
20 {
21 return a < ta.a || ( a == ta.a && b < ta.b);
22 }
23 }eg[1000005];
24
25 struct Link_Cut_Tree
26 {
27 static const int MAXN = 1000000 + 7;
28
29 int ch[MAXN][2], fa[MAXN], rev[MAXN], v[MAXN], mx[MAXN], id[MAXN];
30 int sk[MAXN];
31
32 bool isroot(int x)
33 {
34 return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
35 }
36
37 void reverse(int x)
38 {
39 rev[x] ^= 1, swap(ch[x][0],ch[x][1]);
40 }
41
42 void update(int x)
43 {
44 int lc = ch[x][0],rc = ch[x][1];
45 mx[x] = v[x], id[x] = x;
46 if(lc && mx[lc] > mx[x])
47 mx[x] = mx[lc], id[x] = id[lc];
48 if(rc && mx[rc] > mx[x])
49 mx[x] = mx[rc], id[x] = id[rc];
50 }
51
52 void push_down(int x)
53 {
54 if(!rev[x]) return ;
55 if(ch[x][0]) reverse(ch[x][0]);
56 if(ch[x][1]) reverse(ch[x][1]);
57 rev[x]=0;
58 }
59
60 void rotate(int x)
61 {
62 int f = fa[x], gf = fa[f];
63 int t1 = ( x != ch[f][0]), t2 = ( f != ch[gf][0]), tmp = ch[x][1^t1];
64 if(!isroot(f)) ch[gf][0^t2] = x;
65 fa[tmp] = f, fa[x] = gf, ch[x][1^t1] = f, fa[f] = x, ch[f][0^t1] = tmp;
66 update(f);
67 }
68
69 void splay(int x)
70 {
71 int top = 0;
72 sk[++top] = x;
73 for(int i = x; !isroot(i); i = fa[i]) sk[++top] = fa[i];
74 while(top) push_down(sk[top--]);
75 for(int f = fa[x], gf = fa[f]; !isroot(x); rotate(x), f = fa[x],gf = fa[f])
76 if(!isroot(f))
77 rotate((x==ch[f][0]) ^ (f==ch[gf][0]) ? x : f);
78 update(x);
79 }
80
81 void access(int x)
82 {
83 for(int p = 0; x; p = x, x = fa[x])
84 splay(x), ch[x][1] = p, update(x);
85 }
86
87 void makeroot(int x)
88 {
89 access(x), splay(x), reverse(x);
90 }
91
92 int findroot(int x)
93 {
94 access(x), splay(x);
95 while(ch[x][0]) x = ch[x][0];
96 return x;
97 }
98 void link(int x,int y)
99 {
100 makeroot(x), fa[x] = y;
101 }
102
103 void cut(int x,int y)
104 {
105 makeroot(x), access(y), splay(y);
106 if(ch[y][0] == x) ch[y][0] = fa[x] = 0;
107 update(y);
108 }
109
110 void go(int n,int m)
111 {
112 int ans=1e9;
113 sort(eg+1,eg+1+m);
114 for(int i=1;i<=m;i++)
115 {
116 int tu=eg[i].u,tv=eg[i].v,bi=eg[i].b,p=i+n;
117 v[p]=mx[p]=bi,id[p]=p;
118 if(tu==tv) continue;
119 if(findroot(tu)!=findroot(tv))
120 link(tu,p),link(p,tv);
121 else
122 {
123 makeroot(tu),access(tv),splay(tv);
124 if(mx[tv] > bi)
125 {
126 int q=id[tv]-n;
127 cut(eg[q].u,q+n),cut(eg[q].v,q+n);
128 link(tu,p),link(p,tv);
129 }
130 }
131 if(findroot(1)==findroot(n))
132 {
133 makeroot(1),access(n),splay(n);
134 ans=min(ans,eg[i].a+mx[n]);
135 }
136 }
137 if(ans==(int)1e9)
138 printf("-1\n");
139 else
140 printf("%d\n",ans);
141 }
142 }lct;
143
144 int main(void)
145 {
146 //freopen("in.acm","r",stdin);
147 int n,m;
148 scanf("%d%d",&n,&m);
149 for(int i=1;i<=n;i++) lct.v[i]=-1;
150 for(int i=1,x,y,a,b;i<=m;i++)
151 scanf("%d%d%d%d",&x,&y,&a,&b),eg[i] = node(x,y,a,b);
152 lct.go(n,m);
153 return 0;
154 }