#include <bits/stdc++.h>
using namespace std;
struct V {
  vector<pair<int, int> > outs;
};
vector<int> adj[212];
int comp[212];
int degree[212];
int vis[212];
set<pair<int, int> > created_edge;
int find_src(vector<V>& vertices) {
  int src = 0;
  for (int i = 0; i < (int)vertices.size(); i++) {
    if (vertices[i].outs.size() & 1) {
      src = i;
      break;
    }
    if (vertices[i].outs.size()) src = i;
  }
  return src;
}
bool check_condition(vector<V>& vertices) {
  int c = 0;
  for (auto& n : vertices) c += (n.outs.size() & 1);
  return (c == 2 || c == 0);
}
vector<int> euler_tour(vector<V>& vertices, int n_edges, int src = -1) {
  if (!check_condition(vertices)) return {};
  if (src == -1) {
    src = find_src(vertices);
  }
  vector<vector<pair<int, int> >::iterator> its;
  for (auto& n : vertices) {
    its.push_back(n.outs.begin());
  }
  vector<int> eu(n_edges);
  vector<int> ret, s = {src};
  while (!s.empty()) {
    int x = s.back();
    auto &it = its[x], end = vertices[x].outs.end();
    while (it != end && eu[it->second]) ++it;
    if (it == end) {
      ret.push_back(x);
      s.pop_back();
    } else {
      s.push_back(it->first);
      eu[it->second] = true;
    }
  }
  if (ret.size() != n_edges + 1) ret.clear();
  reverse(ret.begin(), ret.end());
  return ret;
}
void dfs(int u, int color) {
  vis[u] = 1;
  comp[u] = color;
  for (int v : adj[u])
    if (!vis[v]) dfs(v, color);
}
int main() {
  int q;
  scanf("%d", &q);
  while (q--) {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
      int u, v;
      scanf("%d%d", &u, &v);
      --u, --v;
      adj[u].push_back(v);
      adj[v].push_back(u);
      degree[u]++;
      degree[v]++;
    }
    int color = 0;
    for (int i = 0; i < n; i++) {
      if (!vis[i]) {
        dfs(i, color);
        color++;
      }
    }
    int evens = 0;
    for (int i = 0; i < color; i++) {
      vector<int> odds;
      for (int j = 0; j < n; j++) {
        if (comp[j] == i) {
          if (degree[j] & 1)
            odds.push_back(j);
          else
            ++evens;
        }
      }
      for (int j = 0; j < (int)odds.size(); j += 2) {
        adj[odds[j]].push_back(odds[j + 1]);
        adj[odds[j + 1]].push_back(odds[j]);
        created_edge.insert(
            {min(odds[j], odds[j + 1]), max(odds[j], odds[j + 1])});
      }
    }
    printf("%d\n", evens);
    vector<int> vertice_id(n);
    vector<int> id_2_vertice(n);
    for (int i = 0; i < color; i++) {
      vector<V> vertices;
      for (int j = 0; j < n; j++) {
        if (comp[j] == i) {
          V u;
          vertice_id[j] = vertices.size();
          id_2_vertice[vertices.size()] = j;
          vertices.push_back(u);
        }
      };
      int edge_id = 0;
      for (int j = 0; j < n; j++) {
        if (comp[j] == i) {
          for (int v : adj[j]) {
            if (v > j) {
              vertices[vertice_id[v]].outs.push_back({vertice_id[j], edge_id});
              vertices[vertice_id[j]].outs.push_back(
                  {vertice_id[v], edge_id++});
            }
          }
        }
      }
      auto res = euler_tour(vertices, edge_id);
      for (int j = 0; j < (int)res.size() - 1; j++) {
        int a = id_2_vertice[res[j]];
        int b = id_2_vertice[res[j + 1]];
        auto it = created_edge.find({min(a, b), max(a, b)});
        if (it == created_edge.end())
          printf("%d %d\n", a + 1, b + 1);
        else
          created_edge.erase(it);
      }
    }
    for (int i = 0; i < n; i++) {
      adj[i].clear();
      vis[i] = degree[i] = comp[i] = 0;
    }
    created_edge.clear();
  }
}
