#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1000000000;
const ll LINF = 1001002003004005006ll;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
struct IOSetup {
  IOSetup() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << fixed << setprecision(12);
  }
} iosetup;
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++)
    os << v[i] << (i + 1 == v.size() ? "" : " ");
  return os;
}
struct StronglyConnectedComponents {
  vector<vector<int>> g;
  vector<vector<int>> to, from;
  vector<int> comp, order, used;
  StronglyConnectedComponents(vector<vector<int>> &g)
      : g(g), to(g.size()), from(g.size()), comp(g.size(), -1), used(g.size()) {
    for (int i = 0; i < g.size(); i++) {
      for (auto x : g[i]) {
        to[i].push_back(x);
        from[x].push_back(i);
      }
    }
  }
  int operator[](int k) { return comp[k]; }
  void dfs(int now) {
    if (used[now]) return;
    used[now] = true;
    for (int x : to[now]) dfs(x);
    order.push_back(now);
  }
  void rdfs(int now, int cnt) {
    if (comp[now] != -1) return;
    comp[now] = cnt;
    for (int x : from[now]) rdfs(x, cnt);
  }
  vector<vector<int>> build() {
    vector<vector<int>> t;
    for (int i = 0; i < to.size(); i++) dfs(i);
    reverse(order.begin(), order.end());
    int ptr = 0;
    for (int i : order)
      if (comp[i] == -1) rdfs(i, ptr), ptr++;
    t.resize(ptr);
    for (int i = 0; i < g.size(); i++) {
      for (auto v : to[i]) {
        int x = comp[i], y = comp[v];
        if (x == y) continue;
        t[x].push_back(y);
      }
    }
    return t;
  }
};
using P = pair<int, int>;
using T = tuple<int, int, int>;
void solve() {
  int n, m;
  cin >> n >> m;
  vector<T> es;
  vector<vector<int>> g(n);
  for (int i = 0; i < (m); i++) {
    int t, u, v;
    cin >> t >> u >> v;
    u--, v--;
    if (t) {
      g[u].push_back(v);
    }
    es.push_back(T(u, v, t));
  }
  StronglyConnectedComponents scc(g);
  auto t = scc.build();
  if (t.size() != n) {
    cout << "NO" << endl;
    return;
  }
  set<P> st;
  vector<P> ans;
  for (auto [u, v, t] : es) {
    if (t) {
      ans.push_back(P(u + 1, v + 1));
      continue;
    }
    if (scc[u] > scc[v]) swap(u, v);
    if (st.count(P(v, u))) {
      cout << "NO" << endl;
      return;
    }
    ans.push_back(P(u + 1, v + 1));
  }
  cout << "YES" << endl;
  for (auto p : ans) cout << p << endl;
}
signed main() {
  int q;
  cin >> q;
  while (q--) solve();
  return 0;
}
