#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
inline void smax(int &x, int y) { x = max(x, y); }
inline void smin(int &x, int y) { x = min(x, y); }
ll gcd(ll a, ll b) { return ((b == 0) ? a : gcd(b, a % b)); }
struct edge {
  ll from, to, cap, flow, index;
  edge(ll from, ll to, ll cap, ll flow, ll index)
      : from(from), to(to), cap(cap), flow(flow), index(index) {}
};
struct PushRelabel {
  static const long long INF = 1e18;
  ll n;
  vector<vector<edge>> g;
  vector<ll> excess;
  vector<ll> height;
  PushRelabel(ll n) : n(n), g(n), excess(n), height(n) {}
  void addEdge(ll from, ll to, ll 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) {
    ll amt = (ll)min(excess[e.from], (long long)e.cap - e.flow);
    if (height[e.from] <= height[e.to] || amt == 0) return;
    e.flow += amt;
    g[e.to][e.index].flow -= amt;
    excess[e.to] += amt;
    excess[e.from] -= amt;
  }
  void relabel(ll u) {
    ll d = 2e5;
    for (auto &it : g[u]) {
      if (it.cap - it.flow > 0) d = min(d, height[it.to]);
    }
    if (d < INF) height[u] = d + 1;
  }
  vector<ll> find_max_height_vertices(ll source, ll dest) {
    vector<ll> max_height;
    for (ll i = 0; i < n; i++) {
      if (i != source && i != dest && excess[i] > 0) {
        if (!max_height.empty() && height[i] > height[max_height[0]])
          max_height.clear();
        if (max_height.empty() || height[i] == height[max_height[0]])
          max_height.push_back(i);
      }
    }
    return max_height;
  }
  long long max_flow(ll source, ll dest) {
    excess.assign(n, 0);
    height.assign(n, 0);
    height[source] = n;
    excess[source] = INF;
    for (auto &it : g[source]) push(it);
    vector<ll> current;
    while (!(current = find_max_height_vertices(source, dest)).empty()) {
      for (auto i : current) {
        bool pushed = false;
        for (auto &e : g[i]) {
          if (excess[i] == 0) break;
          if (e.cap - e.flow > 0 && height[e.from] == height[e.to] + 1) {
            push(e);
            pushed = true;
          }
        }
        if (!pushed) {
          relabel(i);
          break;
        }
      }
    }
    long long max_flow = 0;
    for (auto &e : g[source]) max_flow += e.flow;
    return max_flow;
  }
};
int32_t main() {
  std::ios::sync_with_stdio(false);
  cin.tie(NULL);
  ll n, m, x;
  cin >> n >> m >> x;
  vector<vector<pair<ll, ll>>> gr(n + 1);
  for (__typeof(m) i = (0) - ((0) > (m)); i != (m) - ((0) > (m));
       i += 1 - 2 * ((0) > (m))) {
    ll x, y, w;
    cin >> x >> y >> w;
    gr[x].push_back(make_pair(y, w));
  }
  long double lo = 1e-11, hi = 1000000100.0, mid = 0.0, ans = 0;
  while (fabs(hi - lo) > 1e-11) {
    mid = (lo + hi) / 2.0;
    PushRelabel flow(n + 1);
    for (__typeof(n + 1) i = (1) - ((1) > (n + 1));
         i != (n + 1) - ((1) > (n + 1)); i += 1 - 2 * ((1) > (n + 1))) {
      for (__typeof(gr[i].size()) j = (0) - ((0) > (gr[i].size()));
           j != (gr[i].size()) - ((0) > (gr[i].size()));
           j += 1 - 2 * ((0) > (gr[i].size()))) {
        flow.addEdge(i, gr[i][j].first, floor(gr[i][j].second / mid));
      }
    }
    long double val = flow.max_flow(1, n);
    if (val >= x) {
      ans = x * mid;
      lo = mid;
    } else {
      hi = mid;
    }
  }
  cout << fixed << setprecision(8);
  cout << ans;
}
