#include <bits/stdc++.h>
using namespace std;
vector<long long int> g[1000005];
vector<long long int> sorted;
long long int possible;
void topsort(long long int u, bool vis[], set<long long int>& ansis) {
  vis[u] = 1;
  ansis.insert(u);
  for (auto j : g[u]) {
    if (ansis.count(j)) {
      possible = 0;
      return;
    }
    if (!vis[j]) {
      topsort(j, vis, ansis);
    }
  }
  ansis.erase(u);
  sorted.push_back(u);
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long int _;
  cin >> _;
  while (_--) {
    long long int n, m;
    cin >> n >> m;
    long long int i;
    for (i = 0; i <= n; i++) {
      g[i].clear();
    }
    sorted.clear();
    vector<pair<long long int, long long int> > und, dir;
    possible = 1;
    for (i = 0; i < m; i++) {
      long long int t, u, v;
      cin >> t >> u >> v;
      if (t == 1) {
        dir.push_back({u, v});
        g[u].push_back(v);
      } else {
        und.push_back({u, v});
      }
    }
    bool vis[n + 1];
    memset(vis, 0, sizeof vis);
    for (i = 1; i <= n; i++) {
      set<long long int> ansis;
      if (!vis[i]) {
        topsort(i, vis, ansis);
      }
    }
    if (possible == 0) {
      cout << "NO" << endl;
      ;
      continue;
    }
    map<long long int, long long int> index;
    for (i = 0; i < sorted.size(); i++) {
      index[sorted[i]] = i;
    }
    if (possible) {
      cout << "YES" << endl;
      ;
      for (auto& j : dir) {
        cout << j.first << " " << j.second << endl;
      }
      for (auto& j : und) {
        long long int x = index[j.first];
        long long int y = index[j.second];
        if (x > y) {
          cout << j.first << " " << j.second << endl;
        } else {
          cout << j.second << " " << j.first << endl;
        }
      }
    }
  }
  return 0;
}
