#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
using namespace std;

// typedef long long li;

// const int mod = 1e9 + 7;
// inline int Add(int x) { return x >= mod ? x - mod : x; }
// inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
// inline int Sub(int x) { return x < 0 ? x + mod : x; }
// inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
// inline int Mul(int x, int y) { return (int)((li)x * y % mod); }

// int Pow(int x, int y) {
//   int z = 1;
//   for (; y; y >>= 1) {
//     if (y & 1) z = Mul(z, x);
//     x = Mul(x, x);
//   }
//   return z;
// }

// ----------------------------------------

typedef pair<int, int> pii;
typedef long long li;

namespace dinic {
  const int maxn = 1e5, maxm = 1e6;
  typedef int FlowType;
  const FlowType inf_f = ~0U >> 1;

  void Init(int n);
  void AddEdge(int u, int v, FlowType cap);
  FlowType Solve(int s, int t);
  vector< pair<pii, FlowType> > Result(void);
}

namespace dinic {
  struct Edge {
    int v;
    FlowType cap, cap0;
  } edge[maxm << 1];

  int n, m, s, t;
  vector<int> g[maxn];

  void Init(int _n) {
    n = _n, m = 0;
    for (int i = 0; i < n; ++i) g[i].clear();
  }

  void AddEdge(int u, int v, FlowType c) {
    g[u].push_back(m);
    edge[m++] = (Edge){v, c, c};
    g[v].push_back(m);
    edge[m++] = (Edge){u, 0, 0};
  }

  int iter[maxn], dist[maxn];

  bool Bfs(void) {
    queue<int> que;
    que.push(s);
    FILL(dist, n, -1);
    dist[s] = 0;
    while (!que.empty()) {
      int u = que.front(); que.pop();
      for (int i = 0; i < g[u].size(); ++i) {
        Edge &e = edge[g[u][i]];
        if (e.cap && dist[e.v] == -1) {
          dist[e.v] = dist[u] + 1;
          que.push(e.v);
        }
      }
    }
    return dist[t] >= 0;
  }

  FlowType Dfs(int u, FlowType f) {
    if (u == t) return f;
    FlowType sum = 0;
    for (int &i = iter[u]; i < g[u].size(); ++i) {
      Edge &e = edge[g[u][i]], &rev = edge[g[u][i] ^ 1];
      if (e.cap && dist[e.v] == dist[u] + 1) {
        FlowType res = Dfs(e.v, min(f - sum, e.cap));
        e.cap -= res;
        rev.cap += res;
        if ((sum += res) == f) break;
      }
    }
    return sum;
  }

  FlowType Solve(int _s, int _t) {
    s = _s, t = _t;
    FlowType ans = 0;
    while (Bfs()) {
      FILL(iter, n, 0);
      ans += Dfs(s, inf_f);
    }
    return ans;
  }

  vector< pair<pii, FlowType> > Result(void) {
    vector< pair<pii, FlowType> > ans;
    for (int u = 0; u < n; ++u) {
      for (int i = 0; i < g[u].size(); ++i) {
        Edge &e = edge[g[u][i]];
        if (e.cap < e.cap0) {
          ans.push_back(make_pair(pii(u, e.v), e.cap0 - e.cap));
        }
      }
    }
    return ans;
  }
}

// ----------------------------------------

const int maxn = 1e5;
int d[maxn], n, m;
vector<pii> edge;
 
int main(void) {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    --u; --v;
    ++d[u]; ++d[v];
    edge.push_back({u, v});
  }

  int cnt6 = 0;
  vector<int> d4;
  for (int i = 0; i < n; ++i) {
    if (d[i] & 1) {
      puts("No");
      return 0;
    }
    if (d[i] == 4) {
      d4.push_back(i);
    } else if (d[i] >= 6) {
      ++cnt6;
    }
  }

  if (cnt6 || d4.size() >= 3) {
    puts("Yes");
    return 0;
  }
  if (d4.size() <= 1) {
    puts("No");
    return 0;
  }

  int A = d4[0], B = d4[1];
  dinic::Init(n);
  for (auto e : edge) {
    dinic::AddEdge(e.first, e.second, 1);
    dinic::AddEdge(e.second, e.first, 1);
  }
  int f = dinic::Solve(A, B);
  puts(f == 2 ? "Yes" : "No");
  return 0;
}


Measured memory_bytes: 16372