#include <bits/stdc++.h>
using namespace std;
class Graph {
  int v;
  vector<vector<int>> adj;

 public:
  bool cyclic = false;
  Graph(int v);
  void addEdge(int u, int v);
  bool topological(int v, vector<bool>& visited, stack<int>& st,
                   vector<bool>& instack);
  void printEdges();
};
Graph::Graph(int v) {
  this->v = v;
  adj.resize(v + 1);
}
void Graph::addEdge(int u, int v) { adj[u].push_back(v); }
bool Graph::topological(int v, vector<bool>& visited, stack<int>& st,
                        vector<bool>& instack) {
  visited[v - 1] = true;
  instack[v - 1] = true;
  for (int x : adj[v]) {
    if (instack[x - 1]) {
      return false;
    }
    if (!visited[x - 1])
      if (!topological(x, visited, st, instack)) return false;
  }
  instack[v - 1] = false;
  st.push(v);
  return true;
}
void Graph::printEdges() {
  for (int i = 1; i <= v; i++) {
    for (int x : adj[i]) {
      cout << i << " " << x << "\n";
    }
  }
}
void solve() {
  int n, m, u, v, t;
  cin >> n >> m;
  Graph g(n);
  vector<pair<int, int>> undirected;
  for (int i = 0; i < m; i++) {
    cin >> t >> u >> v;
    if (t == 0)
      undirected.push_back({u, v});
    else
      g.addEdge(u, v);
  }
  vector<bool> visited(n, false);
  stack<int> st;
  vector<bool> instack(n, false);
  for (int i = 1; i <= n; i++) {
    if (visited[i - 1] == false)
      if (!g.topological(i, visited, st, instack)) {
        cout << "NO\n";
        return;
      }
  }
  cout << "YES\n";
  vector<int> posTopo(n);
  int pos = 0;
  while (!st.empty()) {
    posTopo[st.top() - 1] = pos++;
    st.pop();
  }
  for (int i = 0; i < undirected.size(); i++) {
    u = undirected[i].first;
    v = undirected[i].second;
    if (posTopo[u - 1] > posTopo[v - 1]) {
      g.addEdge(v, u);
    } else
      g.addEdge(u, v);
  }
  g.printEdges();
}
int main() {
  ios_base::sync_with_stdio(false);
  int t = 1;
  cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}
