#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vd = vector<ld>;
using vpi = vector<pi>;
using vpl = vector<pl>;
const int N = 300010;
const int mod = 998244353;
const ld PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 1e18;
template <typename T>
inline void gmax(T &A, T B) {
  (A < B) && (A = B);
}
template <typename T>
inline void gmin(T &A, T B) {
  (A > B) && (A = B);
}
int n, m, t, cnt1, cnt2, ans;
int col[N];
bool ok;
vi g[N];
void dfs(int u, int k) {
  if (col[u]) {
    if (col[u] != k) ok = false;
    return;
  }
  if (k == 1)
    cnt1++;
  else
    cnt2++;
  col[u] = k;
  for (auto x : g[u]) dfs(x, k & 1 ? 2 : 1);
}
ll qpow(ll x, ll k) {
  ll res = 1;
  for (x %= mod; k; k >>= 1, x = x * x % mod)
    if (k & 1) res = res * x % mod;
  return res;
}
int main() {
  {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
  }
  int T;
  for (cin >> T; T--;) {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) g[i].clear(), col[i] = 0;
    while (m--) {
      int u, v;
      cin >> u >> v;
      g[u].push_back(v), g[v].push_back(u);
    }
    ok = true;
    ans = 1;
    for (int i = 1; i <= n; i++) {
      if (!col[i]) {
        cnt1 = cnt2 = 0, dfs(i, 1);
        if (cnt1 != 0 && cnt2 != 0)
          ans =
              ans * (qpow(2LL, cnt1 * 1LL) + qpow(2LL, cnt2 * 1LL) % mod) % mod;
        else
          ans = ans * 3LL % mod;
      }
      if (!ok) break;
    }
    if (!ok) ans = 0;
    cout << ans << endl;
  }
  return 0;
}
