//2020/8/24/21:07
#include <cstdio>
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
const int INF = 0x3f3f3f3f;
//
inline int read()
{
char c=getchar();
int x=0,f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*f;
}
int n, m;
int head[N], cnt = 0;
int to[N], nxt[N], c[N];
int num[N], dis[N]; bool vis[N]; //mark[N];
inline void add(int u, int v, int w){
to[cnt] = v, c[cnt] = w, nxt[cnt] = head[u], head[u] = cnt ++;
// to[cnt] = u, c[cnt] = w, nxt[cnt] = head[u], head[u] = cnt ++;
}
bool SPFA(int st){
queue<int> q;
for(int i = 0; i <= n; ++ i){
vis[i] = false; num[i] = 0; dis[i] = INF;
}
q.push(st); vis[st] = true; num[st] = 1; dis[st] = 0;
while(q.size()){
int u = q.front(); q.pop();
vis[u] = false;
for(int i = head[u]; i != -1; i = nxt[i]){
int v = to[i], w = c[i];
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
if(!vis[v]){
q.push(v); vis[v] = true;
if(++ num[v] >= n) return false;
}
}
}
}
return true;
}
int main()
{
n = read(), m = read();
cnt = 0;
for(int i = 0; i <= n; ++ i) head[i] = -1;
while(m --){
int op, x, y;
op = read();
if(op == 1){
x = read(), y = read();
add(x, y, 0); add(y, x, 0);
}
else if(op == 2){
x = read(), y = read();
if(x == y){
printf("-1\n"); return 0;
}
add(x, y, -1);
}
else if(op == 3){
x = read(), y = read();
add(y, x, 0);
}
else if(op == 4){
x = read(), y = read();
if(x == y){
printf("-1\n"); return 0;
}
add(y, x, -1);
}
else{
x = read(), y = read();
add(x, y, 0);
}
}
for(int i = n; i >= 1; -- i){
add(0, i, -1);
}
if(SPFA(0)){
ll res = 0;
for(int i = 1; i <= n; ++ i) {
res -= dis[i];
}
printf("%lld\n",res);
}
else printf("-1\n");
return 0;
}