#include <bits/stdc++.h>
using namespace std;
int d[205][205];
int rk[205][205];
bool vis[205];
struct Point {
  int x, y, w;
  Point(int ix = 0, int iy = 0, int iw = 0) : x(ix), y(iy), w(iw) {}
} pt[205 * 205 / 2];
void floyd(int n) {
  for (int k = 1; k <= n; k++) {
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++)
        if (i != j) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
    }
  }
}
int solve(int c, int n) {
  int u = pt[c].x, v = pt[c].y;
  int tmp = min(d[u][rk[u][n]] << 1, d[v][rk[v][n]] << 1);
  for (int cmp = n, i = n - 1; i; i--) {
    if (d[v][rk[u][i]] > d[v][rk[u][cmp]]) {
      tmp = min(tmp, d[u][rk[u][i]] + d[v][rk[u][cmp]] + pt[c].w);
      cmp = i;
    }
  }
  return tmp;
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  memset(d, 0x3f, sizeof(d));
  for (int i = 1; i <= n; i++) d[i][i] = 0;
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    d[u][v] = d[v][u] = w;
    pt[i] = Point(u, v, w);
  }
  floyd(n);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) rk[i][j] = j;
    for (int j = 1; j <= n; j++) {
      for (int k = j + 1; k <= n; k++) {
        if (d[i][rk[i][j]] > d[i][rk[i][k]]) swap(rk[i][j], rk[i][k]);
      }
    }
  }
  int ans = 0x3f3f3f3f;
  for (int i = 1; i <= m; i++) {
    int tmp = solve(i, n);
    ans = min(tmp, ans);
  }
  printf("%lf\n", ans / 2.0);
  return 0;
}
