#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void program();
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  program();
}
const int MX = 5e5;
int testCases;
int n, m;
set<int> adj[MX];
vector<int> ex[MX], rev[MX];
bitset<MX> visited;
int cnt[MX];
void dfs(int u) {
  if (visited[u]) return;
  visited[u] = 1;
  for (int v : adj[u]) {
    adj[v].erase(u);
    ex[v].push_back(u);
    rev[u].push_back(v);
  }
  adj[u].clear();
  for (int v : rev[u]) cnt[v]++;
  for (int v : rev[u])
    if (cnt[v] == ex[v].size()) dfs(v);
}
int col[MX];
bool pos;
void proc(int u) {
  if (col[u] == 1) {
    pos = 0;
    return;
  }
  col[u] = 1;
  for (int v : ex[u]) {
    if (col[v] == 2) continue;
    proc(v);
    if (!pos) return;
  }
  col[u] = 2;
}
void program() {
  cin >> testCases;
  while (testCases--) {
    cin >> n >> m;
    for (int i = int(1); i < int(n + 1); i++) cnt[i] = 0;
    for (int i = int(1); i < int(n + 1); i++) ex[i].clear();
    for (int i = int(1); i < int(n + 1); i++) adj[i].clear();
    for (int i = int(1); i < int(n + 1); i++) rev[i].clear();
    for (int i = int(0); i < int(m); i++) {
      int t, u, v;
      cin >> t >> u >> v;
      if (!t) {
        adj[u].insert(v);
        adj[v].insert(u);
      } else {
        ex[u].push_back(v);
        rev[v].push_back(u);
      }
    }
    for (int i = int(1); i < int(n + 1); i++) visited[i] = 0;
    for (int i = int(1); i < int(n + 1); i++)
      if (ex[i].size() == cnt[i]) dfs(i);
    pos = 1;
    for (int i = int(1); i < int(n + 1); i++) col[i] = 0;
    for (int i = int(1); i < int(n + 1); i++)
      if (adj[i].size()) pos = 0;
    for (int i = int(1); i < int(n + 1); i++) proc(i);
    cout << (pos ? "Yes" : "No") << endl;
    if (pos)
      for (int u = int(1); u < int(n + 1); u++) {
        for (int v : ex[u]) cout << u << " " << v << endl;
      }
  }
}
