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.math.*;

public class D{
	
	static int n,m;
	static boolean e[][];
	static void MainMethod()throws Exception{
		n=reader.nextInt();e=new boolean[n+2][n+2];
		int u,v,i;
		m=reader.nextInt();
		for (i=0;i<e.length;i++) {
			Arrays.fill(e[i], false);
		}
		for (i=0;i<m;i++) {
			u=reader.nextInt();
			v=reader.nextInt();
			e[u][v]=true;	
		}
		if (process())
			printer.print("YES");
		else
			printer.print("NO");
	}
	static int pre[];
	static ArrayList<Integer>cyc=new ArrayList<Integer>();
	static boolean getc=true;
	static boolean ind[],outd[];
	static boolean checkdfs(int u) {
		ind[u]=true;
		for (int v=1;v<=n;v++) if (e[u][v]==true) {
			if ((ind[v]==true)&&(outd[v]==false)) {
				if (getc==true) {
					cyc.clear();
					cyc.add(v);
					int x=u;
					do {
						cyc.add(x);
						x=pre[x];
					}while(x!=v);
					cyc.add(v);
					getc=false;
				}
				return false;
			}
			if (ind[v]==false) {
				
				pre[v]=u;
				if (checkdfs(v)==false)
					return false;
			}
		}
		outd[u]=true;
		return true;
	}
	static boolean checkDAG(){
		Arrays.fill(ind, false);
		Arrays.fill(outd, false);
		for (int i=1;i<=n;i++)
			if (ind[i]==false) 
				if (checkdfs(i)==false)
					return false;
		return true;
	}
	static boolean process() {
		ind = new boolean[n+2];
		outd = new boolean[n+2];
		pre=new int[n+2];
		if (checkDAG()) return true;
		int i,u,v,k=cyc.size();
		 
		for (i=1;i<k;i++) {
			v=cyc.get(i-1);
			u=cyc.get(i);
			e[u][v]=false;
			if (checkDAG()==true) return true;
			e[u][v]=true;
		}
		return false;
	}

	public static void main(String[] args)throws Exception{
		MainMethod();
		printer.close();
	}
	static void halt(){
		printer.close();
		System.exit(0);
	}
	static PrintWriter printer=new PrintWriter(new OutputStreamWriter(System.out));
	static class reader{
		static BufferedReader bReader=new BufferedReader(new InputStreamReader(System.in));
		static StringTokenizer token=new StringTokenizer("");
		static String readNextLine() throws Exception{
			return bReader.readLine();
		}
		static String next() throws Exception{
			while (token.hasMoreTokens()==false){
				token=new StringTokenizer(bReader.readLine());
			}
			return token.nextToken();
		}
		static int nextInt()throws Exception{
			while (token.hasMoreTokens()==false){
				token=new StringTokenizer(bReader.readLine());
			}
			return Integer.parseInt(token.nextToken());
		}
		static long nextLong()throws Exception{
			while (token.hasMoreTokens()==false){
				token=new StringTokenizer(bReader.readLine());
			}
			return Long.parseLong(token.nextToken());
		}
		static double nextDouble()throws Exception{
			while (token.hasMoreTokens()==false){
				token=new StringTokenizer(bReader.readLine());
			}
			return Double.parseDouble(token.nextToken());
		}
	}
	static class MyMathCompute{
		static long [][] MatrixMultiplyMatrix(long [][] A, long [][] B, long mod) throws Exception{
			int n=A.length, m=B[0].length; 
			int p=A[0].length;
			int i,j,k;
			if (B.length!=p) throw new Exception("invalid matrix input");
			long [][] res=new long [n][m];
			for (i=0;i<n;i++) for (j=0;j<m;j++){
				if (A[i].length!=p) throw new Exception("invalid matrix input");
				res[i][j]=0;
				for (k=0;k<p;k++)
					res[i][j]=(res[i][j]+((A[i][k]*B[k][j])% mod))% mod;
			}
			return res;
		}
		static double [][] MatrixMultiplyMatrix(double [][] A, double [][] B ) throws Exception{
			int n=A.length, m=B[0].length; 
			int p=A[0].length;
			int i,j,k;
			if (B.length!=p) throw new Exception("invalid matrix input");
			double [][] res=new double [n][m];
			for (i=0;i<n;i++) for (j=0;j<m;j++){
				if (A[i].length!=p) throw new Exception("invalid matrix input");
				res[i][j]=0;
				for (k=0;k<p;k++)
					res[i][j]=res[i][j]+(A[i][k]*B[k][j]);
			}
			return res;
		}
		static long [][] MatrixPow(long [][] A,long n, long mod) throws Exception{
			if (n==1) return A;
			long [][] res=MatrixPow(A, n/2, mod);
			res=MatrixMultiplyMatrix(res, res, mod);
			if ((n % 2) == 1) res=MatrixMultiplyMatrix(A,res, mod);		
			return res;
		}
		static double [][] MatrixPow(double [][] A,long n) throws Exception{
			if (n==1) return A;
			double[][] res=MatrixPow(A, n/2);
			res=MatrixMultiplyMatrix(res, res);
			if ((n % 2) == 1) res=MatrixMultiplyMatrix(A,res);		
			return res;
		}
		static long pow(long a,long n,long mod){
			a= a % mod;
			if (n==0) return 1;
			long k=pow(a,n/2,mod);
			if ((n % 2)==0) return ((k*k)%mod);
			else return (((k*k) % mod)*a) % mod;
		}
		static double pow(double a,long n){
			if (n==0) return 1;
			double k=pow(a,n/2);
			if ((n % 2)==0) return (k*k);
			else return (((k*k) )*a) ;
		}
	}
}
