#include <bits/stdc++.h>
#define rep(i, n) for (int i=0; i<(int)(n); i++)
#define all(v) v.begin(), v.end()
#define PRINT(v) for (auto x : (v)) cout <<x <<" " ; cout <<endl;
using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
using mat = vector<vector<ll>>;
const ll MOD = 1000000007;
const ll INF = 10000000000000000;
vector<int> x4 = {0, 1, 0, -1}, x8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<int> y4 = {1, 0, -1, 0}, y8 = {1, 1, 0, -1, -1, -1, 0, 1};
template<class T> inline bool chmin(T& a, T b){if (a>b){a = b; return true;}return false;}
template<class T> inline bool chmax(T& a, T b){if (a<b){a = b; return true;}return false;}
template<class T> inline T powerM(T a,T b){if (b==0) return 1;
T tmp = powerM(a,b/2); if (b%2==0) return tmp*tmp%MOD; else return tmp*tmp%MOD*a%MOD; }
template<class T> inline T power(T a,T b,T m){ if (b==0) return 1;
  T tmp = power(a,b/2,m); if (b%2==0) return tmp*tmp%m; else return tmp*tmp%m*a%m; }
template<class T> inline T gcd(T a, T b){if (b==0) return a; return gcd(b, a%b);}
template<class T> inline T lcm(T a, T b){return a / gcd(a,b) * b;}
// ax+by=gcd(a,b)を解く
template<class T> inline T extgcd(T a,T b,T &x,T &y){if (b==0){x=1; y=0; return a;} T d=extgcd(b,a%b,y,x); y -= a/b*x; return d;}
void hey(){ cout <<"hey" <<endl; }

template<class T> struct edge { int to; T cost;};


// 最小費用流:PotentialとDijkstra--------------------------------------------------
// 最短路反復法。Potentialの概念を導入し負辺を駆逐しDijkstraを使えるようにする
// O(F|E|log|V|) or O(F|V|^2)
// verifyはここ <http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_B&lang=jp>

// 辺を表す構造体 (行き先、容量、コスト、逆辺)
struct edgeflow {int to, cap, cost, rev;};
typedef pair<int,int> P;

struct MinCostFlowPo {
  int V;                      // 頂点数
  vector<vector<edgeflow>> G; // グラフの隣接リスト表現
  vector<int> h;              // ポテンシャル
  vector<int> dist;           // 最短距離
  vector<int> prevv,preve;    // 直前の頂点と辺
  const int Inf = 1000000000;

  MinCostFlowPo(int n) : V(n), G(n), h(n, 0), dist(n, Inf), prevv(n, -1), preve(n, -1) {}

  // fromからtoへ向かう容量cap, コストcostの辺をグラフに追加する
  void add_edge(int from, int to, int cap, int cost) {
    G[from].push_back((edgeflow){to, cap, cost, (int)G[to].size()});
    G[to].push_back((edgeflow){from, 0, -cost, (int)G[from].size() - 1});
  }

  // sからtへの流量fの最小費用流を求める。流せない場合は-1を返す
  int min_cost_flow(int s, int t, int f){
    int res = 0;
    h.assign(V, 0);
    while (f > 0){
      // Dijkstra法によりhを更新する
      priority_queue<P, vector<P>, greater<P> > que;
      dist.assign(V, Inf);
      dist[s] = 0;
      que.push(P(0, s));
      while (!que.empty()){
        P p = que.top(); que.pop();
        int v = p.second;
        if (dist[v] < p.first) continue;
        for (int i=0; i<G[v].size(); i++){
          edgeflow &e = G[v][i];
          if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]){
            dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
            prevv[e.to] = v;
            preve[e.to] = i;
            que.push(P(dist[e.to], e.to));
          }
        }
      }
      // これ以上流せない
      if (dist[t] == Inf) return -1;

      for (int v=0; v<V; v++) h[v] += dist[v];

      // s-t間最短路に沿って目いっぱい流す
      int d = f;
      for (int v=t; v != s; v = prevv[v]){
        d = min(d, G[prevv[v]][preve[v]].cap);
      }
      f -= d;
      res += d * h[t];
      for (int v=t; v != s; v = prevv[v]){
        edgeflow &e = G[prevv[v]][preve[v]];
        e.cap -= d;
        G[v][e.rev].cap += d;
      }
    }
    return res;
  }
};


int main() {
  int N,M,F; cin >>N >>M >>F;
  MinCostFlowPo mc(N);
  rep(i, M){
    int u,v,c,d; cin >>u >>v >>c >>d;
    mc.add_edge(u, v, c, d);
  }
  int res = mc.min_cost_flow(0, N-1, F);
  cout <<res <<endl;
}



Measured memory_bytes: 3224