#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using si = set<int>;
using usi = unordered_set<int>;
vvi g;
vi ord, pos, in_edges;
vector<pii> edge_list;
vector<bool> used;
int t, d, n, m, from, to;
void dfs(int node) {
  used[node] = true;
  for (int to : g[node]) {
    if (!used[to]) dfs(to);
  }
  ord.push_back(node);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> t;
  while (t--) {
    cin >> n >> m;
    g.assign(n + 1, vector<int>()), used.assign(n + 1, false),
        pos.assign(n + 1, 0);
    edge_list.clear();
    for (int i = 0; i < (int)m; i++) {
      cin >> d >> from >> to;
      if (d) {
        g[from].push_back(to);
      }
      edge_list.push_back({from, to});
    }
    ord.assign(1, 0);
    for (int i = 1; i < (int)n + 1; i++) {
      if (!used[i]) dfs(i);
    }
    reverse(ord.begin(), ord.end());
    for (int i = 1; i < (int)n + 1; i++) {
      pos[ord[i]] = i;
    }
    bool bad = false;
    for (int i = 1; i < (int)n + 1; i++) {
      for (int to : g[i]) {
        if (pos[to] < pos[i]) {
          bad = true;
          break;
        }
      }
      if (bad) break;
    }
    if (bad) {
      cout << "NO" << '\n';
      continue;
    }
    cout << "YES" << '\n';
    for (auto p : edge_list) {
      int from, to;
      tie(from, to) = p;
      if (pos[from] < pos[to])
        cout << from << ' ' << to << '\n';
      else
        cout << to << ' ' << from << '\n';
    }
  }
}
