# 思路

• 不存在边满足两个权值都大于 $mid$
• 不存在边的 $deg$ 是奇数。

$∀i$ 满足 $deg[i]=0$ 时，显然流量是 $\frac{\sum^{n}_{i=1}\operatorname{abs}deg[i]}{2}$。判断是否满流即可。

# 代码

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <queue>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=2010,M=100010,Inf=1e9+114514;
bool vis[M],WYCtql;
vector<int> r[N];

struct edge1
{
int from,to,a,b;
}e[M];

void add(int from,int to,int a,int b)
{
e[++tot].to=to;
e[tot].from=from;
e[tot].a=a;
e[tot].b=b;
}

struct edge2
{
int next,to,flow;
}ans[M];

struct edge3
{
int next,to;
}ee[M];

{
out[from]++;
ee[++tot].to=to;
}

struct Dinic
{
edge2 e[M];

void clr()
{
tot=1;
}

{
e[++tot].to=to;
e[tot].flow=flow;
swap(from,to);
e[++tot].to=to;
e[tot].flow=0;
}

bool bfs()
{
memset(dep,0x3f3f3f3f,sizeof(dep));
queue<int> q; q.push(S);
dep[S]=0;
while (q.size())
{
int u=q.front();
q.pop();
{
int v=e[i].to;
if (e[i].flow && dep[v]>dep[u]+1)
{
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return dep[T]<Inf;
}

int dfs(int x,int flow)
{
int ret=0,used=0;
if (x==T)
{
maxflow+=flow;
return flow;
}
for (int i=cur[x];~i;i=e[i].next)
{
int v=e[i].to;
cur[x]=i;
if (e[i].flow && dep[x]==dep[v]-1)
{
ret=dfs(v,min(flow-used,e[i].flow));
if (ret)
{
used+=ret;
e[i].flow-=ret; e[i^1].flow+=ret;
if (used==flow) break;
}
}
}
return used;
}

void dinic()
{
maxflow=0;
while (bfs()) dfs(S,Inf);
}
}dinic;

bool check(int mid)
{
memset(deg,0,sizeof(deg));
for (int i=1;i<=m;i++)
{
if (min(e[i].a,e[i].b)>mid) return 0;
if (e[i].a<=mid)
deg[e[i].from]++,deg[e[i].to]--;
else
deg[e[i].to]++,deg[e[i].from]--;
}
dinic.clr();
for (int i=1;i<=m;i++)
if (e[i].a<=mid && e[i].b<=mid)
int sum=0;
for (int i=1;i<=n;i++)
{
if (abs(deg[i])&1) return 0;
deg[i]/=2; sum+=abs(deg[i]);
}
dinic.dinic();
return maxflow==sum/2;
}

void print(int x)
{
{
int k=i;
if (!vis[k]) {
vis[k]=1;
print(ee[k].to);
st[++top]=k;
}
}
}

int main()
{
scanf("%d%d",&n,&m);
srand(n+m+23333);
L=Inf; S=N-1; T=N-2;
for (int i=1,x,y,a,b;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&a,&b);
L=min(L,min(a,b)); R=max(R,max(a,b));
}
bool flag=0;
while (L<=R)
{
Mid=(L+R)>>1;
if (check(Mid))
{
R=Mid-1; flag=1;
memcpy(ans,dinic.e,sizeof(ans));
}
else L=Mid+1;
}
if (flag) printf("%d\n",R+1);
else return !printf("NIE");
tot=0;
for (int i=1,j=0;i<=m;i++)
if (e[i].a<=R+1 && e[i].b<=R+1)
{
j++;
if (!ans[j*2].flow)