#include <bits/stdc++.h>
using namespace std;
void top_dfs(int src, vector<vector<int> >& directed_graph, vector<int>& vis,
             vector<int>& top_order) {
  vis[src] = 1;
  for (int i = 0; i < directed_graph[src].size(); i++) {
    if (vis[directed_graph[src][i]] == 0) {
      top_dfs(directed_graph[src][i], directed_graph, vis, top_order);
    }
  }
  top_order.push_back(src);
}
void solve() {
  int n, m;
  cin >> n >> m;
  vector<int> vis(n + 1, 0);
  vector<vector<int> > directed_graph(n + 1);
  vector<int> top_order;
  vector<pair<int, int> > edges;
  for (int i = 0; i < m; i++) {
    int t, u, v;
    cin >> t >> u >> v;
    if (t == 1) {
      directed_graph[u].push_back(v);
    }
    edges.push_back(make_pair(u, v));
  }
  for (int i = 1; i <= n; i++) {
    if (vis[i] == 0) top_dfs(i, directed_graph, vis, top_order);
  }
  reverse(top_order.begin(), top_order.end());
  int pos[n + 1];
  for (int i = 1; i <= n; i++) {
    pos[top_order[i - 1]] = i;
  }
  for (int i = 1; i <= n; i++) {
    int u = i;
    for (int j = 0; j < directed_graph[i].size(); j++) {
      int v = directed_graph[i][j];
      if (pos[u] > pos[v]) {
        cout << "NO" << endl;
        return;
      }
    }
  }
  cout << "YES" << endl;
  for (int i = 0; i < m; i++) {
    int x = edges[i].first, y = edges[i].second;
    if (pos[x] < pos[y]) {
      cout << x << " " << y << endl;
    }
    if (pos[y] < pos[x]) {
      cout << y << " " << x << endl;
    }
  }
}
int main() {
  int t;
  cin >> t;
  for (int i = 0; i < t; i++) solve();
  return 0;
}
