package main
import (
"fmt"
"os"
)
type Edge struct {
to, cap, flow, rev int
}
var adj [][]Edge
var level []int
var ptr []int
func addEdge(from, to, cap int) {
adj[from] = append(adj[from], Edge{to, cap, 0, len(adj[to])})
adj[to] = append(adj[to], Edge{from, 0, 0, len(adj[from]) - 1})
}
func bfs(s, t int) bool {
for i := range level {
level[i] = -1
}
level[s] = 0
queue := []int{s}
for len(queue) > 0 {
v := queue[0]
queue = queue[1:]
for _, e := range adj[v] {
if e.cap-e.flow > 0 && level[e.to] == -1 {
level[e.to] = level[v] + 1
queue = append(queue, e.to)
}
}
}
return level[t] != -1
}
func dfs(v, t, pushed int) int {
if pushed == 0 {
return 0
}
if v == t {
return pushed
}
for i := ptr[v]; i < len(adj[v]); i++ {
e := adj[v][i]
tr := e.to
if level[v]+1 != level[tr] || e.cap-e.flow == 0 {
ptr[v]++
continue
}
push := dfs(tr, t, min(pushed, e.cap-e.flow))
if push == 0 {
ptr[v]++
continue
}
adj[v][i].flow += push
adj[tr][e.rev].flow -= push
return push
}
return 0
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
type OrigEdge struct {
u, v int
c float64
}
func main() {
var n, m, x int
if _, err := fmt.Fscan(os.Stdin, &n, &m, &x); err != nil {
return
}
edges := make([]OrigEdge, m)
for i := 0; i < m; i++ {
var u, v int
var c float64
fmt.Fscan(os.Stdin, &u, &v, &c)
edges[i] = OrigEdge{u, v, c}
}
level = make([]int, n+1)
ptr = make([]int, n+1)
low := 0.0
high := 1000001.0
for iter := 0; iter < 80; iter++ {
mid := low + (high-low)/2
adj = make([][]Edge, n+1)
for _, e := range edges {
val := e.c / mid
cap := 0
if val > float64(x) {
cap = x
} else {
cap = int(val)
}
if cap > 0 {
addEdge(e.u, e.v, cap)
}
}
flow := 0
for bfs(1, n) {
for i := range ptr {
ptr[i] = 0
}
for {
pushed := dfs(1, n, int(1e9))
if pushed == 0 {
break
}
flow += pushed
}
}
if flow >= x {
low = mid
} else {
high = mid
}
}
fmt.Printf("%.10f\n", float64(x)*low)
}