#include <bits/stdc++.h>
using namespace std;
struct ed {
  int pre, to;
} edge[400010] = {0};
int nodenum, edgenum, at = 0, ptr[200010] = {0};
int stackx[200010] = {0}, headx, tstamp = 0, cache1, cache2;
int dfn[200010] = {0}, low[200010] = {0}, inst[200010] = {0};
int belong[200010], sccnum = 0, siz[200010] = {0}, edgnum[200010] = {0};
int ans;
inline void readx(int& x) {
  x = 0;
  int k = 1;
  register char ch = 0;
  while (ch < '0' || ch > '9') {
    ch = getchar();
    if (ch == '-') k = -1;
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  x *= k;
}
inline void Insert(int fx, int tx) {
  at++;
  edge[at].pre = ptr[fx];
  edge[at].to = tx;
  ptr[fx] = at;
  at++;
  edge[at].pre = ptr[tx];
  edge[at].to = fx;
  ptr[tx] = at;
}
inline void Tarjan(int u) {
  dfn[u] = low[u] = ++tstamp;
  stackx[++headx] = u;
  inst[u] = true;
  for (int prex = ptr[u]; prex; prex = edge[prex].pre) {
    if (!dfn[edge[prex].to]) {
      Tarjan(edge[prex].to);
      low[u] = min(low[u], low[edge[prex].to]);
    } else if (inst[edge[prex].to])
      low[u] = min(low[u], dfn[edge[prex].to]);
  }
  if (low[u] == dfn[u]) {
    sccnum++;
    do {
      siz[sccnum]++;
      cache2 = stackx[headx--];
      inst[cache2] = false;
      belong[cache2] = sccnum;
    } while (cache2 != u);
  }
}
inline void countx() {
  for (int i = 1; i <= nodenum; i++)
    for (int prex = ptr[i]; prex; prex = edge[prex].pre)
      if (belong[i] == belong[edge[prex].to]) edgnum[belong[i]]++;
}
inline void getans(int u, int visn, int st) {
  low[u] = true;
  if (visn == siz[belong[u]]) {
    if (siz[belong[u]] <= 2) return;
    int ednum = 0;
    for (int prex = ptr[u]; prex; prex = edge[prex].pre)
      if (belong[edge[prex].to] == belong[u]) ednum++;
    if (ednum != 2) return;
    for (int prex = ptr[u]; prex; prex = edge[prex].pre)
      if (belong[edge[prex].to] == belong[u] && edge[prex].to == st) ans++;
    return;
  }
  for (int prex = ptr[u]; prex; prex = edge[prex].pre)
    if (!low[edge[prex].to])
      if (belong[edge[prex].to] == belong[u])
        getans(edge[prex].to, visn + 1, st);
}
int main() {
  readx(nodenum);
  readx(edgenum);
  for (int i = 1; i <= edgenum; i++) {
    readx(cache1);
    readx(cache2);
    Insert(cache1, cache2);
  }
  for (int i = 1; i <= nodenum; i++)
    if (!dfn[i]) Tarjan(i);
  memset(low, 0, sizeof(low));
  countx();
  for (int i = 1; i <= nodenum; i++)
    if (!low[i])
      if (siz[belong[i]] * 2 == edgnum[belong[i]]) getans(i, 1, i);
  printf("%d\n", ans);
  return 0;
}
