An undirected graph is called a caterpillar if it is a connected graph without cycles and it has such a path p that any vertex is located at a distance of at most 1 from the path p. The caterpillar can contain loops (edges from a vertex to itself) but cannot contain multiple (parallel) edges.

The picture contains an example of a caterpillar: 

<image>

You are given an undirected graph G. You are allowed to do a merging operations, each such operation merges two vertices into one vertex. For that two any vertices a and b (a ≠ b) are chosen. These verteces are deleted together with their edges (which are incident to at least one of the vertices a or b) but a new vertex w is added together with edges (x, w) for each edge (a, w) and/or (b, w). If there was the edge (a, b) it transforms to the loop (w, w). The resulting graph (after the merging operation) may contain multiple (parallel) edges between pairs of vertices and loops. Let us note that this operation decreases the number of vertices of graph by 1 but leaves the number of edges in the graph unchanged.

The merging operation can be informally described as a unity of two vertices of the graph into one with the natural transformation of the graph edges.

You may apply this operation consecutively and make the given graph to be a caterpillar. Write a program that will print the minimal number of merging operations required to make the given graph a caterpillar.

Input

The first line contains a pair of integers n, m (1 ≤ n ≤ 2000;0 ≤ m ≤ 105), where n represents the number of vertices in the graph and m is the number of edges in it. Then the following m lines contain edge descriptions, one edge description per line. Every line contains a pair of integers ai, bi (1 ≤ ai, bi ≤ n;ai ≠ bi), ai, bi which represent the indices of the vertices connected by the edge. The vertices are numbered from 1 to n. In the given graph it will be no more than one edge between any pair of vertices. The given graph is not necessarily connected.

Output

Print the minimal required number of operations.

Examples

Input

4 4
1 2
2 3
3 4
4 2


Output

2


Input

6 3
1 2
3 4
5 6


Output

2


Input

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


Output

1
#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > G, F;
vector<int> visited, explored, V, dp1, dp2, cat, childs, dsu, par, nodes,
    leaves;
int dfs_contract(int v, int p) {
  par[v] = p;
  nodes.push_back(v);
  ++visited[v];
  int ans = 0;
  for (int u : G[v]) {
    if (u == p) continue;
    if (visited[u]) {
      if (explored[u]) continue;
      --V[v];
      ++V[u];
      continue;
    }
    ans += dfs_contract(u, v);
    V[v] += V[u];
    dp1[v] += dp1[u];
  }
  ++explored[v];
  if (V[v] < 0) {
    ++dp1[v];
    dsu[v] = p;
    return 0;
  }
  ans += dp1[v];
  dp1[v] = 0;
  return ans;
}
int Find(int v) {
  if (dsu[v] == v)
    return v;
  else
    return dsu[v] = Find(dsu[v]);
}
void dfs_init(int v, int p) {
  ++childs[v];
  leaves[v] = (F[v].size() < 2);
  for (int u : F[v]) {
    if (u == p) continue;
    dfs_init(u, v);
    childs[v] += childs[u];
    leaves[v] += leaves[u];
  }
}
int far(int v, int& d) {
  queue<vector<int> > Q;
  Q.push({0, v, v});
  int u = v, p;
  while (not Q.empty()) {
    vector<int> aux = Q.front();
    Q.pop();
    d = aux[0], u = aux[1], p = aux[2];
    for (int w : F[u]) {
      if (w != p) Q.push({d + 1, w, u});
    }
  }
  return u;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  G = F = vector<vector<int> >(n);
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  visited = explored = V = dp1 = dp2 = childs = dsu = par = leaves =
      vector<int>(n, 0);
  for (int i = 0; i < n; ++i) dsu[i] = i;
  int ans = 0;
  for (int i = 0; i < n; ++i) {
    if (not visited[i]) {
      if (i) ++ans;
      nodes.clear();
      ans += dfs_contract(i, i);
      for (int v : nodes) {
        if (v == i) continue;
        int u = Find(v);
        int w = Find(par[v]);
        if (u == w) continue;
        F[u].push_back(w);
        F[w].push_back(u);
      }
      dfs_init(i, i);
      int d = 0;
      int v = far(i, d);
      d = 0;
      int u = far(v, d);
      d = max(0, d - 1) + leaves[i];
      ans += childs[i] - d;
    }
  }
  cout << ans << endl;
}
