#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
vector<int>graph[MAXN], colour[MAXN], idx[MAXN], marc(MAXN), in[MAXN], out[MAXN], edges;
vector<pair<pair<int, int>, int>>e;
bool ok;
void ans(int find_x, int find_c){
vector<int>resp;
while(true){
int at=edges[edges.size()-1];
edges.pop_back();
resp.push_back(at);
if(find_x==e[at-1].first.first and find_c==e[at-1].second){
cout<<"YES"<<endl<<resp.size()<<' ';
for(int k=resp.size()-1;k>=0;k--){
cout<<resp[k]<<' ';
}
cout<<endl;
edges.clear();
return;
}
}
}
void dfs(int x, int c){
marc[x]++;
in[x].push_back(c);
if(marc[x]==3){
return;
}
for(int k=0;k<graph[x].size();k++){
int neighbour=graph[x][k], next_c=colour[x][k];
if(next_c==c){
continue;
}
edges.push_back(idx[x][k]);
for(int i=0;i<out[neighbour].size();i++){
if(out[neighbour][i]!=next_c){
ans(neighbour, out[neighbour][i]);
ok=1;
return;
}
}
if(marc[neighbour]<3){
auto it=lower_bound(in[neighbour].begin(), in[neighbour].end(), c);
if(it!=in[neighbour].end() and *it==c){
continue;
}
out[x].push_back(next_c);
dfs(neighbour, next_c);
if(ok){
return;
}
out[x].pop_back();
}
edges.pop_back();
}
}
int main(){
cin.tie(0)->sync_with_stdio(0);
int t;
cin>>t;
while(t--){
int n, m;
cin>>n>>m;
for(int k=1;k<=n;k++){
graph[k].clear();
colour[k].clear();
idx[k].clear();
out[k].clear();
in[k].clear();
marc[k]=0;
}
e.clear();
ok=0;
for(int k=0;k<m;k++){
int a, b, c;
cin>>a>>b>>c;
e.push_back({{a, b}, c});
idx[a].push_back(k+1);
graph[a].push_back(b);
colour[a].push_back(c);
}
for(int k=1;k<=n;k++){
if(marc[k]<3){
dfs(k, 0);
}
if(ok){
break;
}
}
if(!ok){
cout<<"NO"<<endl;
}
}
}