#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 2000 + 20;
int n, m, belong[MAXN], val[MAXN], sum[MAXN], cntBcc, depth[MAXN], low[MAXN];
bool vis[MAXN];
vector<int> g[MAXN];
stack<int> s;
void dfs(int now, int pre, int deep = 1) {
  s.push(now);
  depth[now] = deep;
  vis[now] = 1;
  low[now] = deep;
  for (auto it : g[now]) {
    if (it != pre) {
      if (!vis[it]) {
        dfs(it, now, deep + 1);
        low[now] = min(low[now], low[it]);
      } else {
        low[now] = min(low[now], depth[it]);
      }
    }
  }
  if (low[now] == deep) {
    cntBcc++;
    while (!s.empty()) {
      int index = s.top();
      s.pop();
      val[cntBcc]++;
      belong[index] = cntBcc;
      if (index == now) break;
    }
  }
}
int res, cntCc = 0, bestValue[MAXN], cntLeaves[MAXN];
vector<int> CC[MAXN];
bool calc[MAXN];
int dp[MAXN];
int ccSize[MAXN];
void dfsCheck(int now, int pre) {
  vis[now] = 1;
  ccSize[cntCc]++;
  CC[cntCc].push_back(now);
  for (auto it : g[now]) {
    if (it != pre) {
      dfsCheck(it, now);
    }
  }
}
void dfsInit(int now, int pre) {
  sum[now] = 1;
  cntLeaves[now] = 0;
  int cntChild = 0;
  for (auto it : g[now]) {
    if (it != pre) {
      cntChild++;
      dfsInit(it, now);
      sum[now] += sum[it];
      cntLeaves[now] += cntLeaves[it];
    }
  }
  if (!cntChild) cntLeaves[now] = 1;
}
int dfsDp(int now, int pre) {
  if (calc[now]) return dp[now];
  calc[now] = 1;
  dp[now] = 1;
  for (auto it : g[now]) {
    if (it != pre) dp[now] = max(dp[now], dfsDp(it, now) + 1);
  }
  return dp[now];
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  vector<pair<int, int> > edges;
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v;
    edges.push_back(make_pair(u, v));
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int i = 1; i <= n; ++i)
    if (!vis[i]) dfs(i, 0);
  res = n - cntBcc;
  for (int i = 1; i <= n; ++i) g[i].clear();
  for (int i = 0; i < m; ++i) {
    int u, v;
    u = edges[i].first;
    v = edges[i].second;
    if (belong[u] != belong[v]) {
      g[belong[u]].push_back(belong[v]);
      g[belong[v]].push_back(belong[u]);
    }
  }
  memset(vis, 0, sizeof(vis));
  n = cntBcc;
  for (int i = 1; i <= n; ++i) val[i] = 1;
  for (int i = 1; i <= n; ++i) {
    if (!vis[i]) {
      cntCc++;
      dfsCheck(i, 0);
    }
  }
  for (int i = 1; i <= cntCc; ++i) {
    bestValue[i] = INF;
    for (auto it : CC[i]) {
      memset(calc, 0, sizeof(calc));
      memset(dp, 0, sizeof(dp));
      dfsInit(it, 0);
      bestValue[i] =
          min(bestValue[i], sum[it] - dfsDp(it, 0) - cntLeaves[it] + 1);
    }
  }
  int addition = 0;
  for (int i = 1; i <= cntCc; ++i) {
    addition += bestValue[i];
  }
  cout << addition + res + cntCc - 1 << endl;
  return 0;
}
