#include <bits/stdc++.h>
using namespace std;
int m, n, cnt = 0;
vector<vector<int> > g;
vector<int> outgroup;
int main() {
  cin >> n >> m;
  vector<int> emptyg;
  g.push_back(emptyg);
  for (int i = 1; i <= n; i++) {
    vector<int> subg;
    g.push_back(subg);
  }
  for (int i = 0; i < m; i++) {
    int fr, to;
    cin >> fr >> to;
    g[fr].push_back(to);
    g[to].push_back(fr);
  }
  while (true) {
    outgroup.clear();
    cerr << "cnt == " << cnt << endl;
    for (int i = 1; i <= n; i++) {
      int deg = g[i].size();
      cerr << "node " << i << " has degree " << deg << "\n";
      if (deg == 1) {
        outgroup.push_back(i);
      }
      cerr.flush();
    }
    if (outgroup.empty()) {
      cout << cnt << endl;
      return 0;
    }
    vector<int>::iterator it = outgroup.begin();
    for (; it != outgroup.end(); it++) {
      int nodetodelete = *it;
      cerr << "deleting node " << nodetodelete << "..." << endl;
      int onlyconnectednode;
      if (!g[nodetodelete].empty()) {
        onlyconnectednode = g[nodetodelete][0];
      } else {
        continue;
      }
      vector<int>::iterator adjit = g[onlyconnectednode].begin();
      for (; adjit != g[onlyconnectednode].end(); adjit++) {
        if (*adjit == nodetodelete) {
          g[onlyconnectednode].erase(adjit);
          break;
        }
      }
      g[nodetodelete].clear();
    }
    cnt = cnt + 1;
    cerr << "has the thread reached here?" << endl;
    bool isEnd = true;
    vector<vector<int> >::iterator ggit = g.begin();
    for (; ggit != g.end(); ggit++) {
      vector<int> thissubg = *ggit;
      isEnd = thissubg.size() == 1 ? false : isEnd;
    }
    if (isEnd) {
      break;
    }
  }
  cout << cnt << endl;
  return 0;
}
