#include <bits/stdc++.h>

using namespace std;

//<editor-fold desc="debugger">

template <class X, class Y>
ostream & operator << (ostream & os, const pair <X, Y>& p) {
    return os << "[" << p.first << ", " << p.second << "]" ;
}

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, const Container& x) {
    os << "{";
    bool f = 1;
    for (auto&y : x) {
        if (!f) os << ", ";
        else f = 0;
        os << y;
    }
    return os << "}";
}

struct Debug {
#ifndef ONLINE_JUDGE
    template<class T>
    Debug& operator << (const T& x) {
        cerr << x << " , ";
        return *this;
    }
    ~Debug() {cerr << endl;}
#define debug cerr << "Line(" << __LINE__ << ") : " , Debug()
#else
    template<class T>
    Debug& operator << (const T& x) {
        return *this;
    }
    #define debug Debug()
#endif
};

//</editor-fold>

//  (EV * min(flow , V))
// (EsqrtV) on bibrtite graphs

struct edge {
    int to , cap;
};

const int N = 55; // make sure is greater than max_node will ever be
int dist[N] , p[N] , src , max_node , snk; // don't forget to set src and snk
vector<edge> edges;
vector<int> network[N]; // adjacency list for maxflow

void addAugEdge(int u , int v , int c) {
    max_node = max(max_node , max(u , v));
    network[u].push_back(edges.size());
    edges.push_back({v , c});
    network[v].push_back(edges.size());
    edges.push_back({u , 0}); // c if undirected 0 if directed
}

bool BFS() {
    memset(dist , -1 , (max_node + 1) * sizeof dist[0]);
    queue<int> q;
    q.push(src);
    dist[src] = 0;

    while (q.size()) {
        int cur = q.front();
        q.pop();
        for (int ci : network[cur]) {
            auto &e = edges[ci];
            if (dist[e.to] == -1 && e.cap) {
                q.push(e.to);
                dist[e.to] = dist[cur] + 1;
            }
        }
    }

    return max_node >= snk && dist[snk] != -1;
}

int DFS(int node , int flow) {
    if (node == snk || !flow)
        return flow;

    for (; p[node] < network[node].size() ; p[node]++) {
        auto &e= edges[network[node][p[node]]];
        auto &re = edges[network[node][p[node]]^1];

        if (dist[node] + 1  != dist[e.to]) continue;

        int push = DFS(e.to , min(flow , e.cap));
        if (push) {
            e.cap -= push;
            re.cap += push;
            return push;
        }
    }

    return 0;
}

long long dinic() {
    long long flow = 0;
    while (BFS()) {
        memset(p , 0 , sizeof p);
        while (int f = DFS(src , 1e9)) // make sure that no edge has cap greater than 1e9
            flow += f;
    }
    return flow;
}

void init() { // every test case
    edges.clear();
    for (int i = 0 ;i <= max_node;i++)
        network[i].clear();
    max_node = 0;
}

vector<array<int , 3> > edgeList;
bool can(double v , int need) {
    init();
    for (auto &e : edgeList)
        addAugEdge(e[0] , e[1] , e[2] / v);
    return dinic() >= need;
}

int main() {
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in" , "r" , stdin);
#endif
    int n , m , x;
    cin >> n >> m >> x;

    while (m--) {
        int u , v , c;
        cin >> u >> v >> c;
        edgeList.push_back({u , v , c});
    }

    src = 1 , snk = n;

    double l = 0 , r = 1e6 + 6 , ans = -1;
    for (int it = 0 ; it < 500 ; it++) {
        double mid = (l + r) / 2;
        if (can(mid , x)) {
            ans = mid;
            l = mid;
        } else {
            r = mid;
        }
    }

    cout << fixed << setprecision(12) << ans * x;
}


#include <bits/stdc++.h>

using namespace std;

//<editor-fold desc="debugger">

template <class X, class Y>
ostream & operator << (ostream & os, const pair <X, Y>& p) {
    return os << "[" << p.first << ", " << p.second << "]" ;
}

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, const Container& x) {
    os << "{";
    bool f = 1;
    for (auto&y : x) {
        if (!f) os << ", ";
        else f = 0;
        os << y;
    }
    return os << "}";
}

struct Debug {
#ifndef ONLINE_JUDGE
    template<class T>
    Debug& operator << (const T& x) {
        cerr << x << " , ";
        return *this;
    }
    ~Debug() {cerr << endl;}
#define debug cerr << "Line(" << __LINE__ << ") : " , Debug()
#else
    template<class T>
    Debug& operator << (const T& x) {
        return *this;
    }
    #define debug Debug()
#endif
};

//</editor-fold>

//  (EV * min(flow , V))
// (EsqrtV) on bibrtite graphs

struct edge {
    int to , cap;
};

const int N = 55; // make sure is greater than max_node will ever be
int dist[N] , p[N] , src , max_node , snk; // don't forget to set src and snk
vector<edge> edges;
vector<int> network[N]; // adjacency list for maxflow

void addAugEdge(int u , int v , int c) {
    max_node = max(max_node , max(u , v));
    network[u].push_back(edges.size());
    edges.push_back({v , c});
    network[v].push_back(edges.size());
    edges.push_back({u , 0}); // c if undirected 0 if directed
}

bool BFS() {
    memset(dist , -1 , (max_node + 1) * sizeof dist[0]);
    queue<int> q;
    q.push(src);
    dist[src] = 0;

    while (q.size()) {
        int cur = q.front();
        q.pop();
        for (int ci : network[cur]) {
            auto &e = edges[ci];
            if (dist[e.to] == -1 && e.cap) {
                q.push(e.to);
                dist[e.to] = dist[cur] + 1;
            }
        }
    }

    return max_node >= snk && dist[snk] != -1;
}

int DFS(int node , int flow) {
    if (node == snk || !flow)
        return flow;

    for (; p[node] < network[node].size() ; p[node]++) {
        auto &e= edges[network[node][p[node]]];
        auto &re = edges[network[node][p[node]]^1];

        if (dist[node] + 1  != dist[e.to]) continue;

        int push = DFS(e.to , min(flow , e.cap));
        if (push) {
            e.cap -= push;
            re.cap += push;
            return push;
        }
    }

    return 0;
}

long long dinic() {
    long long flow = 0;
    while (BFS()) {
        memset(p , 0 , sizeof p);
        while (int f = DFS(src , 1e9)) // make sure that no edge has cap greater than 1e9
            flow += f;
    }
    return flow;
}

void init() { // every test case
    edges.clear();
    for (int i = 0 ;i <= max_node;i++)
        network[i].clear();
    max_node = 0;
}

const double eps = 1e-7;

vector<array<int , 3> > edgeList;
bool can(double v , int need) {
    init();
    for (auto &e : edgeList)
        addAugEdge(e[0] , e[1] , e[2] / v + eps);
    return dinic() >= need;
}

int main() {
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in" , "r" , stdin);
#endif
    int n , m , x;
    cin >> n >> m >> x;

    while (m--) {
        int u , v , c;
        cin >> u >> v >> c;
        edgeList.push_back({u , v , c});
    }

    src = 1 , snk = n;

    double l = 1.0 / x , r = 1e6 + 6;
    for (int it = 0 ; it < 100 ; it++) {
        double mid = (l + r) / 2;
        if (can(mid , x)) {
            l = mid;
        } else {
            r = mid;
        }
    }

    cout << fixed << setprecision(12) << l * x;
}


#include <bits/stdc++.h>

using namespace std;

//<editor-fold desc="debugger">

template <class X, class Y>
ostream & operator << (ostream & os, const pair <X, Y>& p) {
    return os << "[" << p.first << ", " << p.second << "]" ;
}

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, const Container& x) {
    os << "{";
    bool f = 1;
    for (auto&y : x) {
        if (!f) os << ", ";
        else f = 0;
        os << y;
    }
    return os << "}";
}

struct Debug {
#ifndef ONLINE_JUDGE
    template<class T>
    Debug& operator << (const T& x) {
        cerr << x << " , ";
        return *this;
    }
    ~Debug() {cerr << endl;}
#define debug cerr << "Line(" << __LINE__ << ") : " , Debug()
#else
    template<class T>
    Debug& operator << (const T& x) {
        return *this;
    }
    #define debug Debug()
#endif
};

//</editor-fold>

//  (EV * min(flow , V))
// (EsqrtV) on bibrtite graphs

struct edge {
    int to , cap;
};

const int N = 55; // make sure is greater than max_node will ever be
int dist[N] , p[N] , src , max_node , snk; // don't forget to set src and snk
vector<edge> edges;
vector<int> network[N]; // adjacency list for maxflow

void addAugEdge(int u , int v , int c) {
    max_node = max(max_node , max(u , v));
    network[u].push_back(edges.size());
    edges.push_back({v , c});
    network[v].push_back(edges.size());
    edges.push_back({u , 0}); // c if undirected 0 if directed
}

bool BFS() {
    memset(dist , -1 , (max_node + 1) * sizeof dist[0]);
    queue<int> q;
    q.push(src);
    dist[src] = 0;

    while (q.size()) {
        int cur = q.front();
        q.pop();
        for (int ci : network[cur]) {
            auto &e = edges[ci];
            if (dist[e.to] == -1 && e.cap) {
                q.push(e.to);
                dist[e.to] = dist[cur] + 1;
            }
        }
    }

    return max_node >= snk && dist[snk] != -1;
}

int DFS(int node , int flow) {
    if (node == snk || !flow)
        return flow;

    for (; p[node] < network[node].size() ; p[node]++) {
        auto &e= edges[network[node][p[node]]];
        auto &re = edges[network[node][p[node]]^1];

        if (dist[node] + 1  != dist[e.to]) continue;

        int push = DFS(e.to , min(flow , e.cap));
        if (push) {
            e.cap -= push;
            re.cap += push;
            return push;
        }
    }

    return 0;
}

long long dinic() {
    long long flow = 0;
    while (BFS()) {
        memset(p , 0 , sizeof p);
        while (int f = DFS(src , 1e9)) // make sure that no edge has cap greater than 1e9
            flow += f;
    }
    return flow;
}

void init() { // every test case
    edges.clear();
    for (int i = 0 ;i <= max_node;i++)
        network[i].clear();
    max_node = 0;
}

vector<array<int , 3> > edgeList;
bool can(double v , int need) {
    init();
    for (auto &e : edgeList)
        addAugEdge(e[0] , e[1] , e[2] / v);
    return dinic() >= need;
}

int main() {
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in" , "r" , stdin);
#endif
    int n , m , x;
    cin >> n >> m >> x;

    while (m--) {
        int u , v , c;
        cin >> u >> v >> c;
        edgeList.push_back({u , v , c});
    }

    src = 1 , snk = n;

    double l = 1e-7 , r = 1e6 + 6;
    for (int it = 0 ; it < 500 ; it++) {
        double mid = (l + r) / 2;
        if (can(mid , x)) {
            l = mid;
        } else {
            r = mid;
        }
    }

    cout << fixed << setprecision(12) << l * x;
}


#include <bits/stdc++.h>

using namespace std;

//<editor-fold desc="debugger">

template <class X, class Y>
ostream & operator << (ostream & os, const pair <X, Y>& p) {
    return os << "[" << p.first << ", " << p.second << "]" ;
}

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, const Container& x) {
    os << "{";
    bool f = 1;
    for (auto&y : x) {
        if (!f) os << ", ";
        else f = 0;
        os << y;
    }
    return os << "}";
}

struct Debug {
#ifndef ONLINE_JUDGE
    template<class T>
    Debug& operator << (const T& x) {
        cerr << x << " , ";
        return *this;
    }
    ~Debug() {cerr << endl;}
#define debug cerr << "Line(" << __LINE__ << ") : " , Debug()
#else
    template<class T>
    Debug& operator << (const T& x) {
        return *this;
    }
    #define debug Debug()
#endif
};

//</editor-fold>

//  (EV * min(flow , V))
// (EsqrtV) on bibrtite graphs

struct edge {
    int to , cap;
};

const int N = 55; // make sure is greater than max_node will ever be
int dist[N] , p[N] , src , max_node , snk; // don't forget to set src and snk
vector<edge> edges;
vector<int> network[N]; // adjacency list for maxflow

void addAugEdge(int u , int v , int c) {
    max_node = max(max_node , max(u , v));
    network[u].push_back(edges.size());
    edges.push_back({v , c});
    network[v].push_back(edges.size());
    edges.push_back({u , 0}); // c if undirected 0 if directed
}

bool BFS() {
    memset(dist , -1 , (max_node + 1) * sizeof dist[0]);
    queue<int> q;
    q.push(src);
    dist[src] = 0;

    while (q.size()) {
        int cur = q.front();
        q.pop();
        for (int ci : network[cur]) {
            auto &e = edges[ci];
            if (dist[e.to] == -1 && e.cap) {
                q.push(e.to);
                dist[e.to] = dist[cur] + 1;
            }
        }
    }

    return max_node >= snk && dist[snk] != -1;
}

int DFS(int node , int flow) {
    if (node == snk || !flow)
        return flow;

    for (; p[node] < network[node].size() ; p[node]++) {
        auto &e= edges[network[node][p[node]]];
        auto &re = edges[network[node][p[node]]^1];

        if (dist[node] + 1  != dist[e.to]) continue;

        int push = DFS(e.to , min(flow , e.cap));
        if (push) {
            e.cap -= push;
            re.cap += push;
            return push;
        }
    }

    return 0;
}

long long dinic() {
    long long flow = 0;
    while (BFS()) {
        memset(p , 0 , sizeof p);
        while (int f = DFS(src , 1e9)) // make sure that no edge has cap greater than 1e9
            flow += f;
    }
    return flow;
}

void init() { // every test case
    edges.clear();
    for (int i = 0 ;i <= max_node;i++)
        network[i].clear();
    max_node = 0;
}

vector<array<int , 3> > edgeList;
bool can(double v , int need) {
    init();
    for (auto &e : edgeList)
        addAugEdge(e[0] , e[1] , e[2] / v);
    return dinic() >= need;
}

int main() {
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in" , "r" , stdin);
#endif
    int n , m , x;
    cin >> n >> m >> x;

    while (m--) {
        int u , v , c;
        cin >> u >> v >> c;
        edgeList.push_back({u , v , c});
    }

    src = 1 , snk = n;

    double l = 1.0 / x , r = 1e6 + 6;
    for (int it = 0 ; it < 200 ; it++) {
        double mid = (l + r) / 2;
        if (can(mid , x)) {
            l = mid;
        } else {
            r = mid;
        }
    }

    cout << fixed << setprecision(12) << l * x;
}


#include <bits/stdc++.h>

using namespace std;

//<editor-fold desc="debugger">

template <class X, class Y>
ostream & operator << (ostream & os, const pair <X, Y>& p) {
    return os << "[" << p.first << ", " << p.second << "]" ;
}

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, const Container& x) {
    os << "{";
    bool f = 1;
    for (auto&y : x) {
        if (!f) os << ", ";
        else f = 0;
        os << y;
    }
    return os << "}";
}

struct Debug {
#ifndef ONLINE_JUDGE
    template<class T>
    Debug& operator << (const T& x) {
        cerr << x << " , ";
        return *this;
    }
    ~Debug() {cerr << endl;}
#define debug cerr << "Line(" << __LINE__ << ") : " , Debug()
#else
    template<class T>
    Debug& operator << (const T& x) {
        return *this;
    }
    #define debug Debug()
#endif
};

//</editor-fold>

//  (EV * min(flow , V))
// (EsqrtV) on bibrtite graphs

struct edge {
    int to , cap;
};

const int N = 55; // make sure is greater than max_node will ever be
int dist[N] , p[N] , src , max_node , snk; // don't forget to set src and snk
vector<edge> edges;
vector<int> network[N]; // adjacency list for maxflow

void addAugEdge(int u , int v , int c) {
    max_node = max(max_node , max(u , v));
    network[u].push_back(edges.size());
    edges.push_back({v , c});
    network[v].push_back(edges.size());
    edges.push_back({u , 0}); // c if undirected 0 if directed
}

bool BFS() {
    memset(dist , -1 , (max_node + 1) * sizeof dist[0]);
    queue<int> q;
    q.push(src);
    dist[src] = 0;

    while (q.size()) {
        int cur = q.front();
        q.pop();
        for (int ci : network[cur]) {
            auto &e = edges[ci];
            if (dist[e.to] == -1 && e.cap) {
                q.push(e.to);
                dist[e.to] = dist[cur] + 1;
            }
        }
    }

    return max_node >= snk && dist[snk] != -1;
}

int DFS(int node , int flow) {
    if (node == snk || !flow)
        return flow;

    for (; p[node] < network[node].size() ; p[node]++) {
        auto &e= edges[network[node][p[node]]];
        auto &re = edges[network[node][p[node]]^1];

        if (dist[node] + 1  != dist[e.to]) continue;

        int push = DFS(e.to , min(flow , e.cap));
        if (push) {
            e.cap -= push;
            re.cap += push;
            return push;
        }
    }

    return 0;
}

long long dinic() {
    long long flow = 0;
    while (BFS()) {
        memset(p , 0 , sizeof p);
        while (int f = DFS(src , 1e9)) // make sure that no edge has cap greater than 1e9
            flow += f;
    }
    return flow;
}

void init() { // every test case
    edges.clear();
    for (int i = 0 ;i <= max_node;i++)
        network[i].clear();
    max_node = 0;
}

vector<array<int , 3> > edgeList;
bool can(double v , int need) {
    init();
    for (auto &e : edgeList)
        addAugEdge(e[0] , e[1] , e[2] / v);
    return dinic() >= need;
}

int main() {
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in" , "r" , stdin);
#endif
    int n , m , x;
    cin >> n >> m >> x;

    while (m--) {
        int u , v , c;
        cin >> u >> v >> c;
        edgeList.push_back({u , v , c});
    }

    src = 1 , snk = n;

    double l = 1.0 / x , r = 1e6 + 6;
    for (int it = 0 ; it < 500 ; it++) {
        double mid = (l + r) / 2;
        if (can(mid , x)) {
            l = mid;
        } else {
            r = mid;
        }
    }

    cout << fixed << setprecision(12) << l * x;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;

typedef long long LL;
typedef pair<int, int> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < EPS)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    bool maxflow(int s, int t, int x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (int i = 0; i < x; ) {
            double new_flow = bfs(s, t);
//            cout << new_flow << " flowed from 1 to " << t << endl;
            int add = (int)(new_flow/perBear);
            if (add==0) return false;
            i += add;
        }
        return true;
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 0, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;

typedef long long LL;
typedef pair<int, double> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < EPS)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    bool maxflow(int s, int t, int x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (int i = 0; i < x; ) {
            double new_flow = bfs(s, t);
//            cout << new_flow << " flowed from 1 to " << t << endl;
            int add = (int)(new_flow/perBear);
            if (add==0) return false;
            i += add;
        }
        return true;
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 0, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, int c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        int ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            int flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    int new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans == 0)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    int maxflow(int s, int t) {
        int flow = 0;
        int new_flow;
        while ((new_flow = bfs(s, t)))
            flow += new_flow;
        return flow;
    }
};

struct ed {
    int u, v, c;
} edges[507];

int n, m, x;
bool canDo(double perBear)
{
    EdmondsKarp ekarp(n+1);
    for (int i = 1; i <= m; i++) {
        ekarp.AddEdge(edges[i].u, edges[i].v, edges[i].c/perBear);
    }
    return ekarp.maxflow(1, n) >= x;
}

int main()
{
    cin >> n >> m >> x;

    for (int i = 1; i <= m; i++) {
        cin >> edges[i].u >> edges[i].v >> edges[i].c;
    }

    double lo = 1, hi = 1e8;
    double mid;

    while (abs(lo-hi) > 1e-8) {
        mid = (lo+hi)/2;
        if (canDo(mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < 1e-10)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    bool maxflow(int s, int t, int x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (int i = 0; i < x; ) {
            double new_flow = bfs(s, t);
//            cout << new_flow << " flowed from 1 to " << t << endl;
            int add = (int)(new_flow/perBear);
            if (add==0) return false;
            i += add;
        }
        return true;
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 0, hi = 1000000;
    double mid;

    while (abs(lo-hi) > 1e-10) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid*x << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-7;

typedef long long LL;
typedef pair<int, double> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    long long bfs(int s, int t, double perBear) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v] >= perBear) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < perBear)   return 0;
        long long done = ans/perBear;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= done*perBear;
            cap[cur][prev] += done*perBear;
            cur = prev;
        }
        return done;
    }

    bool maxflow(int s, int t, long long x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (long long i = 0; i < x; ) {
            long long g = bfs(s, t, perBear);
//            cout << g << " done" << endl;
//            print();
            if (g==0) return false;
            i += g;
        }
        return true;
    }

    void print() {
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                cout << cap[i][j] << ' ';
            }
            cout << endl;
        }
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 1, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, int c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        int ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            int flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    int new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans == 0)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    int maxflow(int s, int t) {
        int flow = 0;
        int new_flow;
        while ((new_flow = bfs(s, t)))
            flow += new_flow;
        return flow;
    }
};

struct ed {
    int u, v, c;
} edges[507];

int n, m, x;
bool canDo(double perBear)
{
    EdmondsKarp ekarp(n+1);
    for (int i = 1; i <= m; i++) {
        ekarp.AddEdge(edges[i].u, edges[i].v, edges[i].c/perBear);
    }
    return ekarp.maxflow(1, n) >= x;
}

int main()
{
    cin >> n >> m >> x;

    for (int i = 1; i <= m; i++) {
        cin >> edges[i].u >> edges[i].v >> edges[i].c;
    }

    double lo = 0, hi = x*1e6;
    double mid;

    while (abs(lo-hi) > 1e-7) {
        mid = (lo+hi)/2;
        if (canDo(mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-7;

typedef long long LL;
typedef pair<int, double> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t, double perBear) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v] >= perBear) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < perBear)   return 0;
        int done = ans/perBear;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= done*perBear;
            cap[cur][prev] += done*perBear;
            cur = prev;
        }
        return done;
    }

    bool maxflow(int s, int t, int x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (int i = 0; i < x; ) {
            int g = bfs(s, t, perBear);
//            cout << g << " done" << endl;
//            print();
            if (g==0) return false;
            i += g;
        }
        return true;
    }

    void print() {
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                cout << cap[i][j] << ' ';
            }
            cout << endl;
        }
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 1, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;

typedef long long LL;
typedef pair<int, double> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t, double perBear) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v] >= perBear) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < perBear)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= perBear;
            cap[cur][prev] += perBear;
            cur = prev;
        }
        return 1;
    }

    bool maxflow(int s, int t, int x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (int i = 0; i < x; ) {
            int g = bfs(s, t, perBear);
//            cout << g << " done" << endl;
//            print();
            if (g==0) return false;
            i += g;
        }
        return true;
    }

    void print() {
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                cout << cap[i][j] << ' ';
            }
            cout << endl;
        }
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 1, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;

typedef long long LL;
typedef pair<int, double> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < 1e-15)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    bool maxflow(int s, int t, long long x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (long long i = 0; i < x; ) {
            double new_flow = bfs(s, t);
//            cout << new_flow << " flowed from 1 to " << t << endl;
            long long add = (long long)(new_flow/perBear);
            if (add==0) return false;
            i += add;
        }
        return true;
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 1, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < 1e-10)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    bool maxflow(int s, int t, int x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (int i = 0; i < x; ) {
            double new_flow = bfs(s, t);
//            cout << new_flow << " flowed from 1 to " << t << endl;
            int add = (int)(new_flow/perBear);
            if (add==0) return false;
            i += add;
        }
        return true;
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 0, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > 1e-10) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;

typedef long long LL;
typedef pair<int, double> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    double bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < 1e-15)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    bool maxflow(int s, int t, long long x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (long long i = 0; i < x; ) {
            double new_flow = bfs(s, t);
//            cout << new_flow << " flowed from 1 to " << t << endl;
            long long add = (long long)(new_flow/perBear);
            if (add==0) return false;
            i += add;
        }
        return true;
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 1, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-8;

typedef long long LL;
typedef pair<int, int> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v]) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < EPS)   return 0;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= ans;
            cap[cur][prev] += ans;
            cur = prev;
        }
        return ans;
    }

    bool maxflow(int s, int t, int x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (int i = 0; i < x; ) {
            double new_flow = bfs(s, t);
//            cout << new_flow << " flowed from 1 to " << t << endl;
            int add = (int)(new_flow/perBear);
            if (add==0) return false;
            i += add;
        }
        return true;
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 0, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;

typedef long long LL;
typedef pair<int, double> PII;
typedef vector<double> VI;
typedef vector<VI> VVI;

const int INF = 1e9+7;

struct EdmondsKarp
{
    int n;
    VVI cap, adj;

    EdmondsKarp(int nn) {
        n = nn;
        cap = VVI(n,  VI(n, 0));
        adj = VVI(n);
    }

    void AddEdge(int u, int v, double c) {
        if (u==v)   return;
        adj[u].push_back(v);
        adj[v].push_back(u);
        cap[u][v] += c;
        ///cap[v][u] += c;      // For Undirected Graphs.
    }

    int bfs(int s, int t, double perBear) {
        VI par(n, -1);
        par[s] = -2;
        queue<PII> q;
        q.push({s, INF});
        double ans = 0;

        while (!q.empty()) {
            int u = q.front().first;
            double flow = q.front().second;
            q.pop();

            for (int v : adj[u]) {
                if (par[v] == -1 && cap[u][v] >= perBear) {
                    par[v] = u;
                    double new_flow = min(flow, cap[u][v]);
                    if (v == t) {ans = new_flow; break;}
                    q.push({v, new_flow});
                }
            }
        }

        if (ans < perBear)   return 0;
        int done = ans/perBear;
        int cur = t;
        while (cur != s) {
            int prev = par[cur];
            cap[prev][cur] -= done*perBear;
            cap[cur][prev] += done*perBear;
            cur = prev;
        }
        return done;
    }

    bool maxflow(int s, int t, int x, double perBear) {
//        cout << "checking " << perBear << endl;
        for (int i = 0; i < x; ) {
            int g = bfs(s, t, perBear);
//            cout << g << " done" << endl;
//            print();
            if (g==0) return false;
            i += g;
        }
        return true;
    }

    void print() {
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                cout << cap[i][j] << ' ';
            }
            cout << endl;
        }
    }
};

///Solves SPOJ MTOTALF - Total Flow
///Given a graph find the max flow between two nodes
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, m, x;
    cin >> n >> m >> x;

    EdmondsKarp ekarp(n+1);

    while (m--) {
        int u, v, c;
        cin >> u >> v >> c;
        ekarp.AddEdge(u, v, c);
    }

    double lo = 1, hi = 1000000*x;
    double mid;

    while (abs(lo-hi) > EPS) {
        mid = (lo+hi)/2;
        EdmondsKarp tmp(ekarp);
        if (tmp.maxflow(1, n, x, mid/x)) lo = mid;
        else hi = mid;
    }

    mid = (lo+hi)/2;
    cout << fixed << setprecision(10) << mid << endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXN = 55;
const int MAXM = 1005;

int n, m, x, ai, bi, ci;

double w[MAXM], cw[MAXM];
int to[MAXM], opp[MAXM];
vector <int> G[MAXN];

bool vis[MAXN];
bool dfs(int u, double xi){
	vis[u] = true;
	if(u == n - 1)return true;

	for(int i : G[u])if(cw[i] >= xi){
		int v = to[i];
		if(vis[v])continue;

		if(dfs(v, xi)){
			cw[i] -= xi;
			cw[opp[i]] += xi;
			return true;
		}
	}
	return false;
}

bool check(double mid){
	memcpy(cw, w, sizeof w);

	int k = x;
	while(k--){
		memset(vis, false, sizeof vis);
		if(!dfs(0, mid))return false;
	}
	return true;
}
int main(){
	scanf("%d %d %d", &n, &m, &x);

	map < pair <int, int>, int> mp;
	int k = 0;

	for(int i = 0; i < m; i++){
		scanf("%d %d %d", &ai, &bi, &ci);
		ai--, bi--;

		if(mp.count({ai, bi}))w[mp[{ai, bi}]] += ci;
		else{
			w[k] += ci;

			G[ai].push_back(k);
			to[k] = bi;
			opp[k] = k + 1;
			mp[{ai, bi}] = k++;

			G[bi].push_back(k);
			to[k] = ai;
			opp[k] = k - 1;
			mp[{bi, ai}] = k++;
		}
	}

	double L = 0.0, R = 1000005;

	int itr = 60;
	while(itr--){
		double mid = (L + R) / 2;

		if(check(mid))L = mid;
		else R = mid;
	}

	printf("%.15f\n", L * x);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXN = 55;

int n, m, x, ai, bi, ci;
double H[MAXN][MAXN], G[MAXN][MAXN];

bool vis[MAXN];
bool dfs(int u, double xi){
	vis[u] = true;
	if(u == n - 1)return true;

	for(int v = 0; v < n; v++)if(G[u][v] >= xi){
		if(vis[v])continue;

		if(dfs(v, xi)){
			G[u][v] -= xi;
			G[v][u] += xi;
			return true;
		}
	}
	return false;
}

bool check(double mid){
	memcpy(G, H, sizeof H);

	int k = x;
	while(k--){
		memset(vis, false, sizeof vis);
		if(!dfs(0, mid))return false;

	}
	return true;
}
int main(){
	scanf("%d %d %d", &n, &m, &x);
	for(int i = 0; i < m; i++){
		scanf("%d %d %d", &ai, &bi, &ci);
		ai--, bi--;

		H[ai][bi] += ci;
	}

	double L = 0.0, R = 1000005;

	int itr = 50;
	while(itr--){
		double mid = (L + R) / 2;

		if(check(mid))L = mid;
		else R = mid;
	}

	printf("%.15f\n", L * x);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXN = 55;
const int MAXM = 1005;

int n, m, x, ai, bi, ci;

double w[MAXM], cw[MAXM];
int to[MAXM], opp[MAXM];
vector <int> G[MAXN];

bool vis[MAXN];
bool dfs(int u, double xi){
	vis[u] = true;
	if(u == n - 1)return true;

	for(int i : G[u])if(cw[i] >= xi){
		int v = to[i];
		if(vis[v])continue;

		if(dfs(v, xi)){
			cw[i] -= xi;
			cw[opp[i]] += xi;
			return true;
		}
	}
	return false;
}

bool check(double mid){
	memcpy(cw, w, sizeof w);

	int k = x;
	while(k--){
		memset(vis, false, sizeof vis);
		if(!dfs(0, mid))return false;
	}
	return true;
}
int main(){
	scanf("%d %d %d", &n, &m, &x);

	map < pair <int, int>, int> mp;
	int k = 0;

	for(int i = 0; i < m; i++){
		scanf("%d %d %d", &ai, &bi, &ci);
		ai--, bi--;

		if(mp.count({ai, bi}))w[mp[{ai, bi}]] += ci;
		else{
			w[k] += ci;

			G[ai].push_back(k);
			to[k] = bi;
			opp[k] = k + 1;
			mp[{ai, bi}] = k++;

			G[bi].push_back(k);
			to[k] = ai;
			opp[k] = k - 1;
			mp[{bi, ai}] = k++;
		}
	}

	double L = 0.0, R = 1000005;

	int itr = 50;
	while(itr--){
		double mid = (L + R) / 2;

		if(check(mid))L = mid;
		else R = mid;
	}

	printf("%.15f\n", L * x);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXN = 55;
const int MAXM = 505;

int n, m, x, ai, bi, ci;

double w[MAXM], cw[MAXM];
int to[MAXM], opp[MAXM];
vector <int> G[MAXN];

bool vis[MAXN];
bool dfs(int u, double xi){
	vis[u] = true;
	if(u == n - 1)return true;

	for(int i : G[u])if(cw[i] >= xi){
		int v = to[i];
		if(vis[v])continue;

		if(dfs(v, xi)){
			cw[i] -= xi;
			cw[opp[i]] += xi;
			return true;
		}
	}
	return false;
}

bool check(double mid){
	memcpy(cw, w, sizeof w);

	int k = x;
	while(k--){
		memset(vis, false, sizeof vis);
		if(!dfs(0, mid))return false;
	}
	return true;
}
int main(){
	scanf("%d %d %d", &n, &m, &x);

	map < pair <int, int>, int> mp;
	int k = 0;

	for(int i = 0; i < m; i++){
		scanf("%d %d %d", &ai, &bi, &ci);
		ai--, bi--;

		if(mp.count({ai, bi}))w[mp[{ai, bi}]] += ci;
		else{
			w[k] += ci;

			G[ai].push_back(k);
			to[k] = bi;
			opp[k] = k + 1;
			mp[{ai, bi}] = k++;

			G[bi].push_back(k);
			to[k] = ai;
			opp[k] = k - 1;
			mp[{bi, ai}] = k++;
		}
	}

	double L = 0.0, R = 1000005;

	int itr = 50;
	while(itr--){
		double mid = (L + R) / 2;

		if(check(mid))L = mid;
		else R = mid;
	}

	printf("%.15f\n", L * x);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXN = 55;

int n, m, x, ai, bi, ci;
double H[MAXN][MAXN], G[MAXN][MAXN];

bool vis[MAXN];
bool dfs(int u, double xi){
	vis[u] = true;
	if(u == n - 1)return true;

	for(int v = 0; v < n; v++)if(G[u][v] >= xi){
		if(vis[v])continue;

		if(dfs(v, xi)){
			G[u][v] -= xi;
			G[v][u] += xi;
			return true;
		}
	}
	return false;
}

bool check(double mid){
	memcpy(G, H, sizeof H);

	int k = x;
	while(k--){
		memset(vis, false, sizeof vis);
		if(!dfs(0, mid))return false;

	}
	return true;
}
int main(){
	scanf("%d %d %d", &n, &m, &x);
	for(int i = 0; i < m; i++){
		scanf("%d %d %d", &ai, &bi, &ci);
		ai--, bi--;

		H[ai][bi] += ci;
	}

	double L = 0.0, R = 1000005;

	int itr = 200;
	while(itr--){
		double mid = (L + R) / 2;

		if(check(mid))L = mid;
		else R = mid;
	}

	printf("%.15f\n", L * x);

	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")

typedef long long ll;

using namespace std;

const int N = 503, M = 1e5 + 3, BIG = 1e9 + 3, MOD = 1e9 + 7, P = 'z' - 'a' + 1;
const double PI = 3.14159265359;

//mt19937 gen(time(NULL));

struct Edge{
	int to, w, c;
	Edge* rev;
	Edge(int t, int ww, int cc) {
		to = t, w = ww, c = cc;
		rev = nullptr;
	}
};

int n, x, st, fin;
vector<vector<Edge*>> gr, gr2;
vector<bool> used;

void new_edge(int fr, int to, int c, vector<vector<Edge*>> &gr_now) {
	gr_now[fr].push_back(new Edge(to, 0, c));
	gr_now[to].push_back(new Edge(fr, 0, 0));
	gr_now[fr].back()->rev = gr_now[to].back();
	gr_now[to].back()->rev = gr_now[fr].back();
}

int dfs(int v, int d) {
	if (v == fin || d == 0)
		return d;
	used[v] = true;
	for (auto &e : gr[v]) {
		if (used[e->to])
			continue;
		int d2 = min(d, dfs(e->to, min(d, e->c - e->w)));
		if (d2 > 0) {
			e->w += d2;
			e->rev->w -= d2;
			return d2;
		}
	}
	return 0;
}

void out_gr(){
	for (int i = 0; i < gr.size(); ++i) {
		cout << i + 1 << " : ";
		for (auto &e : gr[i])
			cout << e->to + 1 << " " << e->w << " " << e->c << ", ";
		cout << "\n";
	}
	cout << endl;
}

bool ok(double bear_w) {
	// cout << bear_w << endl;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < gr[i].size(); ++j) {
			gr[i][j]->c = (double)gr2[i][j]->c / bear_w;
			gr[i][j]->w = 0;
		}
	// out_gr();
	while(true) {
		// cout << "try" << endl;
		used.assign(n, false);
		if (dfs(st, BIG) == 0)
			break;
	}
	int num = 0;
	for (auto &e : gr[st])
		num += e->w;
	// cout << "ans is " << num << endl;
	return num >= x;
}

int main () {
	// freopen("a.in", "r", stdin), freopen("a.out", "w", stdout);
	// freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cout << setprecision(13) << fixed;
	int m, fr, to, c;
	cin >> n >> m >> x;
	st = 0, fin = n - 1;
	gr.resize(n);
	gr2.resize(n);
	for (int i = 0; i < m; ++i) {
		cin >> fr >> to >> c, --fr, --to;
		new_edge(fr, to, c, gr);
		new_edge(fr, to, c, gr2);
	}
	// cout << "ok" << endl;
	double L = 0, R = 1e9, mid;
	for (int i = 0; i < 1e4; ++i) {
		mid = (L + R) / 2;
		if (ok(mid))
			L = mid;
		else
			R = mid;
	}
	cout << L * x;
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")

typedef long long ll;

using namespace std;

const int N = 503, M = 1e5 + 3, BIG = 1e9 + 3, MOD = 1e9 + 7, P = 'z' - 'a' + 1;
const double PI = 3.14159265359;

//mt19937 gen(time(NULL));

struct Edge{
	ll to, w, c;
	Edge* rev;
	Edge(ll t, ll ww, ll cc) {
		to = t, w = ww, c = cc;
		rev = nullptr;
	}
};

ll n, x, st, fin;
vector<vector<Edge*>> gr, gr2;
vector<bool> used;

void new_edge(ll fr, ll to, ll c, vector<vector<Edge*>> &gr_now) {
	gr_now[fr].push_back(new Edge(to, 0, c));
	gr_now[to].push_back(new Edge(fr, 0, 0));
	gr_now[fr].back()->rev = gr_now[to].back();
	gr_now[to].back()->rev = gr_now[fr].back();
}

ll dfs(ll v, ll d) {
	if (v == fin || d == 0)
		return d;
	used[v] = true;
	for (auto &e : gr[v]) {
		if (used[e->to])
			continue;
		ll d2 = min(d, dfs(e->to, min(d, e->c - e->w)));
		if (d2 > 0) {
			e->w += d2;
			e->rev->w -= d2;
			return d2;
		}
	}
	return 0;
}

void out_gr(){
	for (int i = 0; i < gr.size(); ++i) {
		cout << i + 1 << " : ";
		for (auto &e : gr[i])
			cout << e->to + 1 << " " << e->w << " " << e->c << ", ";
		cout << "\n";
	}
	cout << endl;
}

bool ok(double bear_w) {
	// cout << bear_w << endl;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < gr[i].size(); ++j) {
			gr[i][j]->c = (double)gr2[i][j]->c / bear_w;
			gr[i][j]->w = 0;
		}
	// out_gr();
	while(true) {
		// cout << "try" << endl;
		used.assign(n, false);
		if (dfs(st, BIG) == 0)
			break;
	}
	ll num = 0;
	for (auto &e : gr[st])
		num += e->w;
	// cout << "ans is " << num << endl;
	return num >= x;
}

int main () {
	// freopen("a.in", "r", stdin), freopen("a.out", "w", stdout);
	// freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cout << setprecision(13) << fixed;
	int m, fr, to, c;
	cin >> n >> m >> x;
	st = 0, fin = n - 1;
	gr.resize(n);
	gr2.resize(n);
	for (int i = 0; i < m; ++i) {
		cin >> fr >> to >> c, --fr, --to;
		new_edge(fr, to, c, gr);
		new_edge(fr, to, c, gr2);
	}
	// cout << "ok" << endl;
	double L = 0, R = 1e9, mid;
	for (int i = 0; i < 2e3; ++i) {
		mid = (L + R) / 2;
		if (ok(mid))
			L = mid;
		else
			R = mid;
	}
	cout << L * x;
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")

typedef long long ll;

using namespace std;

const int N = 503, M = 1e5 + 3, BIG = 1e9 + 3, MOD = 1e9 + 7, P = 'z' - 'a' + 1;
const double PI = 3.14159265359;

//mt19937 gen(time(NULL));

struct Edge{
	ll to, w, c;
	Edge* rev;
	Edge(ll t, ll ww, ll cc) {
		to = t, w = ww, c = cc;
		rev = nullptr;
	}
};

ll n, x, st, fin;
vector<vector<Edge*>> gr, gr2;
vector<bool> used;

void new_edge(ll fr, ll to, ll c, vector<vector<Edge*>> &gr_now) {
	gr_now[fr].push_back(new Edge(to, 0, c));
	gr_now[to].push_back(new Edge(fr, 0, 0));
	gr_now[fr].back()->rev = gr_now[to].back();
	gr_now[to].back()->rev = gr_now[fr].back();
}

ll dfs(ll v, ll d) {
	if (v == fin || d == 0)
		return d;
	used[v] = true;
	for (auto &e : gr[v]) {
		if (used[e->to])
			continue;
		ll d2 = min(d, dfs(e->to, min(d, e->c - e->w)));
		if (d2 > 0) {
			e->w += d2;
			e->rev->w -= d2;
			return d2;
		}
	}
	return 0;
}

void out_gr(){
	for (int i = 0; i < gr.size(); ++i) {
		cout << i + 1 << " : ";
		for (auto &e : gr[i])
			cout << e->to + 1 << " " << e->w << " " << e->c << ", ";
		cout << "\n";
	}
	cout << endl;
}

bool ok(double bear_w) {
	// cout << bear_w << endl;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < gr[i].size(); ++j) {
			gr[i][j]->c = (double)gr2[i][j]->c / bear_w;
			gr[i][j]->w = 0;
		}
	// out_gr();
	while(true) {
		// cout << "try" << endl;
		used.assign(n, false);
		if (dfs(st, BIG) == 0)
			break;
	}
	ll num = 0;
	for (auto &e : gr[st])
		num += e->w;
	// cout << "ans is " << num << endl;
	return num >= x;
}

int main () {
	// freopen("a.in", "r", stdin), freopen("a.out", "w", stdout);
	// freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cout << setprecision(13) << fixed;
	int m, fr, to, c;
	cin >> n >> m >> x;
	st = 0, fin = n - 1;
	gr.resize(n);
	gr2.resize(n);
	for (int i = 0; i < m; ++i) {
		cin >> fr >> to >> c, --fr, --to;
		new_edge(fr, to, c, gr);
		new_edge(fr, to, c, gr2);
	}
	// cout << "ok" << endl;
	double L = 0, R = 1e9, mid;
	for (int i = 0; i < 1e3; ++i) {
		mid = (L + R) / 2;
		if (ok(mid))
			L = mid;
		else
			R = mid;
	}
	cout << L * x;
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")

typedef long long ll;

using namespace std;

const int N = 503, M = 1e5 + 3, BIG = 1e9 + 3, MOD = 1e9 + 7, P = 'z' - 'a' + 1;
const double PI = 3.14159265359;

//mt19937 gen(time(NULL));

struct Edge{
	int to, w, c;
	Edge* rev;
	Edge(int t, int ww, int cc) {
		to = t, w = ww, c = cc;
		rev = nullptr;
	}
};

int n, x, st, fin;
vector<vector<Edge*>> gr, gr2;
vector<bool> used;

void new_edge(int fr, int to, int c, vector<vector<Edge*>> &gr_now) {
	gr_now[fr].push_back(new Edge(to, 0, c));
	gr_now[to].push_back(new Edge(fr, 0, 0));
	gr_now[fr].back()->rev = gr_now[to].back();
	gr_now[to].back()->rev = gr_now[fr].back();
}

int dfs(int v, int d) {
	if (v == fin || d == 0)
		return d;
	used[v] = true;
	for (auto &e : gr[v]) {
		if (used[e->to])
			continue;
		int d2 = min(d, dfs(e->to, min(d, e->c - e->w)));
		if (d2 > 0) {
			e->w += d2;
			e->rev->w -= d2;
			return d2;
		}
	}
	return 0;
}

void out_gr(){
	for (int i = 0; i < gr.size(); ++i) {
		cout << i + 1 << " : ";
		for (auto &e : gr[i])
			cout << e->to + 1 << " " << e->w << " " << e->c << ", ";
		cout << "\n";
	}
	cout << endl;
}

bool ok(double bear_w) {
	// cout << bear_w << endl;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < gr[i].size(); ++j) {
			gr[i][j]->c = (double)gr2[i][j]->c / bear_w;
			gr[i][j]->w = 0;
		}
	// out_gr();
	while(true) {
		// cout << "try" << endl;
		used.assign(n, false);
		if (dfs(st, BIG) == 0)
			break;
	}
	int num = 0;
	for (auto &e : gr[st])
		num += e->w;
	// cout << "ans is " << num << endl;
	return num >= x;
}

int main () {
	// freopen("a.in", "r", stdin), freopen("a.out", "w", stdout);
	// freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cout << setprecision(13) << fixed;
	int m, fr, to, c;
	cin >> n >> m >> x;
	st = 0, fin = n - 1;
	gr.resize(n);
	gr2.resize(n);
	for (int i = 0; i < m; ++i) {
		cin >> fr >> to >> c, --fr, --to;
		new_edge(fr, to, c, gr);
		new_edge(fr, to, c, gr2);
	}
	// cout << "ok" << endl;
	double L = 0, R = 20, mid;
	for (int i = 0; i < 20; ++i) {
		mid = (L + R) / 2;
		if (ok(mid))
			L = mid;
		else
			R = mid;
	}
	cout << L * x;
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")

typedef long long ll;

using namespace std;

const int N = 503, M = 1e5 + 3, BIG = 1e9 + 3, MOD = 1e9 + 7, P = 'z' - 'a' + 1;
const double PI = 3.14159265359;

//mt19937 gen(time(NULL));

struct Edge{
	int to, w, c;
	Edge* rev;
	Edge(int t, int ww, int cc) {
		to = t, w = ww, c = cc;
		rev = nullptr;
	}
};

int n, x, st, fin;
vector<vector<Edge*>> gr, gr2;
vector<bool> used;

void new_edge(int fr, int to, int c, vector<vector<Edge*>> &gr_now) {
	gr_now[fr].push_back(new Edge(to, 0, c));
	gr_now[to].push_back(new Edge(fr, 0, 0));
	gr_now[fr].back()->rev = gr_now[to].back();
	gr_now[to].back()->rev = gr_now[fr].back();
}

int dfs(int v, int d) {
	if (v == fin || d == 0)
		return d;
	used[v] = true;
	for (auto &e : gr[v]) {
		if (used[e->to])
			continue;
		int d2 = min(d, dfs(e->to, min(d, e->c - e->w)));
		if (d2 > 0) {
			e->w += d2;
			e->rev->w -= d2;
			return d2;
		}
	}
	return 0;
}

void out_gr(){
	for (int i = 0; i < gr.size(); ++i) {
		cout << i + 1 << " : ";
		for (auto &e : gr[i])
			cout << e->to + 1 << " " << e->w << " " << e->c << ", ";
		cout << "\n";
	}
	cout << endl;
}

bool ok(double bear_w) {
	// cout << bear_w << endl;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < gr[i].size(); ++j) {
			gr[i][j]->c = (double)gr2[i][j]->c / bear_w;
			gr[i][j]->w = 0;
		}
	// out_gr();
	while(true) {
		// cout << "try" << endl;
		used.assign(n, false);
		if (dfs(st, BIG) == 0)
			break;
	}
	int num = 0;
	for (auto &e : gr[st])
		num += e->w;
	// cout << "ans is " << num << endl;
	return num >= x;
}

int main () {
	// freopen("a.in", "r", stdin), freopen("a.out", "w", stdout);
	// freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cout << setprecision(13) << fixed;
	int m, fr, to, c;
	cin >> n >> m >> x;
	st = 0, fin = n - 1;
	gr.resize(n);
	gr2.resize(n);
	for (int i = 0; i < m; ++i) {
		cin >> fr >> to >> c, --fr, --to;
		new_edge(fr, to, c, gr);
		new_edge(fr, to, c, gr2);
	}
	// cout << "ok" << endl;
	double L = 0, R = 1e7, mid;
	for (int i = 0; i < 1e3; ++i) {
		mid = (L + R) / 2;
		if (ok(mid))
			L = mid;
		else
			R = mid;
	}
	cout << L * x;
	return 0;
}


// Aggressive Play

#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
using namespace std;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

const int MAXN = 5e1 + 5;  // change for changing size of graph
const ll INF = 1e12;    // see this for ll and int shit

struct maxFlow{
    vector<pair<int, int> > e[MAXN];
    vector<ll> cap[MAXN];
    int level[MAXN];
    int nxt[MAXN];
    int s, t;   // source, destination
    int N;  // number of nodes

    queue<int> q;

    void init(int n){   // look out for 0 based and 1 based indexing [for 1 based do <= N everywhere, or simply do N++]
        N = n;
        for(int i = 0; i < N; i++)
            e[i].clear(), cap[i].clear();
    }

    void addEdge(int x, int y, ll cxy, ll cyx){   // note that e[x][y] will not be edge corresponding to edge between node x and node y, same goes for cap[x][y]
        e[x].push_back({y, cap[y].size()}); // the second value basically tells ki x, y mein kahaan pada hai
        e[y].push_back({x, cap[x].size()}); // the second value basically tells ki y, x mein kahaan pada hai
        cap[x].push_back(cxy);
        cap[y].push_back(cyx);
    }

    bool bfs(){ // return 1 if there's a path from s to t, also, set the level graph
        while(!q.empty())
            q.pop();

        for(int i = 0; i < N; i++) level[i] = -1;

        level[s] = 0;
        q.push(s);

        while(!q.empty()){
            int p = q.front();
            q.pop();
            if(p == t)
                return true;

            for(int i = 0; i < (int)e[p].size(); i++){
                int x = e[p][i].F;
                if(level[x] == -1 && cap[p][i] != 0){   // cap[p][i] is capacity of edge p - x, it's just that it's stored at index i in vector cap[p]
                    level[x] = level[p] + 1;
                    q.push(x);
                }
            }
        }
        return false;
    }

    ll augment(int x, ll c){
        if(x == t)
            return c;
        for(int &i = nxt[x]; i < (int)e[x].size(); i++){    // notice the use of &i [used for pruning]
            int y = e[x][i].F;
            if(cap[x][i] > 0 && level[y] == level[x] + 1){
                ll tempFlow = augment(y, min(c, cap[x][i]));
                if(tempFlow > 0){
                    cap[x][i] -= tempFlow;
                    cap[y][e[x][i].S] += tempFlow;  // e[x][i].S is the position where edge y - x is stored in vector of y
                    return tempFlow;
                }
            }
        }
        return 0;
    }

    ll solve(int source, int sink){
        s = source, t = sink;
        ll ans = 0;
        while(bfs()){   // setting level graph
            ll flow = 0;
            for(int i = 0; i < N; i++) // important for pruning
                nxt[i] = 0;
            while(flow = augment(s, INF))   // keep sending flow till wer're finding an augmented path
                ans += flow;
        }
        return ans;
    }
};
ll n, m, x;
vector<pair<int, pair<int, int> > > edges;
bool calc(double mid){
    maxFlow flowGraph;
    flowGraph.init(n);
    for(auto i : edges){
        int a = i.F, b = i.S.F;
        double weight = i.S.S;
        a--, b--;
        weight /= mid;
        flowGraph.addEdge(a, b, (ll)weight, 0);
    }
    return(flowGraph.solve(0, n - 1) >= x);
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m >> x;
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        edges.push_back({a, {b, c}});
    }
    double lo = 0, hi = 1e18;
    for(int i = 0; i < 50; i++){
        double mid = (hi + lo) / 2.0;
        if(calc(mid))
            lo = mid;
        else hi = mid;
    }
    cout << fixed << setprecision(12) << (lo * 1.0 * x);
return 0;
}


// Aggressive Play

#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
using namespace std;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

const int MAXN = 5e1 + 5;  // change for changing size of graph
const ll INF = 1e12;    // see this for ll and int shit

struct maxFlow{
    vector<pair<int, int> > e[MAXN];
    vector<ll> cap[MAXN];
    int level[MAXN];
    int nxt[MAXN];
    int s, t;   // source, destination
    int N;  // number of nodes

    queue<int> q;

    void init(int n){   // look out for 0 based and 1 based indexing [for 1 based do <= N everywhere, or simply do N++]
        N = n;
        for(int i = 0; i < N; i++)
            e[i].clear(), cap[i].clear();
    }

    void addEdge(int x, int y, ll cxy, ll cyx){   // note that e[x][y] will not be edge corresponding to edge between node x and node y, same goes for cap[x][y]
        e[x].push_back({y, cap[y].size()}); // the second value basically tells ki x, y mein kahaan pada hai
        e[y].push_back({x, cap[x].size()}); // the second value basically tells ki y, x mein kahaan pada hai
        cap[x].push_back(cxy);
        cap[y].push_back(cyx);
    }

    bool bfs(){ // return 1 if there's a path from s to t, also, set the level graph
        while(!q.empty())
            q.pop();

        for(int i = 0; i < N; i++) level[i] = -1;

        level[s] = 0;
        q.push(s);

        while(!q.empty()){
            int p = q.front();
            q.pop();
            if(p == t)
                return true;

            for(int i = 0; i < (int)e[p].size(); i++){
                int x = e[p][i].F;
                if(level[x] == -1 && cap[p][i] != 0){   // cap[p][i] is capacity of edge p - x, it's just that it's stored at index i in vector cap[p]
                    level[x] = level[p] + 1;
                    q.push(x);
                }
            }
        }
        return false;
    }

    ll augment(int x, ll c){
        if(x == t)
            return c;
        for(int &i = nxt[x]; i < (int)e[x].size(); i++){    // notice the use of &i [used for pruning]
            int y = e[x][i].F;
            if(cap[x][i] > 0 && level[y] == level[x] + 1){
                ll tempFlow = augment(y, min(c, cap[x][i]));
                if(tempFlow > 0){
                    cap[x][i] -= tempFlow;
                    cap[y][e[x][i].S] += tempFlow;  // e[x][i].S is the position where edge y - x is stored in vector of y
                    return tempFlow;
                }
            }
        }
        return 0;
    }

    ll solve(int source, int sink){
        s = source, t = sink;
        ll ans = 0;
        while(bfs()){   // setting level graph
            ll flow = 0;
            for(int i = 0; i < N; i++) // important for pruning
                nxt[i] = 0;
            while(flow = augment(s, INF))   // keep sending flow till wer're finding an augmented path
                ans += flow;
        }
        return ans;
    }
};
ll n, m, x;
vector<pair<int, pair<int, int> > > edges;
bool calc(double mid){
    maxFlow flowGraph;
    flowGraph.init(n);
    for(auto i : edges){
        int a = i.F, b = i.S.F;
        double weight = i.S.S;
        a--, b--;
        weight /= mid;
        flowGraph.addEdge(a, b, (ll)weight, 0);
    }
    return(flowGraph.solve(0, n - 1) >= x);
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m >> x;
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        edges.push_back({a, {b, c}});
    }
    double lo = 0, hi = 1e18;
    for(int i = 0; i < 90; i++){
        double mid = (hi + lo) / 2.0;
        if(calc(mid))
            lo = mid;
        else hi = mid;
    }
    cout << fixed << setprecision(12) << (lo * 1.0 * x);
return 0;
}


// Aggressive Play

#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
using namespace std;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

const int MAXN = 5e1 + 5;  // change for changing size of graph
const ll INF = 1e12;    // see this for ll and int shit

struct maxFlow{
    vector<pair<int, int> > e[MAXN];
    vector<ll> cap[MAXN];
    int level[MAXN];
    int nxt[MAXN];
    int s, t;   // source, destination
    int N;  // number of nodes

    queue<int> q;

    void init(int n){   // look out for 0 based and 1 based indexing [for 1 based do <= N everywhere, or simply do N++]
        N = n;
        for(int i = 0; i < N; i++)
            e[i].clear(), cap[i].clear();
    }

    void addEdge(int x, int y, ll cxy, ll cyx){   // note that e[x][y] will not be edge corresponding to edge between node x and node y, same goes for cap[x][y]
        e[x].push_back({y, cap[y].size()}); // the second value basically tells ki x, y mein kahaan pada hai
        e[y].push_back({x, cap[x].size()}); // the second value basically tells ki y, x mein kahaan pada hai
        cap[x].push_back(cxy);
        cap[y].push_back(cyx);
    }

    bool bfs(){ // return 1 if there's a path from s to t, also, set the level graph
        while(!q.empty())
            q.pop();

        for(int i = 0; i < N; i++) level[i] = -1;

        level[s] = 0;
        q.push(s);

        while(!q.empty()){
            int p = q.front();
            q.pop();
            if(p == t)
                return true;

            for(int i = 0; i < (int)e[p].size(); i++){
                int x = e[p][i].F;
                if(level[x] == -1 && cap[p][i] != 0){   // cap[p][i] is capacity of edge p - x, it's just that it's stored at index i in vector cap[p]
                    level[x] = level[p] + 1;
                    q.push(x);
                }
            }
        }
        return false;
    }

    ll augment(int x, ll c){
        if(x == t)
            return c;
        for(int &i = nxt[x]; i < (int)e[x].size(); i++){    // notice the use of &i [used for pruning]
            int y = e[x][i].F;
            if(cap[x][i] > 0 && level[y] == level[x] + 1){
                ll tempFlow = augment(y, min(c, cap[x][i]));
                if(tempFlow > 0){
                    cap[x][i] -= tempFlow;
                    cap[y][e[x][i].S] += tempFlow;  // e[x][i].S is the position where edge y - x is stored in vector of y
                    return tempFlow;
                }
            }
        }
        return 0;
    }

    ll solve(int source, int sink){
        s = source, t = sink;
        ll ans = 0;
        while(bfs()){   // setting level graph
            ll flow = 0;
            for(int i = 0; i < N; i++) // important for pruning
                nxt[i] = 0;
            while(flow = augment(s, INF))   // keep sending flow till wer're finding an augmented path
                ans += flow;
        }
        return ans;
    }
};
ll n, m, x;
vector<pair<int, pair<int, int> > > edges;
bool calc(double mid){
    maxFlow flowGraph;
    flowGraph.init(n);
    for(auto i : edges){
        int a = i.F, b = i.S.F;
        double weight = i.S.S;
        a--, b--;
        weight /= mid;
        flowGraph.addEdge(a, b, (ll)weight, 0);
    }
    return(flowGraph.solve(0, n - 1) >= x);
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m >> x;
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        edges.push_back({a, {b, c}});
    }
    double lo = 0, hi = 1e15;
    for(int i = 0; i < 150; i++){
        double mid = (hi + lo) / 2.0;
        if(calc(mid))
            lo = mid;
        else hi = mid;
    }
    cout << fixed << setprecision(12) << (lo * 1.0 * x);
return 0;
}


// Aggressive Play

#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
using namespace std;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

const int MAXN = 5e1 + 5;  // change for changing size of graph
const ll INF = 1e12;    // see this for ll and int shit

struct maxFlow{
    vector<pair<int, int> > e[MAXN];
    vector<ll> cap[MAXN];
    int level[MAXN];
    int nxt[MAXN];
    int s, t;   // source, destination
    int N;  // number of nodes

    queue<int> q;

    void init(int n){   // look out for 0 based and 1 based indexing [for 1 based do <= N everywhere, or simply do N++]
        N = n;
        for(int i = 0; i < N; i++)
            e[i].clear(), cap[i].clear();
    }

    void addEdge(int x, int y, ll cxy, ll cyx){   // note that e[x][y] will not be edge corresponding to edge between node x and node y, same goes for cap[x][y]
        e[x].push_back({y, cap[y].size()}); // the second value basically tells ki x, y mein kahaan pada hai
        e[y].push_back({x, cap[x].size()}); // the second value basically tells ki y, x mein kahaan pada hai
        cap[x].push_back(cxy);
        cap[y].push_back(cyx);
    }

    bool bfs(){ // return 1 if there's a path from s to t, also, set the level graph
        while(!q.empty())
            q.pop();

        for(int i = 0; i < N; i++) level[i] = -1;

        level[s] = 0;
        q.push(s);

        while(!q.empty()){
            int p = q.front();
            q.pop();
            if(p == t)
                return true;

            for(int i = 0; i < (int)e[p].size(); i++){
                int x = e[p][i].F;
                if(level[x] == -1 && cap[p][i] != 0){   // cap[p][i] is capacity of edge p - x, it's just that it's stored at index i in vector cap[p]
                    level[x] = level[p] + 1;
                    q.push(x);
                }
            }
        }
        return false;
    }

    ll augment(int x, ll c){
        if(x == t)
            return c;
        for(int &i = nxt[x]; i < (int)e[x].size(); i++){    // notice the use of &i [used for pruning]
            int y = e[x][i].F;
            if(cap[x][i] > 0 && level[y] == level[x] + 1){
                ll tempFlow = augment(y, min(c, cap[x][i]));
                if(tempFlow > 0){
                    cap[x][i] -= tempFlow;
                    cap[y][e[x][i].S] += tempFlow;  // e[x][i].S is the position where edge y - x is stored in vector of y
                    return tempFlow;
                }
            }
        }
        return 0;
    }

    ll solve(int source, int sink){
        s = source, t = sink;
        ll ans = 0;
        while(bfs()){   // setting level graph
            ll flow = 0;
            for(int i = 0; i < N; i++) // important for pruning
                nxt[i] = 0;
            while(flow = augment(s, INF))   // keep sending flow till wer're finding an augmented path
                ans += flow;
        }
        return ans;
    }
};
ll n, m, x;
vector<pair<int, pair<int, int> > > edges;
bool calc(double mid){
    maxFlow flowGraph;
    flowGraph.init(n);
    for(auto i : edges){
        int a = i.F, b = i.S.F;
        double weight = i.S.S;
        a--, b--;
        weight /= mid;
        flowGraph.addEdge(a, b, (ll)weight, 0);
    }
    return(flowGraph.solve(0, n - 1) >= x);
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m >> x;
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        edges.push_back({a, {b, c}});
    }
    double lo = 0, hi = 1e15;
    for(int i = 0; i < 90; i++){
        double mid = (hi + lo) / 2.0;
        if(calc(mid))
            lo = mid;
        else hi = mid;
    }
    cout << fixed << setprecision(12) << (lo * 1.0 * x);
return 0;
}


// Aggressive Play

#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
using namespace std;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

const int MAXN = 5e1 + 5;  // change for changing size of graph
const ll INF = 1e12;    // see this for ll and int shit

struct maxFlow{
    vector<pair<int, int> > e[MAXN];
    vector<ll> cap[MAXN];
    int level[MAXN];
    int nxt[MAXN];
    int s, t;   // source, destination
    int N;  // number of nodes

    queue<int> q;

    void init(int n){   // look out for 0 based and 1 based indexing [for 1 based do <= N everywhere, or simply do N++]
        N = n;
        for(int i = 0; i < N; i++)
            e[i].clear(), cap[i].clear();
    }

    void addEdge(int x, int y, ll cxy, ll cyx){   // note that e[x][y] will not be edge corresponding to edge between node x and node y, same goes for cap[x][y]
        e[x].push_back({y, cap[y].size()}); // the second value basically tells ki x, y mein kahaan pada hai
        e[y].push_back({x, cap[x].size()}); // the second value basically tells ki y, x mein kahaan pada hai
        cap[x].push_back(cxy);
        cap[y].push_back(cyx);
    }

    bool bfs(){ // return 1 if there's a path from s to t, also, set the level graph
        while(!q.empty())
            q.pop();

        for(int i = 0; i < N; i++) level[i] = -1;

        level[s] = 0;
        q.push(s);

        while(!q.empty()){
            int p = q.front();
            q.pop();
            if(p == t)
                return true;

            for(int i = 0; i < (int)e[p].size(); i++){
                int x = e[p][i].F;
                if(level[x] == -1 && cap[p][i] != 0){   // cap[p][i] is capacity of edge p - x, it's just that it's stored at index i in vector cap[p]
                    level[x] = level[p] + 1;
                    q.push(x);
                }
            }
        }
        return false;
    }

    ll augment(int x, ll c){
        if(x == t)
            return c;
        for(int &i = nxt[x]; i < (int)e[x].size(); i++){    // notice the use of &i [used for pruning]
            int y = e[x][i].F;
            if(cap[x][i] > 0 && level[y] == level[x] + 1){
                ll tempFlow = augment(y, min(c, cap[x][i]));
                if(tempFlow > 0){
                    cap[x][i] -= tempFlow;
                    cap[y][e[x][i].S] += tempFlow;  // e[x][i].S is the position where edge y - x is stored in vector of y
                    return tempFlow;
                }
            }
        }
        return 0;
    }

    ll solve(int source, int sink){
        s = source, t = sink;
        ll ans = 0;
        while(bfs()){   // setting level graph
            ll flow = 0;
            for(int i = 0; i < N; i++) // important for pruning
                nxt[i] = 0;
            while(flow = augment(s, INF))   // keep sending flow till wer're finding an augmented path
                ans += flow;
        }
        return ans;
    }
};
ll n, m, x;
vector<pair<int, pair<int, int> > > edges;
bool calc(double mid){
    maxFlow flowGraph;
    flowGraph.init(n);
    for(auto i : edges){
        int a = i.F, b = i.S.F;
        double weight = i.S.S;
        a--, b--;
        weight /= mid;
        flowGraph.addEdge(a, b, (ll)weight, 0);
    }
    return(flowGraph.solve(0, n - 1) >= x);
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m >> x;
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        edges.push_back({a, {b, c}});
    }
    double lo = 0, hi = 1e18;
    for(int i = 0; i < 80; i++){
        double mid = (hi + lo) / 2.0;
        if(calc(mid))
            lo = mid;
        else hi = mid;
    }
    cout << fixed << setprecision(12) << (lo * 1.0 * x);
return 0;
}


// Aggressive Play

#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
using namespace std;

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

const int MAXN = 5e1 + 5;  // change for changing size of graph
const ll INF = 1e12;    // see this for ll and int shit

struct maxFlow{
    vector<pair<int, int> > e[MAXN];
    vector<ll> cap[MAXN];
    int level[MAXN];
    int nxt[MAXN];
    int s, t;   // source, destination
    int N;  // number of nodes

    queue<int> q;

    void init(int n){   // look out for 0 based and 1 based indexing [for 1 based do <= N everywhere, or simply do N++]
        N = n;
        for(int i = 0; i < N; i++)
            e[i].clear(), cap[i].clear();
    }

    void addEdge(int x, int y, ll cxy, ll cyx){   // note that e[x][y] will not be edge corresponding to edge between node x and node y, same goes for cap[x][y]
        e[x].push_back({y, cap[y].size()}); // the second value basically tells ki x, y mein kahaan pada hai
        e[y].push_back({x, cap[x].size()}); // the second value basically tells ki y, x mein kahaan pada hai
        cap[x].push_back(cxy);
        cap[y].push_back(cyx);
    }

    bool bfs(){ // return 1 if there's a path from s to t, also, set the level graph
        while(!q.empty())
            q.pop();

        for(int i = 0; i < N; i++) level[i] = -1;

        level[s] = 0;
        q.push(s);

        while(!q.empty()){
            int p = q.front();
            q.pop();
            if(p == t)
                return true;

            for(int i = 0; i < (int)e[p].size(); i++){
                int x = e[p][i].F;
                if(level[x] == -1 && cap[p][i] != 0){   // cap[p][i] is capacity of edge p - x, it's just that it's stored at index i in vector cap[p]
                    level[x] = level[p] + 1;
                    q.push(x);
                }
            }
        }
        return false;
    }

    ll augment(int x, ll c){
        if(x == t)
            return c;
        for(int &i = nxt[x]; i < (int)e[x].size(); i++){    // notice the use of &i [used for pruning]
            int y = e[x][i].F;
            if(cap[x][i] > 0 && level[y] == level[x] + 1){
                ll tempFlow = augment(y, min(c, cap[x][i]));
                if(tempFlow > 0){
                    cap[x][i] -= tempFlow;
                    cap[y][e[x][i].S] += tempFlow;  // e[x][i].S is the position where edge y - x is stored in vector of y
                    return tempFlow;
                }
            }
        }
        return 0;
    }

    ll solve(int source, int sink){
        s = source, t = sink;
        ll ans = 0;
        while(bfs()){   // setting level graph
            ll flow = 0;
            for(int i = 0; i < N; i++) // important for pruning
                nxt[i] = 0;
            while(flow = augment(s, INF))   // keep sending flow till wer're finding an augmented path
                ans += flow;
        }
        return ans;
    }
};
ll n, m, x;
vector<pair<int, pair<int, int> > > edges;
bool calc(double mid){
    maxFlow flowGraph;
    flowGraph.init(n);
    for(auto i : edges){
        int a = i.F, b = i.S.F;
        double weight = i.S.S;
        a--, b--;
        weight /= mid;
        flowGraph.addEdge(a, b, (ll)weight, 0);
    }
    return(flowGraph.solve(0, n - 1) >= x);
}
int main()
{
    ios_base ::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m >> x;
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        edges.push_back({a, {b, c}});
    }
    double lo = 0, hi = 1e18;
    for(int i = 0; i < 100; i++){
        double mid = (hi + lo) / 2.0;
        if(calc(mid))
            lo = mid;
        else hi = mid;
    }
    cout << fixed << setprecision(12) << (lo * 1.0 * x);
return 0;
}


import java.util.Scanner;
public class ValeraAndX
{
	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		String sika = "" , chars = "";
                int n = in.nextInt();
		boolean hi = true;
		for(int i = 0;i < n;i++)
		{
			sika = in.next();
			if(i == 0 && !sika.replace("" + sika.charAt(0) , "").isEmpty())
				chars = "[" + sika.substring(0 , 2) + "]";
			hi = !sika.replace("" + sika.charAt(0) , "").isEmpty()
			     && sika.replaceAll(chars , "").isEmpty()
                             && checkPattern(sika , chars , i) && hi;
                }
		System.out.println(hi ? "YES" : "NO");
	}
        public static boolean checkPattern(String sika , String chars , int j)
        {
            boolean hello = true , whatEver = sika.charAt(j) == chars.charAt(1);
            for(int i = 0;i < sika.length()/2 && hello && whatEver;i++)
                if(sika.charAt(i) != sika.charAt(sika.length()-1-i))
                    hello = false;
            return hello && whatEver;
        }
}


import java.util.Scanner;

public class Solution {

	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		String s = in.nextLine();

		char[][] chars = new char[n][];

		for(int i = 0; i < n; i++)
			chars[i] = in.nextLine().toCharArray();
        boolean x = isX(chars);

        if(x)
        	System.out.println("YES");
        else
        	System.out.println("NO");
	}

	public static boolean isX(char[][] chars)
	{
		int i, j;
		char key1 = chars[0][0];
		for(i = 0, j = chars.length - 1; i < chars.length; i++, j--)
		{
			if(chars[i][i] != key1 || chars[i][j] != key1)
				return false;
		}

		char key2 = chars[0][1];
		if(key1 == key2)
			return false;
		for(i = 0; i < chars.length; i++)
			for(j = 0; j < chars.length; j++)
			{
				if(i - j == 0 || Math.abs(i - j) == 1)
					continue;
				else if(chars[i][j] != key2 || chars[i][j] == key1)
					return false;
			}
		return true;
	}

}


import java.util.Scanner;

public class Solution {

	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		String s = in.nextLine();

		char[][] chars = new char[n][];

		for(int i = 0; i < n; i++)
			chars[i] = in.nextLine().toCharArray();
        boolean x = isX(chars);

        if(x)
        	System.out.println("YES");
        else
        	System.out.println("NO");
	}

	public static boolean isX(char[][] chars)
	{
		int i, j, k;
		char key1 = chars[0][0];
		for(i = 0, j = chars.length - 1; i < chars.length; i++, j--)
		{
			if(chars[i][i] != key1 || chars[i][j] != key1)
				return false;
		}

		char key2 = chars[0][1];
		if(key1 == key2)
			return false;
		for(i = 0, k = chars.length; i < chars.length; i++, k--)
			for(j = 0; j < chars.length; j++)
			{
				if(i - j == 0 || k - j == 0)
					continue;
				else if(chars[i][j] != key2 || chars[i][j] == key1)
					return false;
			}
		return true;
	}

}


import java.util.Scanner;

public class Solution {

	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		String s = in.nextLine();

		char[][] chars = new char[n][];

		for(int i = 0; i < n; i++)
			chars[i] = in.nextLine().toCharArray();
        boolean x = isX(chars);

        if(x)
        	System.out.println("YES");
        else
        	System.out.println("NO");
	}

	public static boolean isX(char[][] chars)
	{
		int i, j;
		char key1 = chars[0][0];
		for(i = 0, j = chars.length - 1; i < chars.length; i++, j--)
		{
			if(chars[i][i] != key1 || chars[i][j] != key1)
				return false;
		}

		char key2 = chars[0][1];

		for(i = 0; i < chars.length; i++)
			for(j = 0; j < chars.length; j++)
				if(chars[i][j] != key1)
					if(chars[i][j] != key2)
						return false;

		return true;
	}

}