Problem:
Score : 800 points

Problem Statement

You are given a simple connected undirected graph consisting of N vertices and M edges.
The vertices are numbered 1 to N, and the edges are numbered 1 to M.

Edge i connects Vertex a_i and b_i bidirectionally.

Determine if three circuits (see Notes) can be formed using each of the edges exactly once.

Notes

A circuit is a cycle allowing repetitions of vertices but not edges.

Constraints

All values in input are integers.

1 \leq N,M \leq 10^{5}

1 \leq a_i, b_i \leq N

The given graph is simple and connected.

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1
:
a_M b_M

Output

If three circuits can be formed using each of the edges exactly once, print Yes; if they cannot, print No.

Sample Input 1

7 9
1 2
1 3
2 3
1 4
1 5
4 5
1 6
1 7
6 7

Sample Output 1

Yes

Three circuits can be formed using each of the edges exactly once, as follows:

Sample Input 2

3 3
1 2
2 3
3 1

Sample Output 2

No

Three circuits are needed.

Sample Input 3

18 27
17 7
12 15
18 17
13 18
13 6
5 7
7 1
14 5
15 11
7 6
1 9
5 4
18 16
4 6
7 2
7 11
6 3
12 14
5 2
10 5
7 8
10 15
3 15
9 8
7 15
5 16
18 15

Sample Output 3

Yes

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.util.LinkedList;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        C solver = new C();
        solver.solve(1, in, out);
        out.close();
    }

    static class C {
        Edge[] parent;
        List<Edge>[] g;

        boolean dfs(int v, int p) {
            for (Edge edge : g[v]) {
                if (edge.used || edge.to == p)
                    continue;
                if (parent[edge.to] == null) {
                    parent[edge.to] = edge;
                    if (dfs(edge.to, v)) {
                        return true;
                    }
                } else {
                    edge.used = edge.rev.used = true;
                    int cur = v;
                    while (cur != edge.to) {
                        parent[cur].used = parent[cur].rev.used = true;
                        cur = parent[cur].from;
                    }
                    return true;
                }
            }
            return false;
        }

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.ni(), m = in.ni();
            parent = new Edge[n];
            Edge[] edges = new Edge[m];
            g = new List[n];
            for (int i = 0; i < n; i++) {
                g[i] = new LinkedList<>();
            }
            int[] degree = new int[n];
            for (int i = 0; i < m; i++) {
                int from = in.ni() - 1, to = in.ni() - 1;
                Edge e = new Edge(from, to, i);
                edges[i] = e;
                g[from].add(e);
                Edge rev = new Edge(to, from, i);
                e.rev = rev;
                rev.rev = e;
                g[to].add(rev);
                degree[from]++;
                degree[to]++;
            }
            for (int i = 0; i < n; i++) {
                if (degree[i] % 2 != 0) {
                    out.println("No");
                    return;
                }
            }
            Edge empty = new Edge(0, 0, -1);
            parent[0] = empty;
            if (dfs(0, -1)) {
                for (int it = 0; it < 2; it++) {
                    boolean found = false;
                    Arrays.fill(parent, null);
                    for (int i = 0; i < m; i++) {
                        if (!edges[i].used) {
                            parent[edges[i].from] = empty;
                            found = dfs(edges[i].from, -1);
                            break;
                        }
                    }
                    if (!found) {
                        out.println("No");
                        return;
                    }
                }
                out.println("Yes");
            } else {
                out.println("No");
                ;
            }

        }

        class Edge {
            int from;
            int to;
            int id;
            Edge rev;
            boolean used;

            public Edge(int from, int to, int id) {
                this.from = from;
                this.to = to;
                this.id = id;
            }

        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String ns() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int ni() {
            return Integer.parseInt(ns());
        }

    }
}