#include <bits/stdc++.h>
using namespace std;
const long double PI = 3.14159265358979323846;
vector<vector<int>> adj;
vector<int> top_sort;
vector<int> in_count;
int n, m;
bool np;
vector<bool> visited;
void Topsort() {
  set<pair<int, int>> s;
  for (int i = 1; i <= n; i++) {
    s.insert({in_count[i], i});
  }
  while (!s.empty()) {
    int v = s.begin()->second;
    s.erase({in_count[v], v});
    if (in_count[v] != 0) {
      np = true;
      return;
    }
    top_sort.push_back(v);
    for (int x : adj[v]) {
      s.erase({in_count[x], x});
      in_count[x]--;
      s.insert({in_count[x], x});
    }
  }
}
int main() {
  ;
  int t;
  cin >> t;
  while (t--) {
    adj.clear();
    top_sort.clear();
    in_count.clear();
    cin >> n >> m;
    adj.resize(n + 1);
    in_count.resize(n + 1, 0);
    vector<pair<int, int>> undir;
    np = false;
    for (int i = 0; i < m; i++) {
      int e, a, b;
      cin >> e >> a >> b;
      if (e == 0) {
        undir.push_back({a, b});
      } else {
        adj[a].push_back(b);
        in_count[b]++;
      }
    }
    Topsort();
    if (np) {
      cout << "NO\n";
      continue;
    }
    vector<int> pos(n + 1);
    for (int i = 0; i < n; i++) pos[top_sort[i]] = i;
    cout << "YES\n";
    for (auto e : undir) {
      if (pos[e.first] > pos[e.second]) swap(e.first, e.second);
      cout << e.first << " " << e.second << "\n";
    }
    for (int i = 0; i <= n; i++)
      for (int x : adj[i]) cout << i << " " << x << "\n";
  }
  return 0;
}
