#include <bits/stdc++.h>
using namespace std;
vector<int> node[2004];
int ja[2004];
int bio[2004];
int N, M;
int tajm;
bool onroute[2004];
inline int FIND(int x) { return x == ja[x] ? x : ja[x] = FIND(ja[x]); }
inline void JOIN(int x, int y) { ja[FIND(y)] = FIND(x); }
vector<int> v;
int cycle_start;
int operation = 0;
bool DFS(int x, int parent) {
  if (parent != -1) parent = FIND(parent);
  bio[x] = tajm;
  bool parent_used = false;
  for (int i = 0; i < node[x].size(); ++i) {
    int y = FIND(node[x][i]);
    if (y == parent && !parent_used) {
      parent_used = true;
      continue;
    }
    if (y == x) continue;
    if (bio[y] == tajm) {
      v.push_back(y);
      cycle_start = y;
      return true;
    }
    if (y == parent) continue;
    if (DFS(y, x)) {
      v.push_back(y);
      return cycle_start != x;
    } else if (cycle_start)
      return false;
  }
  return false;
}
int MERGE(int x, int y) {
  x = FIND(x);
  y = FIND(y);
  if (x == y) return x;
  if (node[y].size() > node[x].size()) swap(x, y);
  node[x].insert(node[x].end(), node[y].begin(), node[y].end());
  JOIN(x, y);
  ++operation;
  return x;
}
void remove_cycles(void) {
  ++tajm;
  for (int i = 1; i <= N; ++i) {
    if (FIND(i) != i) continue;
    cycle_start = 0;
    v.clear();
    ++tajm;
    DFS(i, -1);
    if (v.size()) {
      while (v.size() >= 2) {
        int x = v.back();
        v.pop_back();
        int y = v.back();
        v.pop_back();
        v.push_back(MERGE(x, y));
      }
      --i;
    }
  }
}
int max_dist, max_dist_x;
int component_size;
void distDFS(int x, int parent, int dist) {
  bio[x] = tajm;
  ++component_size;
  if (dist > max_dist) {
    max_dist = dist;
    max_dist_x = x;
  }
  for (int i = 0; i < node[x].size(); ++i) {
    int y = FIND(node[x][i]);
    if (bio[y] == tajm) continue;
    distDFS(y, x, dist + 1);
  }
}
bool routeDFS(int x, int target, int parent) {
  if (x == target) {
    onroute[x] = true;
    v.push_back(x);
    return true;
  }
  for (int i = 0; i < node[x].size(); ++i) {
    int y = FIND(node[x][i]);
    if (y == parent) continue;
    if (routeDFS(y, target, x)) {
      onroute[x] = true;
      v.push_back(x);
      return true;
    }
  }
  return false;
}
void mergeDFS(int x, int parent) {
  bio[x] = tajm;
  if (node[x].size() > 1 && !onroute[x]) ++operation;
  for (int i = 0; i < node[x].size(); ++i) {
    int y = FIND(node[x][i]);
    if (onroute[y] || y == parent || bio[y] == tajm) continue;
    mergeDFS(y, x);
  }
}
int main(void) {
  int A, B;
  scanf("%d%d", &N, &M);
  for (int i = 0; i < M; ++i) {
    scanf("%d%d", &A, &B);
    node[A].push_back(B);
    node[B].push_back(A);
  }
  for (int i = 1; i <= N; ++i) ja[i] = i;
  remove_cycles();
  memset(bio, 0, sizeof(bio));
  int components = 0;
  for (int i = 1; i <= N; ++i) {
    if (bio[i] || FIND(i) != i) continue;
    ++components;
    component_size = 0;
    max_dist = 0;
    ++tajm;
    distDFS(i, -1, 0);
    int D = max_dist_x;
    if (component_size <= 3) continue;
    max_dist = 0;
    ++tajm;
    distDFS(D, -1, 0);
    int E = max_dist_x;
    v.clear();
    routeDFS(D, E, -1);
    ++tajm;
    for (int j = 0; j < v.size(); ++j) mergeDFS(v[j], -1);
  }
  operation += components - 1;
  printf("%d\n", operation);
  return 0;
}
