Dinic:
int tot;int front[N],to[M<<1],nxt[M<<1],val[M<<1];int src,decc;int cur[N],lev[N];queue q;void read(int &x){ x=0; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }}void add(int u,int v,int w){ to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w; to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=0;}bool bfs(){ while(!q.empty()) q.pop(); for(int i=src;i<=decc;i++) lev[i]=-1,cur[i]=front[i]; lev[src]=0; q.push(src); int now; while(!q.empty()) { now=q.front(); q.pop(); for(int i=front[now];i;i=nxt[i]) { if(lev[to[i]]==-1&&val[i]>0) { lev[to[i]]=lev[now]+1; if(to[i]==decc) return true; q.push(to[i]); } } } return false;}int dinic(int now,int flow){ if(now==decc) return flow; int rest=0,delta; for(int &i=cur[now];i;i=nxt[i]) { if(lev[to[i]]>lev[now]&&val[i]>0) { delta=dinic(to[i],min(flow-rest,val[i])); if(delta) { val[i]-=delta; val[i^1]+=delta; rest+=delta; if(rest==flow) break; } } } if(rest==flow) lev[now]=-1; return rest;}
isap:
int tot;int front[N],nxt[M<<1],to[M<<1],val[M<<1],from[M<<1];int lev[N],num[N];int path[N];int cur[N]; int src,decc;void add(int u,int v,int w){ to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; from[tot]=u; val[tot]=w; to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; from[tot]=v; val[tot]=0;}bool bfs(){ queue q; for(int i=src;i<=decc;++i) lev[i]=decc; q.push(decc); lev[decc]=0; int now,t; while(!q.empty()) { now=q.front(); q.pop(); for(int i=front[now];i;i=nxt[i]) { t=to[i]; if(lev[t]==decc && val[i^1]) { lev[t]=lev[now]+1; q.push(t); } } } return lev[src]!=decc;} int augment(){ int now=decc,flow=inf; int i; while(now!=src) { i=path[now]; flow=min(flow,val[i]); now=from[i]; } now=decc; while(now!=src) { i=path[now]; val[i]-=flow; val[i^1]+=flow; now=from[i]; } return flow;} int isap(){ int flow=0; if(!bfs()) return 0; memset(num,0,sizeof(num)); for(int i=src;i<=decc;++i) num[lev[i]]++,cur[i]=front[i]; int now=src,t; while(lev[src]<=decc) { if(now==decc) { flow+=augment(); now=src; } bool advanced=false; for(int i=cur[now];i;i=nxt[i]) { t=to[i]; if(lev[t]==lev[now]-1 && val[i]) { advanced=true; path[t]=i; cur[now]=i; now=t; break; } } if(!advanced) { int mi=decc; for(int i=front[now];i;i=nxt[i]) if(val[i]) mi=min(mi,lev[to[i]]); if(!--num[lev[now]]) break; num[lev[now]=mi+1]++; cur[now]=front[now]; if(now!=src) now=from[path[now]]; } } return flow;}