// pSaurabh
#include <bits/stdc++.h>
using namespace std;
#define read(a, n) for(int i = 0; i < n; ++i) cin >> a[i];
#define print(a, n) for(int i = 0; i < n; ++i) if(i == n - 1){ cout << a[i] << "\n"; } else { cout << a[i] << ' '; }
typedef long long ll;
typedef long double ld;
const ll mod = 1e9 + 7;
const int maxSize = 5e5 + 5;
void fast(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
vector <vector <int>> adjP(maxSize);
vector <vector <int>> adjH(maxSize);
vector <vector <int>> adj (maxSize);
vector <char> assigned(maxSize, 'N');
vector <bool> vis(maxSize, 0);
bool dfs(int root, char type){
if(assigned[root] == 'N'){
assigned[root] = type;
}
else{
if(type != assigned[root]){
return 0;
}
}
if(vis[root]) return 1;
vis[root] = 1;
if(type == 'H'){
bool isConsistent = 1;
for(auto it : adjP[root]){
isConsistent &= dfs(it, 'P');
}
for(auto it : adjH[root]){
isConsistent &= dfs(it, 'H');
}
return isConsistent;
}
else{
bool isConsistent = 1;
for(auto it : adjP[root]){
isConsistent &= dfs(it, 'H');
}
for(auto it : adjH[root]){
isConsistent &= dfs(it, 'P');
}
return isConsistent;
}
return 1;
}
int getParasiteCnt(int root){
vis[root] = 1;
int ans = (assigned[root] == 'P');
for(auto it : adj[root]){
if(!vis[it]){
ans += getParasiteCnt(it);
}
}
return ans;
}
void clearOnlyVis(int root){
vis[root] = 0;
for(auto it : adj[root]){
if(vis[it]){
clearOnlyVis(it);
}
}
}
void clearVisAssigned(int root){
vis[root] = 0;
assigned[root] = 'N';
for(auto it : adj[root]){
if(vis[it]){
clearVisAssigned(it);
}
}
}
int main(){
fast();
int t;
cin >> t;
while(t--){
int n, m;
cin >> n >> m;
for(int i = 0; i <= n; ++i){
adjP[i].clear();
adjH[i].clear();
adj[i].clear();
assigned[i] = 'N';
vis[i] = 0;
}
for(int i = 0; i < m; ++i){
int type, u, v;
cin >> type >> u >> v;
if(type == 1){
adjP[u].push_back(v);
adjP[v].push_back(u);
}
else{
adjH[u].push_back(v);
adjH[v].push_back(u);
}
adj[u].push_back(v);
adj[v].push_back(u);
}
int ans = 0;
bool ok = 1;
bool cons = 1;
for(int i = 1; i <= n; ++i){
if(!vis[i]){
int cnt = -1;
ok = dfs(i, 'H');
clearOnlyVis(i);
if(ok){
cnt = getParasiteCnt(i);
}
clearVisAssigned(i);
ok = dfs(i, 'P');
clearOnlyVis(i);
if(ok){
cnt = max(cnt, getParasiteCnt(i));
}
if(cnt == -1){
cons = 0;
break;
}
ans += cnt;
}
}
if(!cons){
cout << -1 << "\n";
}
else cout << ans << "\n";
}
return 0;
}