#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
template <class T>
inline T gcd(T x, T y) {
  return y ? gcd(y, x % y) : x;
}
template <class T>
inline T lcm(T x, T y) {
  return x / gcd(x, y) * y;
}
template <class T>
inline void adj(T &x, T y) {
  if (x >= y) x %= y;
  while (x < 0) x += y;
}
template <class T>
inline T qpow(T x, long long y, T z) {
  for (; y; y >>= 1, x = x * x)
    if (y & 1) z = z * x;
  return z;
}
template <class T>
inline T mpow(long long w, T x, long long y, T z) {
  for (; y; y >>= 1, x = x * x, x = x % w)
    if (y & 1) z = z * x, z = z % w;
  return z;
}
const long long MOD = 998244353LL;
const int M = 5000005;
const int N = 300005;
int _, n, m, dep[N], t, tt, d[N], op, ed;
long long er[N], ans;
vector<int> g[N];
inline int bfs(int x) {
  dep[x] = 1;
  d[1] = x;
  for (op = ed = 1; op <= ed; op++) {
    int now = d[op];
    for (auto &j : g[now])
      if (dep[j] < 0) {
        dep[j] = dep[now] + 1;
        d[++ed] = j;
      } else if (!((dep[j] + dep[now]) & 1))
        return 0;
  }
  return 1;
}
int main() {
  er[0] = 1LL;
  for (int i = 1; i < N; i++) er[i] = er[i - 1] * 2 % MOD;
  for (scanf("%d", &_); _; _--) {
    scanf("%d %d", &n, &m);
    ans = 1;
    for (int i = 1; i <= n; i++) {
      dep[i] = -1;
      vector<int>().swap(g[i]);
    }
    for (int i = 1; i <= m; i++) {
      scanf("%d %d", &t, &tt);
      g[t].push_back(tt);
      g[tt].push_back(t);
    }
    for (int i = 1; i <= n; i++)
      if (dep[i] < 0) {
        if (bfs(i)) {
          t = tt = 0;
          for (int j = 1; j <= ed; j++)
            if (dep[d[j]] & 1)
              t++;
            else
              tt++;
          ans = ans * (er[t] + er[tt]) % MOD;
        } else
          ans = 0;
      }
    for (int i = 1; i <= n; i++)
      if (dep[i] < 0) ans = ans * 3 % MOD;
    printf("%I64d\n", ans);
  }
  return 0;
}
