//题意:给定一些限制条件,询问满足条件的任一正数解是什么。(详细题意搜原题)
//思路: 本题有几个额外信息很关键
// 最大人数1e5,连出去的边只有0和-1
// 如果我们直接冲差分约束,那么复杂度会冲到1e9之上,是跑不完所有数据的
// 所以我们为了减少时间复杂度,应当减少点数与边数,所以我们想到缩点
// 但是这题需判断是否无解(有负环),所以我们应当首先判断负环,不过好在这题的边权除了-1就只有0,所以我们缩点后对每个强联通分量进行判断,看有没有-1就行
// 另外当最短路图中没有环时,我们可以先拓扑排序然后按拓扑序求最短路
// 最后这题的复杂度应该接近O(n+m)
//
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;
int n, k;
vector<pair<int, int>> mp[N];
vector<pair<int, int>> nmp[2 * N];//重边对最短路没有影响
void read() {
int od, a, b; cin >> od >> a >> b;
if (od == 1) {
mp[a].push_back({ b,0 });
mp[b].push_back({ a,0 });
}
else if (od == 2) mp[b].push_back({ a,-1 });
else if (od == 3) mp[a].push_back({ b,0 });
else if (od == 4) mp[a].push_back({ b,-1 });
else if (od == 5) mp[b].push_back({ a,0 });
}
int dfn[N], idx, bel[N], low[N], ins[N], cnt, sz[N];
stack<int> stk;
vector<int> scc[N];
void dfs(int x) {
dfn[x] = low[x] = ++idx;
stk.push(x);
ins[x] = 1;
for (auto v : mp[x]) {
int tp = v.first;
if (!dfn[tp]) {
dfs(tp);
low[x] = min(low[x], low[tp]);
}
else if (ins[tp]) low[x] = min(low[x], dfn[tp]);
}
if (dfn[x] == low[x]) {
++cnt;
while (true) {
int v = stk.top();
scc[cnt].push_back(v);
sz[cnt]++;
ins[v] = false;
bel[v] = cnt;
stk.pop();
if (v == x) break;
}
}
}
int rd[2 * N], cnt1, odr[N];
queue<int> lis;
void topo() {
while (!lis.empty()) {
int x = lis.front();
odr[++cnt1] = x;
for (auto y : nmp[x]) {
rd[y.first]--;
if (!rd[y.first]) lis.push(y.first);
}
lis.pop();
}
}
int dis[2 * N];
signed main() {
cin >> n >> k;
for (int i = 1; i <= k; i++) read();
for (int i = 1; i <= n; i++) mp[i].push_back({ 0,-1 });//最小糖果树是正数,所以满足xi-x0>=1
for (int i = 1; i <= n; i++)
if (!dfn[i]) dfs(i);
for (int i = 1; i <= cnt; i++)
for (auto x : scc[i])
for (auto v : mp[x])
if (bel[v.first] == i && v.second == -1) {
cout << -1; return 0;
}
//有负环
for (int i = 1; i <= cnt; i++)
for (auto x : scc[i])
for (auto v : mp[x])
if (bel[x] != bel[v.first]) {
nmp[n + i].push_back({ n + bel[v.first], v.second});//建新图
rd[n + bel[v.first]]++;
}
for (int i = 1 + n; i <= n + cnt; i++) dis[i] = 1 << 29;
for (int i = 1 + n; i <= n + cnt; i++) {
if (rd[i] == 0) {
dis[i] = 0;
lis.push(i);
}
}
topo();
for (int i = 1; i <= cnt1; i++)
for (auto x : nmp[odr[i]])
if (dis[odr[i]] + x.second < dis[x.first])
dis[x.first] = dis[odr[i]] + x.second;
int ans = 0, dis0 = dis[bel[0] + n];
for (int i = 1 + n; i <= n + cnt; i++) {
ans += sz[i - n] * (dis[i] - dis0);
}
cout << ans;
return 0;
}