#include <bits/stdc++.h>
using namespace std;
int read() {
  int x = 0, f = 0;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = 1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return f ? -x : x;
}
const int N = 210;
struct Edge {
  int u, v, w;
} e[N * N];
int f[N][N], rk[N][N], val[N], n, m;
bool cmp(int a, int b) { return val[a] < val[b]; }
int main() {
  n = read();
  m = read();
  memset(f, 0x3f, sizeof(f));
  for (int i = 1; i <= m; i++) {
    e[i].u = read();
    e[i].v = read();
    e[i].w = read();
    f[e[i].u][e[i].v] = f[e[i].v][e[i].u] = e[i].w;
  }
  for (int i = 1; i <= n; i++) f[i][i] = 0;
  for (int k = 1; k <= n; k++) {
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      rk[i][j] = j;
      val[j] = f[i][j];
    }
    sort(rk[i] + 1, rk[i] + 1 + n, cmp);
  }
  int ans = 0x3f3f3f3f;
  for (int i = 1; i <= n; i++) ans = min(ans, f[i][rk[i][n]] * 2);
  for (int i = 1; i <= m; i++) {
    int p = n;
    for (int j = n - 1; j >= 1; j--) {
      if (f[e[i].v][rk[e[i].u][j]] > f[e[i].v][rk[e[i].u][p]]) {
        ans = min(ans,
                  f[e[i].u][rk[e[i].u][j]] + f[e[i].v][rk[e[i].u][p]] + e[i].w);
        p = j;
      }
    }
  }
  printf("%.9f\n", (double)ans / 2.0);
  return 0;
}
