You are given a simple connected undirected graph with N vertices and M edges. Each edge connects two vertices bidirectionally. Determine if three circuits can be formed using each edge exactly once. A circuit is a cycle allowing repetitions of vertices but not edges. All input values are integers, and N and M are between 1 and 10^5. If three circuits can be formed, print "Yes"; otherwise, print "No".

# Buggy version:
n, m = [int(item) for item in input().split()]
edge = [[] for _ in range(n)]

def find_single_self_loop(start, prev, n):
    if prev != -1 and len(edge[n]) != 2:
        if n == start:
            return True
        else:
            return False
    for item in edge[n]:
        if item == prev:
            continue
        ret = find_single_self_loop(start, n, item)
        if ret:
            return True
    return False

for i in range(m):
    a, b = [int(item) for item in input().split()]
    a -= 1; b -= 1
    edge[a].append(b)
    edge[b].append(a)

order = [0] * (10**5 + 10)
# Must be Euler graph
for i, line in enumerate(edge):
    o = len(line)
    order[o] += 1
    if o % 2 != 0:
        print("No")
        exit()
    if o >= 4:
        index = i

# Existance of over order-6 node means graph includes over 3 circuits
if max(order[6:]) > 0:
    print("Yes")
    exit()

print(order[:10])
# only 1 order-4 up to 2 circuit
if order[4] <= 1:
    print("No")
    exit()
# over 3 order-4 includes over 3 circuits 
elif order[4] >= 3:
    print("Yes")
    exit()
# 2 order-4
else:
    ret = find_single_self_loop(index, -1, index)
    if ret:
        print("Yes")
    else:
        print("No")

# Fixed version:
import sys
sys.setrecursionlimit(10**6)
n, m = [int(item) for item in input().split()]
edge = [[] for _ in range(n)]

def find_single_self_loop(start, prev, n):
    if prev != -1 and len(edge[n]) != 2:
        if n == start:
            return True
        else:
            return False
    for item in edge[n]:
        if item == prev:
            continue
        ret = find_single_self_loop(start, n, item)
        if ret:
            return True
    return False

for i in range(m):
    a, b = [int(item) for item in input().split()]
    a -= 1; b -= 1
    edge[a].append(b)
    edge[b].append(a)

order = [0] * (10**5 + 10)
# Must be Euler graph
for i, line in enumerate(edge):
    o = len(line)
    order[o] += 1
    if o % 2 != 0:
        print("No")
        exit()
    if o >= 4:
        index = i

# Existance of over order-6 node means graph includes over 3 circuits
if max(order[6:]) > 0:
    print("Yes")
    exit()

# only 1 order-4 up to 2 circuit
if order[4] <= 1:
    print("No")
    exit()
# over 3 order-4 includes over 3 circuits 
elif order[4] >= 3:
    print("Yes")
    exit()
# 2 order-4
else:
    ret = find_single_self_loop(index, -1, index)
    if ret:
        print("Yes")
    else:
        print("No")

# Buggy version:
import sys
sys.setrecursionlimit(10**7)
INF = 10 ** 18
MOD = 10 ** 9 + 7
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return input()

from collections import defaultdict

def main():
    N, M = LI()
    edges = defaultdict(list)
    for _ in range(M):
        a, b = LI_()
        edges[a].append(b)
        edges[b].append(a)
    quads = []
    for i, e in enumerate(edges):
        c = len(e)
        if c % 2 == 1:
            loops = -1
            return 'No'
        if c >= 6:
            return 'Yes'
        if c == 4:
            quads.append(i)
    if len(quads) < 2:
        return 'No'
    for v in edges[quads[0]]:
        visited = [0] * N
        visited[quads[0]] = 1
        while v != quads[1]:
            visited[v] = 1
            for to in edges[v]:
                if visited[to] == 0:
                    v = to
                    break
            if visited[v] == 1:
                break
        if v != quads[1]:
            return 'Yes'

    return 'No'

print(main())

# Fixed version:
import sys
sys.setrecursionlimit(10**7)
INF = 10 ** 18
MOD = 10 ** 9 + 7
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return input()

from collections import defaultdict

def main():
    N, M = LI()
    edges = defaultdict(list)
    for _ in range(M):
        a, b = LI_()
        edges[a].append(b)
        edges[b].append(a)
    quads = []
    large = 0
    for i, e in edges.items():
        c = len(e)
        if c % 2 == 1:
            return 'No'
        if c >= 6:
            large += 1
        if c == 4:
            quads.append(i)
    if large > 0:
        return 'Yes'
    if len(quads) > 2:
        return 'Yes'
    if len(quads) < 2:
        return 'No'
    for v in edges[quads[0]]:
        visited = [0] * N
        visited[quads[0]] = 1
        while v != quads[1]:
            visited[v] = 1
            for to in edges[v]:
                if visited[to] == 0:
                    v = to
                    break
            if visited[v] == 1:
                break
        if v != quads[1]:
            return 'Yes'

    return 'No'

print(main())

# Buggy version:
N, M = map(int, input().split())
G = [[] for i in range(N)]
for i in range(M):
  a, b = map(int, input().split())
  G[a - 1].append(b - 1)
  G[b - 1].append(a - 1)
V = []
D = 0
for i in range(N):
  if len(G[i]) % 2:
    print('No')
    break
  D = max(len(G[i], D))
  if len(G[i]) == 4:
    V.append(i)
else:
  if D >= 6:
    print('Yes')
  elif len(V) != 2:
    print('Yes' if len(V) > 2 else 'No')
  else:
    s = V[0]
    for i in range(3):
      t = G[s].pop()
      G[t].pop(G[t].index(s))
      while t not in V:
        d = G[t].pop()
        G[d].pop(G[d].index(t))
        t = d
      if s == t:
        print('Yes')
        break
      else:
        s = t
    else:
      print('No')

# Fixed version:
N, M = map(int, input().split())
G = [[] for i in range(N)]
for i in range(M):
  a, b = map(int, input().split())
  G[a - 1].append(b - 1)
  G[b - 1].append(a - 1)
V = []
D = 0
for i in range(N):
  if len(G[i]) % 2:
    print('No')
    break
  D = max(len(G[i]), D)
  if len(G[i]) == 4:
    V.append(i)
else:
  if D >= 6:
    print('Yes')
  elif len(V) != 2:
    print('Yes' if len(V) > 2 else 'No')
  else:
    s = V[0]
    for i in range(3):
      t = G[s].pop()
      G[t].pop(G[t].index(s))
      while t not in V:
        d = G[t].pop()
        G[d].pop(G[d].index(t))
        t = d
      if s == t:
        print('Yes')
        break
      else:
        s = t
    else:
      print('No')