#include <bits/stdc++.h>
using namespace std;
enum Type { LE, GE, EQ };
enum Result { OK, UNBOUND, UNFEASIBLE };
enum OFType { MAX, MIN };
struct SimplexModel {
  vector<vector<long double> > lhs;
  vector<long double> rhs;
  vector<Type> constraintTypes;
  vector<long double> of;
  OFType oftype;
  vector<bool> unRestricted;
  vector<long double> solution;
  int nVar, nCon;
  vector<int> negativePart;
  vector<int> positivePart;
  vector<bool> isNegativePart;
  vector<int> basic;
  vector<bool> isArtificial;
  int addVariable() {
    for (int i = 0; i < lhs.size(); i++) lhs[i].push_back(0);
    of.push_back(0);
    isArtificial.push_back(false);
    isNegativePart.push_back(false);
    positivePart.push_back(0);
    return nVar++;
  }
  void standardize() {
    nVar = unRestricted.size();
    nCon = lhs.size();
    negativePart.resize(nVar);
    positivePart.resize(nVar);
    isNegativePart.clear();
    isNegativePart.resize(nVar, false);
    basic.clear();
    solution.clear();
    solution.resize(nVar, 0);
    isArtificial.clear();
    isArtificial.resize(nVar, false);
    int i, j, varIdx;
    if (oftype == MIN) {
      for (i = 0; i < nVar; i++) of[i] *= -1;
      oftype = MAX;
    }
    for (i = 0; i < unRestricted.size(); i++) {
      if (!unRestricted[i]) continue;
      varIdx = addVariable();
      for (j = 0; j < nCon; j++) lhs[j][varIdx] = -lhs[j][i];
      of[varIdx] = -of[i];
      negativePart[i] = varIdx;
      positivePart[varIdx] = i;
      isNegativePart[varIdx] = true;
    }
    for (i = 0; i < nCon; i++) {
      if (rhs[i] < 0) {
        rhs[i] *= -1;
        for (j = 0; j < nVar; j++) lhs[i][j] *= -1;
        if (constraintTypes[i] != EQ)
          constraintTypes[i] = constraintTypes[i] == GE ? LE : GE;
      }
      int basicVar = addVariable();
      basic.push_back(basicVar);
      lhs[i][basicVar] = 1;
      switch (constraintTypes[i]) {
        case GE:
          varIdx = addVariable();
          lhs[i][varIdx] = -1;
        case EQ:
          isArtificial[basicVar] = true;
          of[basicVar] = -1e30;
          break;
      }
      constraintTypes[i] = EQ;
    }
  }
  Result solve() {
    standardize();
    int i, j, k;
    long double z, ratio, cmz;
    while (true) {
      int pivotCol = 0;
      long double bestCMZ = -1e30;
      for (j = 0; j < nVar; j++) {
        z = k = 0;
        for (i = 0; i < basic.size(); i++) z += of[basic[i]] * lhs[k++][j];
        cmz = of[j] - z;
        pivotCol = (cmz > bestCMZ) ? j : pivotCol;
        bestCMZ = max(cmz, bestCMZ);
      }
      if (fabs(bestCMZ) < 1e-9) break;
      int pivotRow = 0;
      long double bestRatio = 1e30;
      for (i = 0; i < nCon; i++) {
        if (lhs[i][pivotCol] < 1e-9) continue;
        ratio = rhs[i] / lhs[i][pivotCol];
        if (ratio < 0) ratio = 1e30;
        pivotRow = ratio < bestRatio ? i : pivotRow;
        bestRatio = min(bestRatio, ratio);
      }
      if (bestRatio >= 1e30) return UNBOUND;
      basic[pivotRow] = pivotCol;
      long double pivot = lhs[pivotRow][pivotCol];
      for (i = 0; i < nVar; i++) lhs[pivotRow][i] /= pivot;
      rhs[pivotRow] /= pivot;
      for (i = 0; i < nCon; i++) {
        if (i == pivotRow) continue;
        long double val = -lhs[i][pivotCol];
        for (j = 0; j < nVar; j++) lhs[i][j] += lhs[pivotRow][j] * val;
        rhs[i] += rhs[pivotRow] * val;
      }
    }
    for (i = 0; i < basic.size(); i++) {
      if (isArtificial[basic[i]] && fabs(rhs[i]) > 1e-9) return UNFEASIBLE;
      if (basic[i] < solution.size())
        solution[basic[i]] += rhs[i];
      else if (isNegativePart[basic[i]])
        solution[positivePart[basic[i]]] += -rhs[i];
    }
    return OK;
  }
};
const int MAXN = 105;
vector<int> in[MAXN], out[MAXN], fin[MAXN], fout[MAXN];
void print(SimplexModel &model) {
  for (int j = 0; j < model.lhs[0].size(); j++)
    cout << setw(4) << (j % 4 == 0 ? "X" : "") << " ";
  cout << "\n";
  for (int i = 0; i < model.lhs.size(); i++) {
    for (int j = 0; j < model.lhs[i].size(); j++)
      cout << setw(4) << model.lhs[i][j] << " ";
    if (model.constraintTypes[i] == GE) cout << setw(4) << ">=";
    if (model.constraintTypes[i] == LE) cout << setw(4) << "<=";
    if (model.constraintTypes[i] == EQ) cout << setw(4) << '=';
    cout << " " << setw(4) << model.rhs[i] << "\n";
  }
}
void print2(SimplexModel &model) {
  for (int i = 0; i < model.solution.size(); i++)
    cout << setw(4) << model.solution[i] << " ";
  cout << "\n";
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  if (m == 0) {
    cout << 0 << "\n";
    return 0;
  }
  int nVar = 4 * m;
  SimplexModel model;
  model.of.resize(nVar, 1);
  model.oftype = MIN;
  model.unRestricted.resize(nVar, false);
  for (int i = 0; i < m; i++) {
    int from, to, cap, flow;
    cin >> from >> to >> cap >> flow;
    in[to].push_back(i);
    fin[to].push_back(flow);
    out[from].push_back(i);
    fout[from].push_back(flow);
    model.constraintTypes.push_back(GE);
    vector<long double> row(nVar, 0);
    const static int arr[] = {-1, 1, 1, -1};
    for (int j = 0; j < 4; j++) row[(i << 2) + j] = arr[j];
    model.lhs.push_back(row);
    model.rhs.push_back(flow - cap);
    row = vector<long double>(nVar, 0);
    row[(i << 2)] = 1;
    row[(i << 2) | 1] = -1;
    model.lhs.push_back(row);
    model.rhs.push_back(-flow);
    model.constraintTypes.push_back(GE);
  }
  for (int i = 2; i < n; i++) {
    vector<long double> row(nVar, 0);
    int sum = 0;
    for (int j = 0; j < in[i].size(); j++) {
      sum += fin[i][j];
      int id = in[i][j];
      row[(id << 2)] = -1;
      row[(id << 2) | 1] = 1;
    }
    for (int j = 0; j < out[i].size(); j++) {
      sum -= fout[i][j];
      int id = out[i][j];
      row[(id << 2)] = 1;
      row[(id << 2) | 1] = -1;
    }
    model.lhs.push_back(row);
    model.rhs.push_back(sum);
    model.constraintTypes.push_back(EQ);
  }
  Result r = model.solve();
  assert(r == 0);
  long double d = 0;
  for (int i = 0; i < model.solution.size(); i++) d += model.solution[i];
  cout << (long long)(d + 0.5) << "\n";
  return 0;
}
