inlinelonglongread() { longlong x = 0; int f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } return x * f; } voidwrite(constlonglong &x) { if (!x) { putchar('0'); return; } char f[100]; longlong tmp = x; if (tmp < 0) { tmp = -tmp; putchar('-'); } int s = 0; while (tmp > 0) { f[s++] = tmp % 10 + '0'; tmp /= 10; } while (s > 0) { putchar(f[--s]); } }
constint N = 3500010, M = 3500010; int ver[M], Next[M], head[N], dfn[N], low[N]; int in_stack[N], in_DCC_num[N]; int ver_of_DCC[M], next_of_DCC[M], head_of_DCC[N], tot_DCC_Nodes; stack<int> Nodes_of_DCCs; vector<int> DCCs[N]; int tot, num, cnt;
voidadd(int x, int y) { ver[++tot] = y, Next[tot] = head[x], head[x] = tot; } voidadd_DCC_Node(int x, int y) { ver_of_DCC[++tot_DCC_Nodes] = y, next_of_DCC[tot_DCC_Nodes] = head_of_DCC[x], head_of_DCC[x] = tot_DCC_Nodes; } voidtarjan(int x) { dfn[x] = low[x] = ++num; Nodes_of_DCCs.push(x); in_stack[x] = 1; for (int i = head[x]; i; i = Next[i]) if (!dfn[ver[i]]) { tarjan(ver[i]); low[x] = min(low[x], low[ver[i]]); } elseif (in_stack[ver[i]]) low[x] = min(low[x], dfn[ver[i]]); if (dfn[x] == low[x]) { cnt++; int y; do { y = Nodes_of_DCCs.top(); Nodes_of_DCCs.pop(); in_stack[y] = 0; in_DCC_num[y] = cnt, DCCs[cnt].push_back(y); } while (x != y); } }
bool visit[3500090]; int match[3500090];
booldfs(int x) { for (int i = head_of_DCC[x]; i; i = next_of_DCC[i]) { int y; if (!visit[y = ver_of_DCC[i]]) { visit[y] = true; if (!match[y] || dfs(match[y])) { match[y] = x; returntrue; } } } returnfalse; }
int answer = 0; int totDOT; int totROAD;
intmain() { totDOT = read(); totROAD = read(); for (int i = 1; i <= totROAD; i++) { add(read(), read()); } for (int i = 1; i <= totDOT; i++) { if (!dfn[i]) { tarjan(i); } } for (int i = 1; i <= totDOT; i++) { for (int j = head[i]; j; j = Next[j]) { int y = ver[j]; if (in_DCC_num[i] == in_DCC_num[y]) continue; add_DCC_Node(in_DCC_num[i], in_DCC_num[y]); } } for (int i = 1; i <= cnt; i++) { memset(visit, 0, sizeof(visit)); if (dfs(i)) { answer++; } } write(answer); return0; } //LikiBlaze Code