#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
vector<int> *mapo;
long long Montgomery(long long a, long long b) {
  long long ans = 1;
  a = a % mod;
  while (b > 0) {
    if (b & 1) ans = ans * a % mod;
    b >>= 1;
    a = a * a % mod;
  }
  return ans;
}
bool inQueue[size_t(3e5 + 10)];
int status[size_t(3e5 + 10)];
long long dfs_detect_possibility(int, int);
int main() {
  int t;
  scanf("%d", &t);
  for (int i = 0; i < t; ++i) {
    int n, m;
    scanf("%d%d", &n, &m);
    fill(inQueue, inQueue + n + 2, false);
    fill(status, status + n + 2, -1);
    vector<int> links[n + 1];
    mapo = links;
    for (int j = 0; j < m; ++j) {
      int t1, t2;
      scanf("%d%d", &t1, &t2);
      links[t1].push_back(t2);
      links[t2].push_back(t1);
    }
    long long ans = 1;
    for (int j = 1; j <= n; j++) {
      if (inQueue[j]) continue;
      ans = ans * dfs_detect_possibility(n, j) % mod;
    }
    cout << ans << endl;
  }
  return 0;
}
long long dfs_detect_possibility(int n, int st) {
  int same = 1;
  status[st] = 1;
  queue<int> q;
  q.push(st);
  inQueue[st] = true;
  long long dans = 1;
  int cnt = 1;
  while (!q.empty()) {
    int poi = q.front();
    q.pop();
    for (int &i : mapo[poi]) {
      if (status[i] == status[poi]) {
        return 0;
      } else if (status[i] == -1) {
        cnt++;
        if (status[poi] == 1)
          status[i] = 0;
        else {
          status[i] = 1;
          same++;
        }
        q.push(i);
        inQueue[i] = true;
      }
    }
  }
  dans = Montgomery(2, same) + Montgomery(2, cnt - same);
  return dans % mod;
}
