#include<stdio.h>
#include<string.h>
#define N 105
int map[N][N],indegree[N];
int Topo(int n)
{
int i,j,ans;
for(i=0;i<n;i++)
{
ans=n;
for(j=0;j<n;j++)
{
if(indegree[j]==0)
{
indegree[j]--;
ans=j;
break;
}
}
if(ans==n)//ans没有更新说明没有入度为0的结点了即无法进行拓扑排序
{
return 0;
}
for(j=0;j<n;j++)
{
if(map[ans][j]>0)//与上面选出来入度为0结点相连的点的入度-1
{
indegree[j]--;
}
}
}
return 1;
}
int main()
{
int m,n,i,p,q,flag;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)
{
break;
}
memset(map,0,sizeof(map));
memset(indegree,0,sizeof(indegree));
for(i=0;i<m;i++)
{
scanf("%d%d",&p,&q);
if(map[p][q]==0)//在这儿必须判断,wa了好几次,
{
map[p][q]=1;
indegree[q]++;
}
}
flag=Topo(n);
if(flag)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}
//BFS
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;
int indegree[1002];
int mp[1002][1002];
int book[1002];
int n,m;
int s,t;
const int INF=99999999;
queue<int> q;
void topsort(){
int temp;
int cnt=0;
for(int i=1;i<=n;i++){
if(indegree[i]==0)
q.push(i);
}
while(!q.empty()){
temp=q.front();
cout<<temp;
q.pop();
book[temp]=cnt++;
for(int i=1;i<=n;i++){
if(mp[temp][i]==1)
if(--indegree[i]==0)
q.push(i);
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
mp[i][j]=INF;
for(int i=1;i<=m;i++){
cin>>s>>t;
if(mp[s][t]==INF)
mp[s][t]=1;
indegree[t]++;
}
topsort();
return 0;
}
//DFS
int topo[1002];
int c[1002];
int t;
bool dfs(int u){
c[u]=-1;
for(int v=0;v<n;v++){
if(G[u][v]){
if(c[v]<0)
return false;
else if(!c[v]&&!dfs(v))
return false;
}
}
c[u]=1;topo[--t]=u;
return true;
}
bool topsort(){
t=n;
memset(c,0,sizeof(c));
for(int u=0;u<n;u++)
if(!c[u])
if(!dfs(u))
return false;
return true;
}
//c[u]=0 从未被访问
//c[u]=1 已经访问过,并且还递归访问过他的所有子孙
//c[u]=-1 正在访问