from collections import Counter # Edges := [Edge*] # Edge := (Vertex, Vertex) # Vertex := Hashable except None def solve_hitofude(edges): def _make_vertexcounter(edges): '各頂点ごとに、辺の数を数える' c = Counter() for x, y in edges: c[x] += 1 c[y] += 1 return c def _make_edgeflag(edges, value=True): '通った辺を管理するための辞書を作る' d = dict() for edge in edges: d[edge] = value return d def _get_head_tail(counter): '始点・終点を決める' odd = [] for k,v in counter.items(): if v&1: odd.append(k) if len(odd) == 2: return tuple(odd) elif len(odd) == 0: t = c.most_common(1)[0][0] return t, t else: return None, None def _edge_selector(pos, edgeflag): 'ジェネレータ関数。ある点につながっていて、まだ通ってない辺をyieldするジェネレータを作る。' for edge in edgeflag: if edgeflag[edge]: a, b = edge if a == pos: yield edge, b if edgeflag[edge] and b == pos: yield edge, a stack_pos = [] # 通った点を順に入れていく stack_edge = [] # 通った辺を入れていく stack_selector = [] # _edge_selectorジェネレータを入れていく c = _make_vertexcounter(edges) remain = _make_edgeflag(edges) pos, tail = _get_head_tail(c) if pos is None: return None n = len(edges) selector = _edge_selector(pos, remain) while n: # 全部の辺をたどったら終了 try: edge, nextpos = next(selector) except StopIteration: # 辿れる辺がなくなったら戻る。これ以上戻れない場合はNoneを返す。 if stack_pos: pos = stack_pos.pop() remain[stack_edge.pop()] = True selector = stack_selector.pop() n += 1 else: return None else: # 辿れる場合の処理。 stack_pos.append(pos) stack_edge.append(edge) stack_selector.append(selector) pos = nextpos remain[edge] = False selector = _edge_selector(pos, remain) n -= 1 if pos == tail: return stack_pos, stack_edge assert False def main(): N,M = map(int,input().split()) lsedg = [tuple(map(int,input().split())) for i in range(M)] print('NO' if solve_hitofude(lsedg)==None else 'YES') main()