#include<bits/stdc++.h>
using namespace std;
//假设无平行边和a-b b-a的回路,cost可以是负值
//利用bellmanford算法求最短路径,因为需要最小cost
//这个算法支持中途调用,但是调用时必须是最小cost状态,因为dp
const int maxn=1001;
int G[maxn][maxn],pre[maxn],n,m,flow[maxn][maxn],d[maxn],w[maxn][maxn],cost=0,as[maxn];//flow是当前的流量 a 代表到某个点的最小残余流量
//通过前驱数组求一条路径,当然结果可能会多了不是这条路径上的点的前驱,因为不一定能一次到
int flg[maxn];
int max_flow_with_cost(int s,int t){
int f=0;
memset(flow,0,sizeof(flow));
while(1){
queue<int> q;
q.push(s);
memset(flg,0,sizeof(flg));
memset(pre,0,sizeof(pre));
memset(d,0x3f3f3f3f,sizeof(d));
memset(as,0x3f3f3f3f,sizeof(as));
flg[s]=1;
d[s]=0;
while(!q.empty()){
int x=q.front();
q.pop();
flg[x]=0;//用于标识队列中如果有了,不重复加入队列
for(int i=1;i<=n;i++){
if(G[x][i]!=0&&G[x][i]>flow[x][i]&&d[x]+w[x][i]<d[i]){
d[i]=d[x]+w[x][i];
pre[i]=x;
// as[i]=min(as[i],G[x][i]-flow[x][i]);
if(!flg[i]){
flg[i]=1;
q.push(i);
}
}
}
}
//t不可达即停止,当然也可以通过pre试试能不能到s然后停止,用a也可
if(d[t]==0x3f3f3f3f) {cout<<"cost is "<<cost<<endl; return f;}
int a=0x3f3f3f3f;
// a=as[t];
for(int i=t;pre[i]!=0;i=pre[i]) a=min(a,G[pre[i]][i]-flow[pre[i]][i]);
for(int i=t;pre[i]!=0;i=pre[i]){
flow[pre[i]][i]+=a;
flow[i][pre[i]]-=a;
cost+=a*w[pre[i]][i];
}
// cost+=a*d[t];
f+=a;
}
}
int main() {
cin>>n>>m;
memset(G,0,sizeof(G));
for(int i=0;i<m;i++){
int x,y,z,k;
cin>>x>>y>>z>>k;
G[x][y]=z;
w[x][y]=k;
}
cout<<max_flow_with_cost(1,2)<<endl;
return 0;
}