You are given a [directed graph](https://en.wikipedia.org/wiki/Directed_graph) consisting of n vertices and m edges (each edge is directed, so it can be traversed in only one direction). You are allowed to remove at most one edge from it.

Can you make this graph [acyclic](https://en.wikipedia.org/wiki/Directed_acyclic_graph) by removing at most one edge from it? A directed graph is called acyclic iff it doesn't contain any cycle (a non-empty path that starts and ends in the same vertex).

Input

The first line contains two integers n and m (2 ≤ n ≤ 500, 1 ≤ m ≤ min(n(n - 1), 100000)) — the number of vertices and the number of edges, respectively.

Then m lines follow. Each line contains two integers u and v denoting a directed edge going from vertex u to vertex v (1 ≤ u, v ≤ n, u ≠ v). Each ordered pair (u, v) is listed at most once (there is at most one directed edge from u to v).

Output

If it is possible to make this graph acyclic by removing at most one edge, print YES. Otherwise, print NO.

Examples

Input

3 4
1 2
2 3
3 2
3 1


Output

YES


Input

5 6
1 2
2 3
3 2
3 1
2 1
4 5


Output

NO

Note

In the first example you can remove edge <image>, and the graph becomes acyclic.

In the second example you have to remove at least two edges (for example, <image> and <image>) in order to make the graph acyclic.
import java.util.*;
import java.io.*;
import java.text.*;
public class Code{
    static final long MOD = (long)1e9+7;
    static final int MAX = (int)1e6+1;
    static FastReader in;
    
    static int N, v1, v2;
    static ArrayList<Integer>[] adj;
    static int[] parent, depth;
    static boolean[] visited, recStack;
    public static void main(String[] args){
        in = new FastReader();
        StringBuilder out = new StringBuilder("");
        int T = 1;
        while(T-->0){
            N = ni();
            int M = ni();
            adj = new ArrayList[N];
            for(int i = 0; i< N; i++)adj[i] = new ArrayList<>();
            for(int i = 0; i< M; i++)adj[ni()-1].add(ni()-1);
            
            visited = new boolean[N];
            recStack = new boolean[N];
            parent = new int[N];
            depth = new int[N];
            boolean cycle = false;
            for(int i = 0; i< N; i++){
                if(!visited[i]){
                    recStack = new boolean[N];
                    parent[i] = i;
                    depth[i] = 0;
                    if(dfs1(i)){
                        cycle = true;
                        break;
                    }
                }
            }   
            if(!cycle)out.append("YES");
            else{
                int[] exc = new int[N+10];
                int c = 0;
                exc[c++] = v1*N+v2;
                if(depth[v1] > depth[v2]){
                    int t = v1;
                    v1 = v2;
                    v2 = t;
                }
                while(depth[v2]>depth[v1]){
                    exc[c++] = parent[v2]*N+v2;
                    v2 = parent[v2];
                }
                while(v1!=v2){
                    exc[c++] = parent[v1]*N+v1;
                    exc[c++] = parent[v2]*N+v2;
                    v1 = parent[v1];
                    v2 = parent[v2];
                }
                boolean yes = false;
                for(int i = 0; i< c && !yes; i++){
                    v1 = exc[i]/N;
                    v2 = exc[i]%N;
                    visited = new boolean[N];
                    cycle = false;
                    for(int j = 0; j< N && !cycle; j++){
                        if(!visited[j]){
                            recStack = new boolean[N];
                            if(dfs2(j))cycle = true;
                        }
                    }
                    if(!cycle)yes = true;
                }
                if(yes)out.append("YES");
                else out.append("NO");
            }
        }
        System.out.print(out.toString());
    }
    
    static boolean dfs1(int u){
        if(!visited[u]){
            visited[u] = true;
            recStack[u] = true;
            for(int i:adj[u]){
                if(recStack[i]){
                    v1 = u;
                    v2 = i;
                    return true;
                }else if(!visited[i]){
                    depth[i] = depth[u]+1;
                    parent[i] = u;
                    if(dfs1(i))return true;
                }
            }
        }
        recStack[u] = false;
        return false;
    }
    
    static boolean dfs2(int u){
        if(!visited[u]){
            visited[u] = true;
            recStack[u] = true;
            for(int i:adj[u]){
                if(u==v1 && i == v2)continue;
                if(recStack[i])return true;
                else if(!visited[i] && dfs2(i))return true;
            }
        }
        recStack[u] = false;
        return false;
    }
    
    static int gcd(int a,int b){
        return (b==0)?a:gcd(b,a%b);
    }
    
    static String n(){
        return in.next();
    }
    
    static String nln(){
        return in.nextLine();
    }
    
    static int ni(){
        return Integer.parseInt(in.next());
    }
    
    static long nl(){
        return Long.parseLong(in.next());
    }
    
    static double nd(){
        return Double.parseDouble(in.next());
    }
    
    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }
        
        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

 
        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
 
        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
    
}       