// 此题首先得判断顶点数目是否等于边数目+1
// 其次是使用并查集判断图的连通性
// 此题有一个陷阱,就是输入0 0的时候输出Yes
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 100001
struct Node {
int u, v;
}node[MAXN];
int root[MAXN], hash[MAXN], mark[MAXN];
int get_root(int x)
{
if( root[x] == x ) {
return x;
}
return root[x] = get_root(root[x]);
}
int valid(int arc_cnt, int end_vertex)
{
int node_cnt(0), ans(0), rx, ry;
for(int i = 1; i <= end_vertex; i ++) {
node_cnt += mark[i];
}
if( node_cnt != arc_cnt+1 ) {
return 0;
}
for(int i = 1; i <= end_vertex; i ++) {
root[i] = (mark[i])? i : 0;
}
for(int i = 0; i < arc_cnt; i ++) {
rx = get_root( node[i].u ); ry = get_root( node[i].v );
if( rx != ry ) {
root[ rx ] = ry;
}
}
fill(hash, hash+end_vertex+1, 0);
for(int i = 1; i <= end_vertex; i ++) {
if( !mark[i] ) {
continue;
}
hash[ root[i] = get_root(i) ] = 1;
}
for(int i = 1; i <= end_vertex; i ++) {
ans += hash[i];
}
return (1 == ans)? 1 : 0;
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int end_vertex(0), u, v, arc_cnt(0), flag(0);
memset(mark, 0, sizeof(mark));
while( scanf("%d %d", &u, &v) ) {
if( -1 == u && -1 == v ) {
break;
}
else if( u && v ) {
mark[u] = 1; mark[v] = 1; flag = 1;
end_vertex = max(end_vertex, max(u, v));
node[ arc_cnt ].u = u; node[ arc_cnt ++ ].v = v;
}
else if( !u && !v ) {
if( !flag || valid(arc_cnt, end_vertex) ) {
printf("Yes\n");
}
else {
printf("No\n");
}
arc_cnt = end_vertex = 0; flag = 0;
memset(mark, 0, sizeof(mark));
}
}
return 0;
}