#ifdef DEBUG
#  define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include "testlib.h"
#define ff first
#define ss second
#define szof(x) ((int)x.size())
#ifndef LOCAL
#  define cerr __get_ce
#endif

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef unsigned long long ull;

using namespace __gnu_pbds;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using ordered_map = tree<K, V, less<K>, rb_tree_tag, tree_order_statistics_node_update>;

int const INF = (int)1e9 + 1e3;
ll const INFL = (ll)1e18 + 1e6;

const int MINT = 1;
const int MAXT = (int) 1e4;

const int MINN = 2;
const int MAXN = (int) 1e5;

const int MINM = 1;
const int MAXM = (int) 2e5;

int main(int argc, char* argv[]) {
  registerValidation(argc, argv);

  int t = inf.readInt(MINT, MAXT, "t");
  inf.readEoln();

  int sum_n = 0;
  int sum_m = 0;

  for (int q = 1; q <= t; q++) {
    setTestCase(q);
    int n = inf.readInt(MINN, MAXN, "n");
    inf.readSpace();
    int m = inf.readInt(MINM, MAXM, "m");
    inf.readEoln();
    sum_n += n;
    ensuref(sum_n <= MAXN, "sum of n is too large: %d > %d", sum_n, MAXN);
    sum_m += m;
    ensuref(sum_m <= MAXM, "sum of m is too large: %d > %d", sum_m, MAXM);
    set<pair<int, int>> s;
    for (int i = 0; i < m; i++) {
      int u = inf.readInt(1, n, "u_" + to_string(i + 1));
      inf.readSpace();
      int v = inf.readInt(1, n, "v_" + to_string(i + 1));
      inf.readEoln();
      ensuref(u != v, "loop found: %d-%d", u, v);
      auto p = make_pair(u, v);
      ensuref(s.find(p) == s.end(), "duplicate edge: %d-%d", u, v);
      s.insert(p);
    }
  }

  inf.readEof();

  return 0;
}
