#include <bits/stdc++.h>
using namespace std;
const long long INF = 0x3f3f3f3f3f3f3f3f;
struct Edge {
  int u, v;
  long long w;
} edge[20005];
int rk[205][205];
long long G[205][205], val[205];
int n, m;
bool cmp(int a, int b) { return val[a] < val[b]; }
void floyd() {
  for (int k = 1; k <= n; ++k)
    for (int i = 1; i <= n; ++i)
      for (int j = 1; j <= n; ++j) G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
}
double solve() {
  floyd();
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      rk[i][j] = j;
      val[j] = G[i][j];
    }
    sort(rk[i] + 1, rk[i] + 1 + n, cmp);
  }
  long long ans = INF;
  for (int i = 1; i <= n; ++i) ans = min(ans, G[i][rk[i][n]] * 2);
  for (int i = 1, u, v; i <= m; ++i) {
    u = edge[i].u, v = edge[i].v;
    for (int p = n, j = n - 1; j >= 1; --j) {
      if (G[v][rk[u][j]] > G[v][rk[u][p]]) {
        ans = min(ans, G[u][rk[u][j]] + G[v][rk[u][p]] + edge[i].w);
        p = j;
      }
    }
  }
  return ans / 2.0;
}
int main() {
  scanf("%d%d", &n, &m);
  memset(G, 0x3f, sizeof(G));
  for (int i = 1; i <= n; ++i) G[i][i] = 0;
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
    G[edge[i].u][edge[i].v] = G[edge[i].v][edge[i].u] = edge[i].w;
  }
  printf("%.2lf\n", solve());
  return 0;
}
