#include <bits/stdc++.h>
using namespace std;
using namespace std::chrono;
struct Weighted_Edge {
  long long int u;
  long long int v;
  long long int weight;
  bool operator<(const Weighted_Edge& that) const {
    return weight < that.weight;
  }
  bool operator()(const Weighted_Edge& a, const Weighted_Edge& b) const {
    return a.weight > b.weight;
  }
};
struct comp {
  bool operator()(pair<long long int, long long int> const& a,
                  pair<long long int, long long int> const& b) {
    return a.first > b.first;
  }
};
vector<long long int> marked(10000007, 0);
vector<list<long long int> > G;
vector<long long int> ans;
void input(long long int v) {
  vector<list<long long int> > G1(v);
  G = G1;
  long long int x, y, e;
  cin >> e;
  while (e--) {
    cin >> x >> y;
    G[x - 1].push_back(y - 1);
    G[y - 1].push_back(x - 1);
  }
  return;
}
void solve() {
  long long int v, i, c = 0, d = 0, t = 0;
  cin >> v;
  input(v);
  queue<long long int> qu;
  long long int marked[v];
  memset(marked, 0, sizeof(marked));
  qu.push(0);
  marked[0] = -1;
  while (!qu.empty()) {
    c = qu.front();
    qu.pop();
    for (auto j : G[c]) {
      if (marked[j] != -1) {
        qu.push(j);
        marked[j] = -1;
      }
    }
  }
  memset(marked, 0, sizeof(marked));
  queue<pair<long long int, long long int> > qp;
  qp.push({c, 0});
  marked[c] = -1;
  pair<long long int, long long int> p;
  while (!qp.empty()) {
    p = qp.front();
    qp.pop();
    for (auto j : G[p.first]) {
      if (marked[j] != -1) {
        qp.push({j, p.second + 1});
        marked[j] = -1;
      }
    }
  }
  cout << p.second << endl;
  return;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  long long int t;
  t = 1;
  while (t--) {
    solve();
  }
  cout << endl;
  return 0;
}
