import std.algorithm;
import std.array;
import std.ascii;
import std.container;
import std.conv;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void log(A...)(A arg) {
    stderr.writeln(arg);
}
int size(T)(in T s) {
    return cast(int)s.length;
}

const INF = 1<<29;

class Graph {
    class Edge {
        int from, to, cap, cost;
        Edge rev;
    }
    int V;
    Edge[][] G;
    Edge[] prevEdge;
    this(int V) {
        this.V = V;
        this.G = new Edge[][V];
        this.prevEdge = new Edge[V];
    }
    void addEdge(int from, int to, int cap, int cost) {
        auto e = new Edge;
        auto r = new Edge;
        e.from = from; e.to = to; e.cap = cap; e.cost = cost; e.rev = r;
        r.from = to; r.to = from; r.cap = 0; r.cost = -cost; r.rev = e;
        G[from] ~= e;
        G[to] ~= r;
    }
    int minCostFlow(int s, int t, int flow) {
        auto potential = new int[V];
        auto D = new int[V];
        int ret = 0;
        alias P = Tuple!(int, "index", int, "dist");
        while (flow > 0) {
            BinaryHeap!(Array!P, "a.dist > b.dist") PQ;
            D[] = INF;
            D[s] = 0;
            PQ.insert(P(s, 0));
            while (! PQ.empty) {
                auto c = PQ.front; PQ.removeFront;
                int v = c.index;
                if (D[v] < c.dist) continue;
                foreach (e; G[c.index]) {
                    int ndist = D[v] + potential[v] - potential[e.to] + e.cost;
                    if (e.cap > 0 && D[e.to] > ndist) {
                        D[e.to] = ndist;
                        prevEdge[e.to] = e;
                        PQ.insert(P(e.to, D[v]));
                    }
                }
            }
            if (D[t] == INF) return -1;
            foreach (v; 0 .. V) potential[v] += D[v];
            int d = flow;
            for (int v = t; v != s; v = prevEdge[v].from) {
                d = min(d, prevEdge[v].cap);
            }
            flow -= d;
            ret += d * potential[t];
            for (int v = t; v != s; v = prevEdge[v].from) {
                auto e = prevEdge[v];
                e.cap -= d;
                e.rev.cap += d;
            }
        }
        return ret;
    }
}

void main() {
    int V, E, F; readf("%s %s %s\n", &V, &E, &F);
    auto G = new Graph(V);
    foreach (i; 0 .. E) {
        int u, v, c, d; readf("%s %s %s %s\n", &u, &v, &c, &d);
        G.addEdge(u, v, c, d);
    }
    writeln(G.minCostFlow(0, V - 1, F));
}