#include <bits/stdc++.h>

using namespace std;

namespace {

    typedef double real;
    typedef long long ll;

    template<class T> ostream& operator<<(ostream& os, const vector<T>& vs) {
        if (vs.empty()) return os << "[]";
        auto i = vs.begin();
        os << "[" << *i;
        for (++i; i != vs.end(); ++i) os << " " << *i;
        return os << "]";
    }
    template<class T> istream& operator>>(istream& is, vector<T>& vs) {
        for (auto it = vs.begin(); it != vs.end(); it++) is >> *it;
        return is;
    }

    const int INF = 1<<28;

    struct Edge {
        int from, to, cap, cost, rev;
        Edge() {}
        Edge(int from, int to, int cap, int cost, int rev=-1) : from(from), to(to), cap(cap), cost(cost), rev(rev) {}
    };
    struct Graph {
        int V;
        vector< vector<Edge> > G;
        vector<bool> used;
        Graph(int V) : V(V) {
            G.clear(); G.resize(V);
            used.clear(); used.resize(V);
        }
        void addEdge(int from, int to, int cap, int cost) {
            G[from].push_back(Edge(from, to, cap, cost, G[to].size()));
            G[to].push_back(Edge(to, from, 0, -cost, int(G[from].size()) - 1));
        }
        int minCostFlow(int from, int to, int flow) {
            vector<int> dist(V, INF);
            dist[from] = 0;
            vector<int> prevv(V), preve(V);
            int ret = 0;
            while (flow > 0) {
                fill(dist.begin(), dist.end(), INF);
                dist[from] = 0;
                bool update = true;
                while (update) {
                    update = false;
                    for (int v = 0; v < V; v++) {
                        if (dist[v] == INF) continue;
                        for (int i = 0; i < int(G[v].size()); i++) {
                            auto& e = G[v][i];
                            if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
                                dist[e.to] = dist[v] + e.cost;
                                prevv[e.to] = v;
                                preve[e.to] = i;
                                update = true;
                            }
                        }
                    }
                }
                if (dist[to] == INF) return -1;
                int d = flow;
                for (int v = to; v != from; v = prevv[v]) {
                    d = min(d, G[prevv[v]][preve[v]].cap);
                }
                flow -= d;
                ret += d * dist[to];
                for (int v = to; v != from; v = prevv[v]) {
                    Edge& e = G[prevv[v]][preve[v]];
                    e.cap -= d;
                    G[v][e.rev].cap += d;
                }
            }
            return ret;
        }
    };

    int V, E, F;
    Graph* g;
    void input() {
        cin >> V >> E >> F;
        g = new Graph(V);
        for (int i = 0; i < E; i++) {
            int from, to, cap, cost;
            cin >> from >> to >> cap >> cost;
            g->addEdge(from, to, cap, cost);
        }
    }

    void solve() {
        cout << g->minCostFlow(0, V - 1, F) << endl;
    }
}

int main() {
    input(); solve();
    return 0;
}

Measured memory_bytes: 3136