#include <bits/stdc++.h>
using namespace std;
struct aresta{
int viz,cor,id;
bool operator <(aresta b){
return cor < b.cor;
}
};
#define fi first
#define sc second
#define sz(v) (int)v.size()
const int MAXN = 1e6+5;
vector< aresta > in[MAXN], out[MAXN];
vector< pair<int,int> > adj[MAXN];
map< pair<int,int>, int > mp;
vector<int> ans;
int marc[MAXN], fim;
bool dfs(int s){
marc[s] = 1;
for(auto[viz,id] : adj[s]){
if(marc[viz] == 1){
if(id != 0)ans.push_back(id);
fim = viz;
return true;
}
bool b = dfs(viz);
if(b){
if(fim > 0 && id != 0)ans.push_back(id);
if(fim == s)fim = 0;
return true;
}
}
marc[s] = 2;
return false;
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int t; cin>>t;
while(t--){
int n,m; cin>>n>>m;
for(int i = 1; i <= m; i++){
int a,b,c; cin>>a>>b>>c;
aresta aux; aux.viz = b; aux.cor = c; aux.id = i;
out[a].push_back(aux);
aux.viz = a; aux.cor = c; aux.id = i;
in[b].push_back(aux);
}
int novo = 0;
for(int i = 1; i <= n; i++){
sort(out[i].begin(), out[i].end());
for(int j = 0; j < sz(out[i]); j++)
if(j == 0 || out[i][j-1].cor != out[i][j].cor ) mp[{i,out[i][j].cor}] = ++novo;
}
for(int i = 1; i <= n; i++){
if(sz(in[i]) == 0)continue;
sort(in[i].begin(), in[i].end());
map< int, int > cg;
int rz = sqrt(sz(in[i]));
vector<int> g;
int ini = 0, grupo = 0, tam = 0;
for(int j = 0; j <= sz(in[i]); j++){
if(j == sz(in[i]) || in[i][j].cor != in[i][ini].cor ){
if(grupo == 0 || tam >= rz || j-ini >= rz){tam = 0; grupo = ++novo; g.push_back(grupo);}
cg[ in[i][ini].cor ] = grupo;
tam += j-ini; ini = j;
}
}
vector<int> c;
for(int j = 0; j < sz(out[i]); j++)
if(j == 0 || out[i][j-1].cor != out[i][j].cor )c.push_back( out[i][j].cor );
for(int x : g){
for(int y : c)
if( cg[ y ] != x)adj[x].emplace_back( mp[{i,y}], 0 );
}
for(int j = 0; j < sz(in[i]); j++){
adj[ mp[ {in[i][j].viz, in[i][j].cor} ] ].emplace_back( cg[ in[i][j].cor ], in[i][j].id );
for(int x : c)
if(cg[ x ] == cg[ in[i][j].cor ] && x != in[i][j].cor)
adj[ mp[ {in[i][j].viz, in[i][j].cor} ] ].emplace_back( mp[{i,x}], 0 );
}
}
for(int i = 1; i <= novo; i++)
if(!marc[i] && dfs(i))break;
if(sz(ans) > 0){
cout<<"YES\n";
cout<<sz(ans)<<" ";
for(int i = sz(ans)-1; i >= 0; i--)cout<<ans[i]<<" ";
cout<<"\n";
}else cout<<"NO\n";
mp.clear(); ans.clear();
for(int i = 1; i <= n; i++){
in[i].clear(); out[i].clear();
}
for(int i = 1; i <= novo; i++){
marc[i] = 0;
adj[i].clear();
}
}
}