rt。
#include <iostream>
#define maxN 100100
#define maxM 200200
using namespace std;
int n, m;
int head[maxN][2], edge[maxM][2], nxt[maxM][2], to[maxM][2], cnt;
void addEdge(int x, int y, int z, bool f) {
nxt[++ cnt][f] = head[x][f];
to[head[x][f] = cnt][f] = y;
edge[cnt][f] = z;
}
bool vis[maxN];
int anc[maxN], top;
int dfn[maxN], low[maxN], idx;
int scc[maxN], size[maxN], tot;
void tarjan(int x) {
low[x] = dfn[x] = ++ idx;
anc[++ top] = x, vis[x] = true;
for (int i = head[x][0]; i; i = nxt[i][0]) {
int y = to[i][0];
if (!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
} else if (vis[y]) {
low[x] = min(low[x], dfn[y]);
}
}
if (dfn[x] == low[x]) {
int y = 0; tot ++;
while (x ^ y) {
y = anc[top --], vis[y] = false, scc[y] = tot, size[tot] ++;
}
}
}
int q[maxN], st = 1, ed;
int candy[maxN], inDegree[maxN], ans;
int topSort() {
for (int i = 1; i <= tot; ++ i) {
if (!inDegree[i]) q[++ ed] = i;
candy[i] = 1;
}
while (st <= ed) {
int x = q[st ++];
for (int i = head[x][1]; i; i = nxt[i][1]) {
int y = nxt[i][1];
candy[y] = max(candy[y], candy[x] + edge[i][1]);
if (-- inDegree[y] == 0) q[++ ed] = y;
}
}
for (int i = 1; i <= tot; ++ i) ans += candy[i] * size[i];
return ans;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= m; ++ i) {
int x, a, b; cin >> x >> a >> b;
if (x == 1) addEdge(a, b, 0, 0), addEdge(b, a, 0, 0);
if (x == 2) addEdge(a, b, 1, 0);
if (x == 3) addEdge(b, a, 0, 0);
if (x == 4) addEdge(b, a, 1, 0);
if (x == 5) addEdge(a, b, 0, 0);
}
for (int i = 1; i <= n; ++ i)
if (!dfn[i]) tarjan(i);
cnt = 0;
for (int x = 1; x <= n; ++ x)
for (int i = head[x][0]; i; i =nxt[i][0]) {
int y = to[i][0], xx = scc[x], yy = scc[y];
if (xx ^ yy) {
addEdge(xx, yy, edge[i][0], 1), inDegree[yy] ++;
} else if (edge[i][0]) {
return puts("-1"), 0;
}
}
cout << topSort() << '\n';
return 0;
}