using namespace std;
struct Edge {
int from,to,nxt,val;
Edge() {}
Edge(
int _from,
int _to,
int _nxt,
int _val):
from(_from),to(_to),nxt(_nxt),val(_val) {}
}e[N
*5];
int n,
m,tot,fir[N],d[N];
void Add_Edge(
int from,
int to,
int val) {
e[++tot]=Edge(from,to,fir[from],val), fir[from]=tot;
return ;
}
bool SPFA() {
static
int cnt[N];
static bool in
q[N];
queue<
int>
q;
q.
push(
0), in
q[0]=true;
while(!
q.empty()) {
int x=
q.front();
q.
pop();
in
q[x]=false;
for(
int i=fir[
x];~i;i=e[i].nxt) {
if(d[e[i].to]>=d[
x]+e[i].val)
continue;
d[e[i].to]=d[
x]+e[i].val;
cnt[e[i].to]=cnt[
x]+
1;
if(cnt[e[i].to]>n+
1)
return false;
if(!in
q[e[i].to])
q.
push(e[i].to), in
q[e[i].to]=true;
}
}
return true;
}
int main() {
memset(fir,-
1,sizeof fir), tot=-
1;
scanf(
"%d%d",&n,&
m);
for(
int i=n;i;--i) Add_Edge(
0,i,
1);
for(
int i=
1,mode,
x,
y;i<=
m;++i) {
scanf(
"%d%d%d",&mode,&
x,&
y);
if(mode==
1) Add_Edge(
x,
y,
0), Add_Edge(
y,
x,
0);
if(mode==
2) Add_Edge(
x,
y,
1);
if(mode==
3) Add_Edge(
y,
x,
0);
if(mode==
4) Add_Edge(
y,
x,
1);
if(mode==
5) Add_Edge(
x,
y,
0);
}
if(!SPFA()) {
puts(
"-1");
return 0;
}
long long ans=
0;
for(
int i=
1;i<=n;++i) ans+=d[i];
printf(
"%lld\n",ans);
return 0;
}