Dima and Inna love spending time together. The problem is, Seryozha isn't too enthusiastic to leave his room for some reason. But Dima and Inna love each other so much that they decided to get criminal...

Dima constructed a trap graph. He shouted: "Hey Seryozha, have a look at my cool graph!" to get his roommate interested and kicked him into the first node.

A trap graph is an undirected graph consisting of n nodes and m edges. For edge number k, Dima denoted a range of integers from lk to rk (lk ≤ rk). In order to get out of the trap graph, Seryozha initially (before starting his movements) should pick some integer (let's call it x), then Seryozha must go some way from the starting node with number 1 to the final node with number n. At that, Seryozha can go along edge k only if lk ≤ x ≤ rk.

Seryozha is a mathematician. He defined the loyalty of some path from the 1-st node to the n-th one as the number of integers x, such that if he initially chooses one of them, he passes the whole path. Help Seryozha find the path of maximum loyalty and return to his room as quickly as possible!

Input

The first line of the input contains two integers n and m (2 ≤ n ≤ 103, 0 ≤ m ≤ 3·103). Then follow m lines describing the edges. Each line contains four integers ak, bk, lk and rk (1 ≤ ak, bk ≤ n, 1 ≤ lk ≤ rk ≤ 106). The numbers mean that in the trap graph the k-th edge connects nodes ak and bk, this edge corresponds to the range of integers from lk to rk.

Note that the given graph can have loops and multiple edges.

Output

In a single line of the output print an integer — the maximum loyalty among all paths from the first node to the n-th one. If such paths do not exist or the maximum loyalty equals 0, print in a single line "Nice work, Dima!" without the quotes.

Examples

Input

4 4
1 2 1 10
2 4 3 5
1 3 1 5
2 4 2 7


Output

6


Input

5 6
1 2 1 10
2 5 11 20
1 4 2 5
1 3 10 11
3 4 12 10000
4 5 6 6


Output

Nice work, Dima!

Note

Explanation of the first example.

Overall, we have 2 ways to get from node 1 to node 4: first you must go along the edge 1-2 with range [1-10], then along one of the two edges 2-4. 

One of them contains range [3-5], that is, we can pass through with numbers 3, 4, 5. So the loyalty of such path is 3.

If we go along edge 2-4 with range [2-7], then we can pass through with numbers 2, 3, 4, 5, 6, 7. The loyalty is 6. That is the answer.

The edge 1-2 have no influence on the answer because its range includes both ranges of the following edges.
import java.util.*;
import java.io.*;
public class D {
    public static long time = 0;

    public static void main(String[] args) throws Exception {
        time = System.currentTimeMillis();
        solve();
        out.flush();
    }
    static IntL[] al = null;
    static IntL[] ehigh = null;
    static IntL[] elow = null;
    public static void solve() throws Exception {
            int n1 = ni();
            int m1 = ni();
            al = new IntL[n1];
            ehigh = new IntL[n1];
            elow = new IntL[n1];
            for (int i =0 ; i< n1; i++){
                al[i] = new IntL();
                ehigh[i] = new IntL();
                elow[i] = new IntL();
            }
            int[] lows = new int[m1];
            int[] highs = new int[m1];
            for (int i = 0 ; i < m1; i++){
                int from = ni() - 1;
                int to = ni() -1;
                int lo = ni();
                int hi = ni();
                
                al[from].add(to);
                ehigh[from].add(hi);
                elow[from].add(lo);
                al[to].add(from);
                ehigh[to].add(hi);
                elow[to].add(lo);
                lows[i] = lo;
                highs[i] = hi;
            }
            IntL lowval = Arrayz.sortedUnique(lows);
            IntL highval = Arrayz.sortedUnique(highs);
            int best = 0;
            for (int i =0; i < lowval.size; i++){
                int low = lowval.get(i);
                
                if (!ok(low,low)) continue;
                
                int lo = low;
                int hi = highval.cont[highval.size - 1];
                for (;hi - lo > 1;){
//                  px(lo,hi);
                    int mid = (lo + hi) >> 1;
                    if (ok(low,mid)){
                        lo = mid;
                    }
                    else {
                        hi = mid;
                    }
                }
//              px(lo,hi,ok(low,hi));
                if (ok(low,hi)){
                    best = Math.max(best, hi - low + 1);
                } 
                else {
                    best = Math.max(best, lo - low + 1);
                }
            }
            for (int i =0; i < highval.size; i++){
                int high = highval.get(i);
                
                if (!ok(high ,high )) continue;
                
                int lo = 1;
                int hi = high;
                for (;hi - lo > 1;){
//                  px(lo,hi);
                    int mid = (lo + hi) >> 1;
                    if (ok(lo,high)){
                        hi = mid;
                    }
                    else {
                        lo = mid;
                    }
                }
//              px(lo,hi,ok(low,hi));
                if (ok(lo,high)){
                    best = Math.max(best, high - lo + 1);
                } 
                else {
                    best = Math.max(best, high - hi+ 1);
                }
            }
            if (best == 0){
                out.println("Nice work, Dima!");
            }
            else {
                out.println(best);
            }
    }
    static IntL l1 = new IntL();
    static IntL l2 = new IntL();
    public static boolean ok(int low, int high){
        boolean[] ex = new boolean[al.length];
        ex[0] = true;
        l1.size = 0;
        l2.size = 0;
        l1.add(0);
        for (;;){
            if (l1.size == 0) break;
            for (int e: l1){
                for (int i = 0 ; i < al[e].size; i++){
                    if (ex[al[e].get(i)]) continue;
                    if (low >= elow[e].get(i)
                            &&high <= ehigh[e].get(i)
                            ){
                        ex[al[e].get(i)] = true;
                        l2.add(al[e].get(i));
                    }
                }
            }
            IntL temp = l1;
            l1 = l2;
            l2 = temp;
            l2.size = 0;
        }
        
        return ex[ex.length - 1];
    }

    public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    public static StringTokenizer st = null;

    public static String nx() throws Exception {
        for (; st == null || !st.hasMoreTokens();) {
            String k1 = in.readLine();
            if (k1 == null) return null;
            st = new StringTokenizer(k1);
        }
        return st.nextToken();
    }

    public static int ni() throws Exception {
        return Integer.parseInt(nx());
    }

    public static long nl() throws Exception {
        return Long.parseLong(nx());
    }

    public static double nd() throws Exception {
        return Double.parseDouble(nx());
    }

    public static void px(Object... l1) {
        System.out.println(Arrays.deepToString(l1));
    }

    public static boolean FLUSH = false;
    public static PrintWriter out = new PrintWriter(System.out, FLUSH);

    public static void p(Object... l1) {
        for (int i = 0; i < l1.length; i++) {
            if (i != 0) out.print(' ');
            out.print(l1[i].toString());
        }
    }

    public static void pn(Object... l1) {
        for (int i = 0; i < l1.length; i++) {
            if (i != 0) out.print(' ');
            out.print(l1[i].toString());
        }
        out.println();
    }

    public static void pn(Collection l1) {
        boolean first = true;
        for (Object e : l1) {
            if (first) first = false;
            else out.print(' ');
            out.print(e.toString());
        }
        out.println();
    }

    private static class IntL implements Iterable<Integer> {
        public int[] cont = null;
        public int size = 0;

        public IntL(int initialCapacity) {
            this.cont = new int[initialCapacity];
        }

        public IntL() {
            this(5);
        }

        public void add(int e) {
            if (size == cont.length) {
                cont = Arrays.copyOf(cont, ((cont.length * 3) >> 1) + 1);
            }
            cont[size++] = e;
        }

        public int get(int id) {
            if (id >= 0) return cont[id];
            else return cont[size + id];
        }

        @Override
        public String toString() {
            StringBuilder fin = new StringBuilder();
            fin.append('{');
            for (int i = 0; i < size; i++) {
                if (i != 0) fin.append(", ");
                fin.append(cont[i]);
            }
            fin.append('}');
            return fin.toString();
        }

        @Override
        public Iterator<Integer> iterator() {
            return new It();
        }

        public class It implements Iterator<Integer> {
            int ptr = 0;

            @Override
            public boolean hasNext() {
                if (ptr < size) return true;
                return false;
            }

            @Override
            public Integer next() {
                int fin = cont[ptr];
                ptr++;
                return fin;
            }

            @Override
            public void remove() {}
        }
    }

    private static class Arrayz {
        public static IntL sortedUnique(int[] l1) {
            int[] copy = l1.clone();
            Arrays.sort(copy);
            IntL fin = new IntL();
            for (int i = 0; i < copy.length; i++) {
                if (i == 0) {
                    fin.add(copy[i]);
                    continue;
                }
                if (copy[i] != copy[i - 1]) {
                    fin.add(copy[i]);
                }
            }
            return fin;
        }
    }

}
