#include <bits/stdc++.h>
using namespace std;
int n, m;
struct Edge {
  int x, y, d;
} E[202 * 202];
struct Dist {
  int nod, dist;
  bool operator<(const Dist &ot) const { return dist > ot.dist; }
} Nod[202];
int d[202][202];
int ans;
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; ++i)
    for (int j = i + 1; j <= n; ++j) d[i][j] = d[j][i] = 2000000000;
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d %d", &E[i].x, &E[i].y, &E[i].d);
    E[i].d *= 2;
    if (d[E[i].x][E[i].y] > E[i].d)
      d[E[i].x][E[i].y] = d[E[i].y][E[i].x] = E[i].d;
  }
  for (int k = 1; k <= n; ++k)
    for (int i = 1; i <= n; ++i)
      for (int j = 1; j <= n; ++j)
        if (i != j)
          if (1LL * d[i][k] + 1LL * d[k][j] < 1LL * d[i][j])
            d[i][j] = d[i][k] + d[k][j];
  ans = 2000000000;
  for (int i = 1; i <= m; ++i) {
    int x = E[i].x, y = E[i].y;
    for (int i = 1; i <= n; ++i) Nod[i] = {i, d[x][i]};
    sort(Nod + 1, Nod + n + 1);
    int r = 0;
    for (int j = 1; j <= n; ++j) {
      int l = Nod[j].dist, mid = (l + r + E[i].d) / 2;
      if (mid >= l && mid <= l + E[i].d) ans = min(ans, mid);
      r = max(r, d[y][Nod[j].nod]);
    }
  }
  printf("%d", ans / 2);
  if (ans % 2) printf(".50\n");
  return 0;
}
