#include <bits/stdc++.h>
using namespace std;
long long n;
struct Edge {
  long long from, to, cap, flow, index;
  Edge(long long from, long long to, long long cap, long long flow,
       long long index)
      : from(from), to(to), cap(cap), flow(flow), index(index) {}
};
struct PushRelabel {
  long long N;
  vector<vector<Edge>> G;
  vector<long long> excess, height;
  PushRelabel(long long N) : N(N), G(N + 1), excess(N + 1), height(N + 1) {}
  void Addedge(long long from, long long to, long long cap) {
    G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
    if (from == to) {
      G[from].back().index++;
    }
    G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
  }
  void Push(Edge &e) {
    long long amt = min(excess[e.from], e.cap - e.flow);
    if (amt == 0) return;
    e.flow += amt;
    G[e.to][e.index].flow -= amt;
    excess[e.to] += amt;
    excess[e.from] -= amt;
  }
  void Relabel(long long u) {
    long long d = 1000000000;
    for (long long i = 0; i < G[u].size(); i++) {
      Edge e = G[u][i];
      if (e.cap - e.flow > 0) d = min(d, height[e.to]);
    }
    if (d < 1000000000) height[u] = d + 1;
  }
  vector<long long> find_max_height_vertices(long long s, long long t) {
    vector<long long> max_height;
    for (long long i = 1; i <= n; i++) {
      if (i != s && i != t && excess[i] > 0) {
        if (!max_height.empty() && height[i] > height[max_height[0]])
          max_height.clear();
        if (max_height.empty() || height[i] == max_height[height[0]])
          max_height.push_back(i);
      }
    }
    return max_height;
  }
  long long getMaxFlow(long long s, long long t) {
    height[s] = N;
    for (long long i = 0; i < G[s].size(); i++) {
      excess[s] += G[s][i].cap;
      Push(G[s][i]);
    }
    vector<long long> current;
    while (!(current = find_max_height_vertices(s, t)).empty()) {
      for (auto i : current) {
        bool pushed = false;
        for (long long j = 0; j < G[i].size(); j++) {
          Edge e = G[i][j];
          if (e.cap - e.flow > 0 && height[i] == height[e.to] + 1) {
            Push(G[i][j]);
            pushed = true;
          }
        }
        if (!pushed) {
          Relabel(i);
          break;
        }
      }
    }
    long long maxflow = 0;
    for (long long i = 0; i < G[s].size(); i++) {
      Edge e = G[s][i];
      maxflow += e.flow;
    }
    return maxflow;
  }
};
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  long long m, x;
  cin >> n >> m >> x;
  long long a[m], b[m], c[m];
  for (long long i = 0; i < m; i++) {
    cin >> a[i] >> b[i] >> c[i];
  }
  double lo = 0;
  double hi = 1000000;
  for (long long i = 0; i < 70; i++) {
    double mid = (lo + hi) / 2;
    struct PushRelabel pr = PushRelabel(n);
    for (long long j = 0; j < m; j++) {
      pr.Addedge(a[j], b[j], floor((double)c[j] / mid));
    }
    long long maxflow = pr.getMaxFlow(1, n);
    if (maxflow >= x)
      lo = mid;
    else
      hi = mid;
  }
  cout << fixed << setprecision(8);
  cout << (hi + lo) / 2 * x;
  return 0;
}
