#include<iostream>//并查集
using namespace std;
#define max 10010
int n,father1[max],father2[max];
int find1(int x)
{
if(father1[x]!=x)
return father1[x]=find1(father1[x]);
else
return x;
}
int find2(int x)
{
if(father2[x]!=x)
return father2[x]=find2(father2[x]);
else
return x;
}
void unite(int a,int b)
{
int i,j;
if(a!=n)
{
i=find1(a);
j=find1(b);
if(i!=j)
father1[a]=b;
}
if(b!=n)
{
i=find2(a);
j=find2(b);
if(i!=j)
father2[b]=a;
}
}
int main()
{
int i,j,m,a,b;
bool ok;
while(cin>>n>>m && m+n)
{
ok=true;
for(i=1;i<=n;i++)
{
father1[i]=father2[i]=i;
}
for(i=1;i<=m;i++)
{
cin>>a>>b;
unite(a,b);
}
for(i=1;i<=n;i++)
if(find1(i)!=n || find2(i)!=n)
{ ok=false;break;}
if(ok)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
//法二 强联通
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define M 100005
#define N 10005
struct ss {
int to;
int next;
} edge[M];
int head[N];
int top, stack[N], mlik[N], indx[N], cnt, tot, belong[N], intime;
bool mark[N];
void add(int x, int y) {
edge[tot].to = y,edge[tot].next = head[x],head[x] = tot++;
}
void Tarjan(int x) {
mark[x] = true;
stack[++top] = x;
mlik[x] = indx[x] = ++intime;
int k, y;
for (k = head[x]; k != -1; k = edge[k].next) {
y = edge[k].to;
if (!indx[y]) {
Tarjan(y);
if (mlik[x] > mlik[y])
mlik[x] = mlik[y];
} else if (mark[y] && mlik[x] > indx[y])mlik[x] = indx[y];
}
if (mlik[x] == indx[x]) {
cnt++;
do {
y = stack[top--];
mark[y] = false;
belong[y] = cnt;
} while (y != x);
}
}
int main() {
int n, m, a, b, i;
while (scanf("%d %d", &n, &m), n + m) {
tot = 1;
memset(head, -1, sizeof (head));
while (m-- && scanf("%d %d", &a, &b))
add(a, b);
memset(indx, 0, sizeof (indx));
cnt = intime = top = 0;
for (i = 1; i <= n; i++)
if (!indx[i])Tarjan(i);
if (cnt ==1 )printf("Yes/n");
else printf("No/n");
}
return 0;
}