#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int INF = 0x3f3f3f3f, N = 505, M = 1e5 + 5;
int n, m, dis[N][N], rk[N][N];
struct edge {
  int u, v, w;
} e[M];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) dis[i][j] = (i == j ? 0 : INF);
  for (int i = 1; i <= m; i++) {
    cin >> e[i].u >> e[i].v >> e[i].w;
    dis[e[i].u][e[i].v] = dis[e[i].v][e[i].u] = e[i].w;
  }
  for (int k = 1; k <= n; k++) {
    for (int i = 1; i <= n; i++) {
      if (dis[i][k] == INF) continue;
      for (int j = 1; j <= n; j++) {
        if (dis[k][j] == INF) continue;
        if (dis[i][k] + dis[k][j] < dis[i][j])
          dis[i][j] = dis[i][k] + dis[k][j];
      }
    }
  }
  int ans = INF;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) rk[i][j] = j;
    sort(rk[i] + 1, rk[i] + n + 1,
         [&](int x, int y) -> bool { return dis[i][x] > dis[i][y]; });
    ans = min(ans, dis[i][rk[i][1]] * 2);
  }
  for (int k = 1; k <= m; k++) {
    int u = e[k].u, v = e[k].v, w = e[k].w;
    for (int i = 1; i <= n;) {
      int j = i + 1;
      while (j <= n && dis[v][rk[u][i]] >= dis[v][rk[u][j]]) j++;
      if (j == n + 1) break;
      ;
      ans = min(ans, dis[u][rk[u][j]] + dis[v][rk[u][i]] + w);
      i = j;
    }
  }
  cout << fixed << setprecision(2) << ans * 1.0 / 2 << '\n';
  return 0;
}
