#include <bits/stdc++.h>
using namespace std;
template <typename T>
using Matrix = vector<vector<T>>;
template <typename T>
Matrix<T> matrix(int R, int C, T x = T()) {
  return Matrix<T>(R, vector<T>(C, x));
}
using Graph = vector<vector<int>>;
double best_prob[500];
double g(int n, vector<double>& probabilities, vector<int>& colors) {
  for (int i = 0; i < n; i++)
    best_prob[colors[i]] = max(best_prob[colors[i]], probabilities[i]);
  auto result = 0.0;
  for (int i = 0; i < n; i++) {
    result += best_prob[colors[i]];
    best_prob[colors[i]] = 0;
  }
  return result;
}
double p_w2[500];
double p(int n, Graph& graph, Matrix<int>& distances,
         vector<int> w1_candidates) {
  auto w2_possible = vector<bool>(n);
  for (auto w1 : w1_candidates)
    for (auto w2 : graph[w1]) w2_possible[w2] = true;
  auto w2_candidates = vector<int>();
  for (int w2 = 0; w2 < n; w2++)
    if (w2_possible[w2]) w2_candidates.push_back(w2);
  auto w2_count = static_cast<int>(w2_candidates.size());
  fill(begin(p_w2), end(p_w2), 0);
  auto p = 1.0 / static_cast<double>(w1_candidates.size());
  for (auto w1 : w1_candidates) {
    auto q = 1.0 / static_cast<double>(graph[w1].size());
    for (auto w2 : graph[w1]) p_w2[w2] += p * q;
  }
  auto w2_probabilities = vector<double>();
  for (auto w2 : w2_candidates) w2_probabilities.push_back(p_w2[w2]);
  auto result = 0.0;
  for (int v2 = 0; v2 < n; v2++) {
    auto w2_distances = vector<int>(w2_count);
    for (int i = 0; i < w2_count; i++)
      w2_distances[i] = distances[v2][w2_candidates[i]];
    result = max(result, g(w2_count, w2_probabilities, w2_distances));
  }
  return result;
}
double p(int n, Graph& graph, Matrix<int>& distances, int v1) {
  unordered_map<int, vector<int>> by_distance;
  for (int w1 = 0; w1 < n; w1++) by_distance[distances[v1][w1]].push_back(w1);
  auto result = 0.0;
  for (auto kv : by_distance) {
    auto size = static_cast<double>(kv.second.size());
    auto p_distance = size / n;
    result += max(1.0 / size, p(n, graph, distances, kv.second)) * p_distance;
  }
  return result;
}
Matrix<int> floyd_warshall(int n, Graph graph) {
  auto distances = matrix<int>(n, n, n);
  for (int i = 0; i < n; i++) {
    distances[i][i] = 0;
    for (auto j : graph[i]) distances[i][j] = 1;
  }
  for (int k = 0; k < n; k++)
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        distances[i][j] =
            min(distances[i][j], distances[i][k] + distances[k][j]);
  return distances;
}
double solve(int n, Graph graph) {
  auto distances = floyd_warshall(n, graph);
  auto result = 0.0;
  for (int v1 = 0; v1 < n; v1++)
    result = max(result, p(n, graph, distances, v1));
  return result;
}
int main() {
  int n, m;
  cin >> n >> m;
  auto graph = Graph(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  cout << solve(n, graph) << endl;
}
