#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long
namespace io{
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define ROF(i,a,b) for(int i=a;i>=b;--i)
#define ls rt<<1
#define rs rt<<1|1
#define mid (l+r)/2
#define pc putchar('\n')
#define pt putchar(' ')
inline int Max(int i,int j){return i>j?i:j;}
inline int Min(int i,int j){return i<j?i:j;}
char ch;
int putout[1<<15];
inline void in(int &x){
x=0;
int f=1;
while(ch=getchar()){
if(ch=='-')f=-1;
if(ch>='0'&&ch<='9')break;
}
x=ch-'0';
while(ch=getchar()){
if(ch<'0'||ch>'9')break;
x=(x<<1)+(x<<3)+ch-'0';
}
x*=f;
}
inline void out(int x){
if(x==0){putchar('0');return ;}
if(x<0){x=-x;putchar('-');}
int len=0;
while(x){putout[++len]=x%10,x/=10;}
ROF(i,len,1)putchar(putout[i]+'0');
return ;
}
}
using namespace io;
const int N=6e5+5;
int n,k;
struct NODE{
int nxt,to,val;
}e[N<<2];
int head[N<<2],cnt;
void add(int from,int to,int val){
e[++cnt].nxt=head[from];
e[cnt].to=to;
e[cnt].val=val;
head[from]=cnt;
return ;
}
int dis[N];
int hd,tl,Q[N<<2];
int pass[N<<2];
bool vis[N];
bool all_flag;
void SPFA(){
memset(dis,~0x3f,sizeof dis);
dis[0]=0;
vis[0]=1;
hd=1,tl=1;
Q[1]=0;
while(hd<=tl){
int u=Q[hd++];
vis[u]=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(dis[v]<dis[u]+e[i].val){
dis[v]=dis[u]+e[i].val;
pass[v]++;
if(pass[v]==n){
return ;
}
if(!vis[v]){
Q[++tl]=v;
vis[v]=1;
}
}
}
}
all_flag=1;
return ;
}
int ans=0;
signed main(){
in(n),in(k);
FOR(i,1,n)add(0,i,1);
FOR(i,1,k){
int x,A,B;
in(x),in(A),in(B);
if(x==1){
add(A,B,0);
add(B,A,0);
}else if(x==2){
if(A==B){printf("-1");return 0;}
add(A,B,1);
}else if(x==3){
add(B,A,0);
}else if(x==4){
if(A==B){printf("-1");return 0;}
add(B,A,1);
}else if(x==5){
add(A,B,0);
}
}
SPFA();
if(all_flag==0){printf("-1");return 0;}
FOR(i,1,n)ans+=dis[i];
out(ans);
return 0;
}