#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
const long long inf = 1ll << 50;
const long long maxn = 100005;
struct scc {
  vector<vector<long long>> g, gt;
  vector<bool> used;
  vector<int> order;
  scc(vector<vector<long long>> &g) {
    this->g = g;
    gt.resize(g.size(), vector<long long>());
    for (int i = 0; i < g.size(); i++) {
      auto it = g[i];
      for (auto it1 : it) {
        gt[it1].push_back(i);
      }
    }
  }
  void dfs1(long long node) {
    used[node] = true;
    for (auto it : g[node]) {
      if (!used[it]) dfs1(it);
    }
    order.push_back(node);
  }
  void dfs2(long long node, long long cl, vector<int> &components) {
    used[node] = true;
    components[node] = cl;
    for (auto it : gt[node]) {
      if (!used[it]) {
        dfs2(it, cl, components);
      }
    }
  }
  vector<int> get_components() {
    used.assign(g.size(), false);
    for (int i = 0; i < g.size(); i++) {
      if (!used[i]) {
        dfs1(i);
      }
    }
    used.assign(g.size(), false);
    vector<int> components(g.size(), 0);
    for (int cnt = 0; order.size();) {
      auto val = order.back();
      order.pop_back();
      if (!used[val]) {
        dfs2(val, cnt++, components);
      }
    }
    return components;
  }
};
struct Tsat {
  enum bool_ops {
    OR,
    XOR,
    IFF,
  };
  vector<vector<long long>> g;
  function<int(int)> neg;
  vector<int> components;
  Tsat(
      int n, function<int(int)> func = [](int x) { return x ^ 1; }) {
    g.resize(n << 1, vector<long long>());
    neg = func;
  }
  vector<pair<long long, long long>> get_inference_edges(long long a,
                                                         long long b,
                                                         bool_ops operation) {
    if (operation == bool_ops::OR) {
      return {{neg(a), b}, {neg(b), a}};
    } else if (operation == bool_ops::XOR) {
      return {{a, neg(b)}, {b, neg(a)}, {neg(a), b}, {neg(b), a}};
    } else if (operation == bool_ops::IFF) {
      return {{a, b}, {neg(a), neg(b)}, {b, a}, {neg(b), neg(a)}};
    }
  }
  void add_clause(long long var1, long long var2, bool_ops operation) {
    for (auto it : get_inference_edges(var1, var2, operation)) {
      g[it.first].push_back(it.second);
    }
  }
  vector<int> *find_components() {
    if (components.empty()) {
      components = scc(g).get_components();
    }
    return &components;
  }
  vector<bool> find_solution() {
    vector<bool> assignment;
    assignment.assign(g.size() >> 1, false);
    vector<int> components = *find_components();
    for (int i = 0; i < g.size(); i += 2) {
      if (components[i] == components[i + 1]) {
        return vector<bool>();
      }
      assignment[i >> 1] = components[i] > components[i + 1];
    }
    return assignment;
  }
  vector<bool> find_second_solution() {
    vector<int> components = *find_components();
    int num_comp = *max_element(components.begin(), components.end()) + 1;
    vector<bool> comp_val(num_comp, false);
    for (int i = 0; i < g.size(); i += 2) {
      long long val = max(components[i], components[i + 1]);
      comp_val[val] = true;
    }
    vector<bool> comp_check(num_comp, true);
    for (int i = 0; i < g.size(); i += 2) {
      long long val = comp_val[components[i]] ? i + 1 : i;
      comp_check[components[val ^ 1]] = false;
      for (auto it : g[val]) {
        if (components[it] == components[val ^ 1] ||
            !comp_val[components[it]]) {
          comp_check[components[val]] = false;
        }
      }
    }
    auto find_it = find(comp_check.begin(), comp_check.end(), true);
    if (find_it == comp_check.end()) {
      return vector<bool>();
    }
    long long to_swap = find_it - comp_check.begin();
    vector<bool> assignment;
    assignment.assign(g.size() >> 1, false);
    for (int i = 0; i < g.size(); i += 2) {
      if (components[i] == to_swap) {
        assignment[i >> 1] = true;
        continue;
      } else if (components[i + 1] == to_swap) {
        assignment[i >> 1] = false;
        continue;
      }
      assignment[i >> 1] = components[i] > components[i + 1];
    }
    return assignment;
  }
};
bool solve(Tsat t_sat) {
  auto sol = t_sat.find_solution();
  auto val = sol[0];
  if (all_of(sol.begin(), sol.end(), [&val](bool v) { return v == val; })) {
    sol = t_sat.find_second_solution();
  }
  if (sol.size() == 0) {
    return 0;
  }
  cout << "Yes"
       << "\n";
  vector<int> ans[2];
  for (int i = 0; i < sol.size(); i++) {
    ans[sol[i]].push_back(i + 1);
  }
  cout << ans[1].size() << " " << ans[0].size() << "\n";
  for (auto it : ans[1]) {
    cout << it << " ";
  }
  cout << "\n";
  for (auto it : ans[0]) {
    cout << it << " ";
  }
  cout << "\n";
  return 1;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long t;
  cin >> t;
  while (t--) {
    long long n, m;
    cin >> n >> m;
    auto t_sat = Tsat(n);
    for (int i = 0; i < m; i++) {
      long long a, b;
      cin >> a >> b;
      if (a == b) continue;
      a--, b--;
      t_sat.add_clause((a << 1) | 1, b << 1, Tsat::bool_ops::OR);
    }
    t_sat.add_clause(0, 0, Tsat::bool_ops::OR);
    if (solve(t_sat)) {
      continue;
    } else {
      t_sat.g[1].pop_back();
      t_sat.g[1].pop_back();
      t_sat.components.clear();
    }
    t_sat.add_clause(1, 1, Tsat::bool_ops::OR);
    if (solve(t_sat)) {
      continue;
    }
    cout << "No"
         << "\n";
  }
  return 0;
}
