#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 9,M = 1e6 + 9;
bool flag[N];
int dis[N];
int n,m;
int op,u,v,w;
struct Graph{
struct edge{
int from,to,cost,nex;
} e[M << 2];
int head[N],ecnt;
int cnt[N];
void addedge(int u,int v,int w){
ecnt++;
e[ecnt] = (edge){u,v,w,head[u]};
head[u] = ecnt;
}
} G1,G2;
int dfn[N],low[N],id;
int cnt,siz[N],bel[N];
stack<int> s;
bool in_stack[N];
void dfs(int u){
id++;
dfn[u] = low[u] = id;
s.push(u);
in_stack[u] = true;
for(int i = G1.head[u];i;i = G1.e[i].nex){
int v = G1.e[i].to;
if(!dfn[v]){
dfs(v);
low[u] = min(low[u],low[v]);
}
else if(in_stack[v])
low[u] = min(low[u],dfn[v]);
}
if(low[u] == dfn[u]){
cnt++;
while(1){
int v = s.top();
s.pop();
in_stack[v] = false;
bel[v] = cnt;
siz[cnt]++;
if(v == u)
break;
}
}
}
int deg[N];
queue<int> q;
int dp[N],ans;
void topsort(){
for(int i = 1;i <= n;i++){
if(deg[i] == 0){
q.push(i);
dp[i] = 1;
}
}
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = G2.head[u];i;i = G2.e[i].nex){
int v = G2.e[i].to,w = G2.e[i].cost;
deg[v]--;
dp[v] = max(dp[v],dp[u] + w);
if(deg[v] == 0)
q.push(v);
}
}
}
signed main(){
freopen("P3275_8.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= m;i++){
cin >> op >> u >> v;
if(op == 1){
G1.addedge(u,v,0);
G1.addedge(v,u,0);
}
else if(op == 2)
G1.addedge(v,u,1);
else if(op == 3)
G1.addedge(u,v,0);
else if(op == 4)
G1.addedge(u,v,1);
else if(op == 5)
G1.addedge(v,u,0);
if(!(op & 1) && u == v){
cout << -1;
return 0;
}
}
for(int i = 1;i <= n;i++)
if(!dfn[i])
dfs(i);
for(int i = 1;i <= G1.ecnt;i++){
int u = G1.e[i].from,v = G1.e[i].to,w = G1.e[i].cost;
if(bel[u] == bel[v]){
if(w == 1){
cout << -1;
return 0;
}
}
else{
G2.addedge(bel[u],bel[v],w);
deg[bel[v]]++;
}
}
topsort();
for(int i = 1;i <= cnt;i++)
ans += siz[i] * dp[i];
cout << ans;
return 0;
}