#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
ll cheng[N];
int cnt=1;
ll gee[N];
ll ge=0;
ll mul[N];
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(beg);
	while(!q.empty()) {
		int now=q.front();
		q.pop();
		ll len=v[now].size();
		ff(i,0,len-1) {
			if(vis[v[now][i]]==0) {
				ge++;
				vis[v[now][i]]=1;
				ran[v[now][i]]=!ran[now];
				if(ran[v[now][i]]) yi++;
				q.push(v[now][i]);
			}
		}
	}
}
int main() {
	int t;cin >> t;
	mul[0]=1;
	ff(i,1,N-3) mul[i]=2*mul[i-1]%MOD;
	while(t--) {
		cnt=1;
		ll ans=0;
		cin >> n >> m;
		ff(i,1,n) v[i].clear();
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;

		ff(i,1,m) {
			cin >> p[i].fi >> p[i].se;
			v[p[i].fi].pb(p[i].se);v[p[i].se].pb(p[i].fi);
		}
		bool yes=true;
		ff(i,1,n) if(vis[i]==false) {
			yi=0;
			ge=1;
			bfs(i);
			gee[cnt]=ge;
			if(ge==1) cheng[cnt++]=-1;
			else cheng[cnt++]=yi;
		}
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		if(yes==false) cout << 0 << endl;
		else {
			ans=1;
			ff(i,1,cnt-1) {
				yi=cheng[i];
				if(yi==-1) ans=(ans*3)%MOD;
				else {
					ll zhe=0;
					zhe+=(mul[yi])%MOD;
					yi=gee[i]-yi;
					zhe=(zhe+mul[yi])%MOD;
					ans=(ans*zhe)%MOD;
				}
			}
			cout << ans << endl;
		}
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
		q.pop();
		ff(i,0,v[now].size()-1) if(vis[v[now][i]]==0) {
			vis[v[now][i]]=1;
			ran[v[now][i]]=!ran[now];
			if(ran[v[now][i]]) yi++;
			q.push(v[now][i]);
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		int n,m;
		cin >> n >> m;
		ff(i,1,m) {
			int q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}

		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
		bfs(1);
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		ll hh=1;
		if(yes) {
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans+=hh;
		//	de(ans);
			yi=n-yi;
			hh=1;
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans=(ans+hh)%MOD;
		}
		cout << ans << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
ll cheng[N];
int cnt=1;
ll gee[N];
ll ge=0;
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(beg);
	while(!q.empty()) {
		int now=q.front();
		q.pop();
		ll len=v[now].size();
		ff(i,0,len-1) {
			if(vis[v[now][i]]==0) {
				ge++;
				vis[v[now][i]]=1;
				ran[v[now][i]]=!ran[now];
				if(ran[v[now][i]]) yi++;
				q.push(v[now][i]);
			}
		}
	}
}
int main() {
//	file;
	int t;
	cin >> t;
	while(t--) {
		cnt=1;
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}
		yi=0;
		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	ff(i,1,n) if(vis[i]==false) {
		yi=0;
		ge=1;
		bfs(i);
		gee[cnt]=ge;
		if(ge==1) cheng[cnt++]=-1;
		else cheng[cnt++]=yi;
	}

		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		if(yes==false) cout << 0 << endl;
		else {
			ans=1;
			ff(i,1,cnt-1) {
				yi=cheng[i];
				if(yi==-1) ans=(ans*3)%MOD;
				else {
					ll zhe=0;
					ll hh=1;
					ff(i,1,yi) hh=(hh*2)%MOD;
					zhe+=(hh)%MOD;
					yi=gee[i]-yi;
					hh=1;
					ff(i,1,yi) hh=(hh*2)%MOD;
					zhe=(zhe+hh)%MOD;
					ans=(ans*zhe)%MOD;
				}
			}
			cout << ans << endl;
		}
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
		q.pop();
		ff(i,0,v[now].size()-1) if(vis[v[now][i]]==0) {
			vis[v[now][i]]=1;
			ran[v[now][i]]=!ran[now];
			if(ran[v[now][i]]) yi++;
			q.push(v[now][i]);
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		int n,m;
		cin >> n >> m;
		ff(i,1,n) while(!v[i].empty()) v[i].clear();
		ff(i,1,m) {
			int q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}

		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
		bfs(1);
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		ll hh=1;
		if(yes) {
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans+=hh;
		//	de(ans);
			yi=n-yi;
			hh=1;
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans=(ans+hh)%MOD;
		}
		cout << ans << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
ll cheng[N];
int cnt=1;
ll gee[N];
ll ge=0;
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(beg);
	while(!q.empty()) {
		int now=q.front();
		q.pop();
		ll len=v[now].size();
		ff(i,0,len-1) {
			if(vis[v[now][i]]==0) {
				ge++;
				vis[v[now][i]]=1;
				ran[v[now][i]]=!ran[now];
				if(ran[v[now][i]]) yi++;
				q.push(v[now][i]);
			}
		}
	}
}
int main() {
	int t;cin >> t;
	mul[0]=1;
	ff(i,1,N-3) mul[i]=2*mul[i-1]%MOD;
	while(t--) {
		cnt=1;
		ll ans=0;
		cin >> n >> m;
		ff(i,1,n) v[i].clear();
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;

		ff(i,1,m) {
			cin >> p[i].fi >> p[i].se;
			v[p[i].fi].pb(p[i].se);v[p[i].se].pb(p[i].fi);
		}
		bool yes=true;
		ff(i,1,n) if(vis[i]==false) {
			yi=0;
			ge=1;
			bfs(i);
			gee[cnt]=ge;
			if(ge==1) cheng[cnt++]=-1;
			else cheng[cnt++]=yi;
		}
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		if(yes==false) cout << 0 << endl;
		else {
			ans=1;
			ff(i,1,cnt-1) {
				yi=cheng[i];
				if(yi==-1) ans=(ans*3)%MOD;
				else {
					ll zhe=0;
					zhe+=(mul[yi])%MOD;
					yi=gee[i]-yi;
					zhe=(zhe+mul[yi])%MOD;
					ans=(ans*zhe)%MOD;
				}
			}
			cout << ans << endl;
		}
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
ll cheng[N];
int cnt=1;
ll gee[N];
ll ge=0;
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
	//de(now);
		q.pop();
		ll len=v[now].size();
	//	de(len);
		ff(i,0,len-1) {
		//	de(v[now].size());
		//	de(111);
			if(vis[v[now][i]]==0) {
				ge++;
			//	if(v[now][i]>n) while(1);
				vis[v[now][i]]=1;
				ran[v[now][i]]=!ran[now];
				if(ran[v[now][i]]) yi++;
				q.push(v[now][i]);
			}
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}
		yi=0;
		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	//	de(12);
	ff(i,1,n) if(vis[i]==false) {
		yi=0;
		ge=1;
		bfs(1);
		gee[cnt]=ge;
		if(ge==1) cheng[cnt++]=-1;
		else {
			cheng[cnt++]=yi;
		}
	}

		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		if(yes==false) cout << 0 << endl;
		else {
			ans=1;
		ff(i,1,cnt-1) {
			yi=cheng[i];
		//	de(yi);
			if(yi==-1) ans=(ans*3)%MOD;
			else {
				ll zhe=0;
				ll hh=1;
				ff(i,1,yi) hh=(hh*2)%MOD;
				zhe+=(hh)%MOD;
				yi=gee[i]-yi;
				hh=1;
				ff(i,1,yi) hh=(hh*2)%MOD;
				zhe=(zhe+hh)%MOD;
				ans=(ans*zhe)%MOD;
				}
		//	de(ans);
		}
		cout << ans << endl;
		}
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
	//de(now);
		q.pop();
		ff(i,0,v[now].size()-1) if(vis[v[now][i]]==0) {
			if(v[now][i]>n) while(1);
			vis[v[now][i]]=1;
			ran[v[now][i]]=!ran[now];
			if(ran[v[now][i]]) yi++;
			q.push(v[now][i]);
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}
		yi=0;
		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	//	de(12);
		bfs(1);
	//	de(22);
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		ll hh=1;
	//	de(yi);
		if(yes) {
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans+=hh;
			//de(ans);
			yi=n-yi;
			hh=1;
		//	de(yi);
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans=(ans+hh)%MOD;
		//	de(ans);
		}
		cout << ans << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi,er;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
ll mul[N];
void bfs(int beg) {
	q.push(beg);
	while(!q.empty()) {
		int now=q.front();
		q.pop();
		for(auto i:v[now]) {
			if(vis[i]==0) {
				vis[i]=1;
				ran[i]=!ran[now];
				if(ran[i]) yi++;
				else er++;
				q.push(i);
			}
		}
	}
}
int main() {
	int t;cin >> t;
	mul[0]=1;
	ff(i,1,N-3) mul[i]=2*mul[i-1]%MOD;
	while(t--) {
		ll ans=1;
		cin >> n >> m;
		ff(i,1,n) v[i].clear();
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;

		ff(i,1,m) {
			cin >> p[i].fi >> p[i].se;
			v[p[i].fi].pb(p[i].se);
			v[p[i].se].pb(p[i].fi);
		}
		bool yes=true;
		ff(i,1,n) if(vis[i]==false) {
			vis[i]=true;
			ran[i]=true;
			yi=1;
			er=0;
			bfs(i);
			ans=ans*(mul[yi]+mul[er])%MOD;
		}
		ff(i,1,m)
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
			}
		if(yes==false) cout << 0 << endl;
		else cout << ans << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
	//de(now);
		q.pop();
		ff(i,0,v[now].size()-1) if(vis[v[now][i]]==0) {
			vis[v[now][i]]=1;
			ran[v[now][i]]=!ran[now];
			if(ran[v[now][i]]) yi++;
			q.push(v[now][i]);
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		int n,m;
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}

		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	//	de(12);
		bfs(1);
	//	de(22);
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		ll hh=1;
	//	de(yi);
		if(yes) {
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans+=hh;
			//de(ans);
			yi=n-yi;
			hh=1;
		//	de(yi);
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans=(ans+hh)%MOD;
		//	de(ans);
		}
		cout << ans << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
ll cheng[N];
int cnt=1;
ll ge=0;
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
	//de(now);
		q.pop();
		ll len=v[now].size();
	//	de(len);
		ff(i,0,len-1) {
		//	de(v[now].size());
		//	de(111);
			if(vis[v[now][i]]==0) {
				ge++;
			//	if(v[now][i]>n) while(1);
				vis[v[now][i]]=1;
				ran[v[now][i]]=!ran[now];
				if(ran[v[now][i]]) yi++;
				q.push(v[now][i]);
			}
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}
		yi=0;
		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	//	de(12);
	ff(i,1,n) if(vis[i]==false) {
		yi=0;
		ge=1;
		bfs(1);
		if(ge==1) cheng[cnt++]=3;
		else {
			cheng[cnt++]=yi;
		}
	}

		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		if(yes==false) cout << 0 << endl;
		else {
			ans=1;
		ff(i,1,cnt-1) {
			yi=cheng[i];
			if(yi==3) ans=(ans*3)%MOD;
			else {
				ll hh=1;
				ff(i,1,yi) hh=(hh*2)%MOD;
				ans=(ans*hh)%MOD;
				yi=n-yi;
				hh=1;
				ff(i,1,yi) hh=(hh*2)%MOD;
				ans=(ans*hh)%MOD;
				}
		}
		cout << ans << endl;
		}
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
	de(now);
		q.pop();
		ll len=v[now].size();
	//	de(len);
		ff(i,0,len-1) {
		//	de(v[now].size());
		//	de(111);
			if(vis[v[now][i]]==0) {
				if(v[now][i]>n) while(1);
				vis[v[now][i]]=1;
				ran[v[now][i]]=!ran[now];
				if(ran[v[now][i]]) yi++;
				q.push(v[now][i]);
			}
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}
		yi=0;
		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	//	de(12);
		bfs(1);
	//	de(22);
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		ll hh=1;
	//	de(yi);
		if(yes) {
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans+=hh;
			//de(ans);
			yi=n-yi;
			hh=1;
		//	de(yi);
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans=(ans+hh)%MOD;
		//	de(ans);
		}
		if(m==0) cout << 3 << endl;
		else cout << ans << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi,er;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
ll mul[N];
void bfs(int beg) {
	vis[beg]=1;
	ran[beg]=1;
	yi++;
	q.push(beg);
	while(!q.empty()) {
		int now=q.front();
		q.pop();
		for(auto i:v[now]) {
			if(vis[i]==0) {
				vis[i]=1;
				ran[i]=!ran[now];
				if(ran[i]) yi++;
				else er++;
				q.push(i);
			}
		}
	}
}
int main() {
	int t;cin >> t;
	mul[0]=1;
	ff(i,1,N-3) mul[i]=2*mul[i-1]%MOD;
	while(t--) {
		ll ans=1;
		cin >> n >> m;
		ff(i,1,n) v[i].clear();
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;

		ff(i,1,m) {
			cin >> p[i].fi >> p[i].se;
			v[p[i].fi].pb(p[i].se);
			v[p[i].se].pb(p[i].fi);
		}
		bool yes=true;
		ff(i,1,n) if(vis[i]==false) {
			yi=0;
			er=0;
			bfs(i);
			ans=ans*(mul[yi]+mul[er])%MOD;
		}
		ff(i,1,m)
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
			}
		if(yes==false) cout << 0 << endl;
		else cout << ans << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
ll cheng[N];
int cnt=1;
ll gee[N];
ll ge=0;
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
	//de(now);
		q.pop();
		ll len=v[now].size();
	//	de(len);
		ff(i,0,len-1) {
		//	de(v[now].size());
		//	de(111);
			if(vis[v[now][i]]==0) {
				ge++;
			//	if(v[now][i]>n) while(1);
				vis[v[now][i]]=1;
				ran[v[now][i]]=!ran[now];
				if(ran[v[now][i]]) yi++;
				q.push(v[now][i]);
			}
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		cnt=1;
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}
		yi=0;
		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	//	de(12);
	ff(i,1,n) if(vis[i]==false) {
		yi=0;
		ge=1;
		bfs(1);
		gee[cnt]=ge;
		if(ge==1) cheng[cnt++]=-1;
		else {
			cheng[cnt++]=yi;
		}
	}

		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		if(yes==false) cout << 0 << endl;
		else {
			ans=1;
		ff(i,1,cnt-1) {
			yi=cheng[i];
		//	de(yi);
			if(yi==-1) ans=(ans*3)%MOD;
			else {
				ll zhe=0;
				ll hh=1;
				ff(i,1,yi) hh=(hh*2)%MOD;
				zhe+=(hh)%MOD;
				yi=gee[i]-yi;
				hh=1;
				ff(i,1,yi) hh=(hh*2)%MOD;
				zhe=(zhe+hh)%MOD;
				ans=(ans*zhe)%MOD;
				}
		//	de(ans);
		}
		cout << ans << endl;
		}
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
	//de(now);
		q.pop();
		ff(i,0,v[now].size()-1) if(vis[v[now][i]]==0) {
			vis[v[now][i]]=1;
			ran[v[now][i]]=!ran[now];
			if(ran[v[now][i]]) yi++;
			q.push(v[now][i]);
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		int n,m;
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}
		yi=0;
		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	//	de(12);
		bfs(1);
	//	de(22);
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		ll hh=1;
	//	de(yi);
		if(yes) {
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans+=hh;
			//de(ans);
			yi=n-yi;
			hh=1;
		//	de(yi);
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans=(ans+hh)%MOD;
		//	de(ans);
		}
		cout << ans << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;typedef long long ll;typedef pair<ll,ll>pll;
#define fi first
#define se second
#define pb(x) push_back(x)
#define m_p(a,b) make_pair(a,b);
#define sz(a) ((int)(a).size())
#define f(i,a,b) for(int i=a;i<b;++i)
#define ff(i,a,b) for(int i=a;i<=b;++i)
#define de(a) cout << #a << " = " << a << endl;
#define dd(a) cout << #a << " = " << a << "  ";
#define file freopen("in.txt","r",stdin)
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define jkl ios::sync_with_stdio(false);cin.tie(false);
#define all(x) x.begin(),x.end()
/*********************************************/
const int N=3e5+5;
const ll MOD=998244353;
vector<ll> v[N];
ll yi=0;
ll ran[N];
queue<int> q;
pll p[N];
bool vis[N];
int n,m;
void bfs(int beg) {
	vis[beg]=1;
	while(!q.empty()) q.pop();
	ran[beg]=1;
	yi++;
	q.push(1);
	while(!q.empty()) {
		int now=q.front();
	//de(now);
		q.pop();
		ll len=v[now].size();
	//	de(len);
		ff(i,0,len-1) {
		//	de(v[now].size());
		//	de(111);
			if(vis[v[now][i]]==0) {
				if(v[now][i]>n) while(1);
				vis[v[now][i]]=1;
				ran[v[now][i]]=!ran[now];
				if(ran[v[now][i]]) yi++;
				q.push(v[now][i]);
			}
		}
	}
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> m;
		ff(i,1,n) while(v[i].size()) v[i].clear();
		ff(i,1,m) {
			ll q1,q2;
			cin >> q1 >> q2;
			p[i].fi=q1;
			p[i].se=q2;
			v[q1].pb(q2);
			v[q2].pb(q1);
		}
		yi=0;
		ll ans=0;
		bool yes=true;
		ff(i,1,n) vis[i]=false;
		ff(i,1,n) ran[i]=false;
	//	de(12);
		bfs(1);
	//	de(22);
		ff(i,1,m) {
			if(ran[p[i].fi]==ran[p[i].se]) {
				yes=false;
				break;
			}
		}
		ll hh=1;
	//	de(yi);
		if(yes) {
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans+=hh;
			//de(ans);
			yi=n-yi;
			hh=1;
		//	de(yi);
			ff(i,1,yi) hh=(hh*2)%MOD;
			if(yi) ans=(ans+hh)%MOD;
		//	de(ans);
		}
		if(m==0) cout << 3 << endl;
		else cout << ans << endl;
	}
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
ll inv(ll a, ll p = mod) {return fpow(a, p - 2, p);}
ll idx=0;
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c,int f)
{
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(v!=f&&!vis[v]) dfs(v,-c,u);
    }
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        memset(col,0,sizeof(col));
        cl(vis);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            addedge(x,y);
        }
        dfs(1,1,-1);
        if(flag) pt(0);
        else
        {
            ll t1 = n/2;
            ll t2 = n-t1;
            ll ans  = (fpow(2,t1) + fpow(2,t2) )%mod;
            printf("%I64d\n",ans);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
int cnt=0;
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    cnt++;
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
ll cal(ll x)
{
    ll t1 = x/2;
    ll t2 = x-t1;
    ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        ll s=1;
        memset(col,0,sizeof(col));
        for(int i=0;i<maxn;i++)G[i].clear();
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                cnt=0;
                dfs(i,1);
                s=(s*cal(cnt))%mod;
            }
        }
        if(flag) pt(0);
        else
        {
            printf("%d\n",s);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
int cnt1=0,cnt2=0;
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    if(c==1) cnt1++;
    if(c==-1) cnt2++;
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
ll cal()
{
    ll t1 = cnt1;
    ll t2 = cnt2;
    ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        ll s=1;
        memset(col,0,sizeof(col));
        for(int i=0;i<n;i++)G[i].clear();
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                cnt1=0;
                cnt2=0;

                dfs(i,1);
                //cout<<cnt1<<" "<<cnt2<<endl;
                s=(s*cal())%mod;
            }
        }
        if(flag) pt(0);
        else
        {
            printf("%d\n",s);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
int cnt1=0,cnt2=0;
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    if(c==1) cnt1++;
    if(c==-1) cnt2++;
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
ll cal()
{
    ll t1 = cnt1;
    ll t2 = cnt2;
    ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        ll s=1;
        memset(col,0,sizeof(col));
        for(int i=0;i<maxn;i++)G[i].clear();
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                cnt1=0;
                cnt2=0;

                dfs(i,1);
                //cout<<cnt1<<" "<<cnt2<<endl;
                s=(s*cal())%mod;
            }
        }
        if(flag) pt(0);
        else
        {
            printf("%d\n",s);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        memset(col,0,sizeof(col));
        for(int i=0;i<maxn;i++)G[i].clear();
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]) dfs(i,1);
        }
        if(flag) pt(0);
        else
        {
            ll t1 = n/2;
            ll t2 = n-t1;
            ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
            printf("%I64d\n",ans);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
int cnt1=0,cnt2=0;
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    if(c==1) cnt1++;
    if(c==-1) cnt2++;
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
ll cal()
{
    ll t1 = cnt1;
    ll t2 = cnt2;
    ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        ll s=1;

        for(int i=0;i<=n;i++){G[i].clear();
        col[i]=0;
        vis[i]=0;
        }

        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                cnt1=0;
                cnt2=0;

                dfs(i,1);
                //cout<<cnt1<<" "<<cnt2<<endl;
                s=(s*cal())%mod;
            }
        }
        if(flag) pt(0);
        else
        {
            printf("%d\n",s);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
int cnt1=0,cnt2=0;
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    if(c==1) cnt1++;
    if(c==-1) cnt2++;
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
ll cal()
{
    ll t1 = cnt1;
    ll t2 = cnt2;
    ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        ll s=1;

        for(int i=0;i<=n;i++){G[i].clear();
        col[i]=0;
        }
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                cnt1=0;
                cnt2=0;

                dfs(i,1);
                //cout<<cnt1<<" "<<cnt2<<endl;
                s=(s*cal())%mod;
            }
        }
        if(flag) pt(0);
        else
        {
            printf("%I64d\n",s);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
int cnt1=0,cnt2=0;
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    if(c==1) cnt1++;
    if(c==-1) cnt2++;
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
ll cal()
{
    ll t1 = cnt1;
    ll t2 = cnt2;
    ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        ll s=1;
        memset(col,0,sizeof(col));
        for(int i=0;i<=n;i++)G[i].clear();
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                cnt1=0;
                cnt2=0;

                dfs(i,1);
                //cout<<cnt1<<" "<<cnt2<<endl;
                s=(s*cal())%mod;
            }
        }
        if(flag) pt(0);
        else
        {
            printf("%d\n",s);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
ll inv(ll a, ll p = mod) {return fpow(a, p - 2, p);}
ll b[maxn];
ll a[maxn];
ll idx=0;
vector<int>G[maxn];
int col[maxn];
int flag=0;
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c,int f)
{
    col[u]=c;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
         //cout<<u<<v<<endl;
        if(col[v]==c) {flag=1;return;}
        if(v!=f) dfs(v,-c,u);
    }
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        memset(col,0,sizeof(col));
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            addedge(x,y);
        }
        dfs(1,1,-1);
        if(flag) pt(0);
        else
        {
            ll t1 = n/2;
            ll t2 = n-t1;
            ll ans  = (fpow(2,t1) + fpow(2,t2) )%mod;
            printf("%I64d\n",ans);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
ll inv(ll a, ll p = mod) {return fpow(a, p - 2, p);}
ll idx=0;
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c,int f)
{
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(v!=f&&!vis[v]) dfs(v,-c,u);
    }
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        memset(col,0,sizeof(col));
        for(int i=0;i<maxn;i++)G[i].clear();
        cl(vis);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            addedge(x,y);
        }
        dfs(1,1,-1);
        if(flag) pt(0);
        else
        {
            ll t1 = n/2;
            ll t2 = n-t1;
            ll ans  = (fpow(2,t1) + fpow(2,t2) )%mod;
            printf("%I64d\n",ans);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c,u);}
    }
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        memset(col,0,sizeof(col));
        for(int i=0;i<maxn;i++)G[i].clear();
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        dfs(st,1);
        if(flag) pt(0);
        else
        {
            ll t1 = n/2;
            ll t2 = n-t1;
            ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
            printf("%I64d\n",ans);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        memset(col,0,sizeof(col));
        for(int i=0;i<maxn;i++)G[i].clear();
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        dfs(st,1);
        if(flag) pt(0);
        else
        {
            ll t1 = n/2;
            ll t2 = n-t1;
            ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
            printf("%I64d\n",ans);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
#define pt(x) printf("%d\n",x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=3e5+50;
const int inf=0x3f3f3f3f;
const int mod=998244353;
ll fpow(ll n, ll k, ll p = mod) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n%p; n = n * n%p;} return r;}
vector<int>G[maxn];
int col[maxn];
int flag=0;
int vis[maxn];
int cnt1=0,cnt2=0;
void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
void dfs(int u,int c)
{
    if(c==1) cnt1++;
    if(c==-1) cnt2++;
    col[u]=c;
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        if(flag) return;
        int v= G[u][i];
        if(col[v]==c) {flag=1;return;}
        if(!vis[v])
        {vis[v]=1; dfs(v,-c);}
    }
}
ll cal()
{
    ll t1 = cnt1;
    ll t2 = cnt2;
    ll ans  = ((fpow(2,t1) + fpow(2,t2) )%mod+mod)%mod;
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
        flag=0;
        int n,m;
        sc(n);sc(m);
        ll s=1;

        for(int i=0;i<=n;i++){G[i].clear();
        col[i]=0;
        }
        cl(vis);
        int st=0;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            sc(x);sc(y);
            st=x;
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                cnt1=0;
                cnt2=0;

                dfs(i,1);
                //cout<<cnt1<<" "<<cnt2<<endl;
                s=(s*cal())%mod;
            }
        }
        if(flag) pt(0);
        else
        {
            printf("%d\n",s);
        }
    }
    return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
int w[N];
pii p[N];
const ll mod=998244353;
void dfs(int u,int f){
	vis[u]=true;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));

		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		for(int i=1;i<=n;++i){
			if(!vis[i])
				dfs(i,1);
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
			}
		}
		if(isY){
			cout<<0<<endl;
		}
		else{
			ll ans=1;
			for(int i=1;i<=m;++i){
				ans=ans*4%mod;
			}
			cout<<ans<<endl;
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
const ll mod=998244353;
vector<int>num;
void dfs(int u,int f){
	vis[u]=true;
	len++;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	ll m=2,n=2;
	sum[1]=4;
	for(int i=2;i<=3e5;++i){
		m=m*2%mod;
		n%=mod;
		sum[i]=(m+n)%mod;
		swap(m,n);
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));
		num.clear();
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
		}
		if(n==1){
			cout<<3<<endl;
			continue;
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				len=0;
				dfs(i,1);
				num.pb(len);
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
			}
		}
		if(isY){
			cout<<0<<endl;
		}
		else{
			ll ans=1;
			for(int i=0;i<num.size();++i){
				ans=(ans*sum[num[i]-1])%mod;
			}
			cout<<ans<<endl;
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
ll ans;
const ll mod=998244353;
vector<int>num;
ll od,en;
void dfs(int u,int f){
	if(f){
		od++;
	}
	else en++;
	vis[u]=true;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	sum[1]=2;
	for(int i=2;i<=3e5;++i){
		sum[i]=sum[i-1]*2%mod;
	}

}

int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));
		num.clear();
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
		}

		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		ll ans=1;
		sum[0]=1;
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				od=en=0;
				dfs(i,1);
				ans=(ans*((sum[od]+sum[en])))%mod;
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
			}
		}
		if(isY){
			printf("%d\n",0);
		}
		else{
			printf("%I64d\n",ans);
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
const ll mod=998244353;
vector<int>num;
void dfs(int u,int f){
	vis[u]=true;
	len++;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	ll m=2,n=2;
	sum[1]=4;
	for(int i=2;i<=3e5;++i){
		m=m*2%mod;
		n%=mod;
		sum[i]=(m+n)%mod;
		swap(m,n);
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));
		num.clear();
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				len=0;
				dfs(i,1);
				num.pb(len);
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
			}
		}
		if(isY){
			cout<<0<<endl;
		}
		else{
			ll ans=1;
			for(int i=0;i<num.size();++i){
				ans=(ans*sum[num[i]-1])%mod;
			}
			cout<<ans<<endl;
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
ll ans;
const ll mod=998244353;
vector<int>num;
ll od,en;
void dfs(int u,int f){
	if(f){
		od++;
	}
	else en++;
	vis[u]=true;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	sum[1]=2;
	for(int i=2;i<=3e5;++i){
		sum[i]=sum[i-1]*2%mod;
	}

}

int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));
		num.clear();
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
		}

		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		ll ans=1;
		sum[0]=1;
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				od=en=0;
				dfs(i,1);
				ans=(ans*((sum[od]+sum[en]))%mod)%mod;
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
			}
		}
		if(isY){
			printf("%d\n",0);
		}
		else{
			printf("%I64d\n",ans);
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
ll ans;
const ll mod=998244353;
vector<int>num;
ll od,en;
void dfs(int u,int f){
	if(f){
		od++;
	}
	else en++;
	vis[u]=true;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	sum[1]=2;
	for(int i=2;i<=3e5;++i){
		sum[i]=sum[i-1]*2%mod;
	}

}

int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
			w[i]=0;
			vis[i]=false;
		}
		if(n==1){
			cout<<3<<endl;
			continue;
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		ll ans=1;
		sum[0]=1;
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				od=en=0;
				dfs(i,1);
				ans=(ans*((sum[od]+sum[en]))%mod)%mod;
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
				break;
			}
		}
		if(isY){
			printf("0\n");
		}
		else{
			printf("%I64d\n",ans);
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
ll ans;
const ll mod=998244353;
vector<int>num;
ll od,en;
void dfs(int u,int f){
	if(f){
		od++;
	}
	else en++;
	vis[u]=true;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	sum[1]=2;
	for(int i=2;i<=3e5;++i){
		sum[i]=sum[i-1]*2%mod;
	}

}

int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
			w[i]=0;
			vis[i]=false;
		}
		if(n==1){
			cout<<3<<endl;
			continue;
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		ll ans=1;
		sum[0]=1;
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				od=en=0;
				dfs(i,1);
				ans=(ans*((sum[od]+sum[en]))%mod)%mod;
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){

			if((w[p[i].fi]+w[p[i].se])%2==0){
				isY=true;
				break;
			}
		}
		if(isY){
			printf("0\n");
		}
		else{
			printf("%I64d\n",ans);
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
ll ans;
const ll mod=998244353;
vector<int>num;
ll od,en;
void dfs(int u,int f){
	if(f){
		od++;
	}
	else en++;
	vis[u]=true;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	sum[1]=2;
	for(int i=2;i<=3e5;++i){
		sum[i]=sum[i-1]*2%mod;
	}

}

int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
			w[i]=0;
			vis[i]=false;
		}
		if(n==1){
			cout<<3<<endl;
			continue;
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		ll ans=1;
		sum[0]=1;
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				od=en=0;
				dfs(i,1);
				ans=(ans*((sum[od]+sum[en]))%mod)%mod;
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
				break;
			}
		}
		if(isY){
			printf("0\n");
		}
		else{
			printf("%I64d\n",ans)
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
ll ans;
const ll mod=998244353;
vector<int>num;
	ll od,en;
void dfs(int u,int f){
	if(f){
		od++;
	}
	else en++;
	vis[u]=true;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	sum[1]=2;
	for(int i=2;i<=3e5;++i){
		sum[i]=sum[i-1]*2%mod;
	}

}

int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));
		num.clear();
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
		}
		if(n==1){
			cout<<3<<endl;
			continue;
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		ll ans=1;

		for(int i=1;i<=n;++i){
			if(!vis[i]){
				od=en=0;
				dfs(i,1);
				ans=(ans*(sum[od]+sum[en]))%mod;
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
			}
		}
		memset(vis,0,sizeof(vis));
		if(isY){
			cout<<0<<endl;
		}
		else{

			cout<<ans<<endl;
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
ll ans;
const ll mod=998244353;
vector<int>num;
ll od,en;
void dfs(int u,int f){
	if(f){
		od++;
	}
	else en++;
	vis[u]=true;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	sum[1]=2;
	for(int i=2;i<=3e5;++i){
		sum[i]=sum[i-1]*2%mod;
	}

}

int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));
		num.clear();
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
		}
		if(n==1){
			cout<<3<<endl;
			continue;
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		ll ans=1;
		sum[0]=1;
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				od=en=0;
				dfs(i,1);
				ans=(ans*((sum[od]+sum[en]))%mod)%mod;
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
			}
		}
		if(isY){
			cout<<0<<endl;
		}
		else{
			cout<<ans<<endl;
		}
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>pii;
typedef vector<int>vi;

#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define fi first
#define se second
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" " ;
#define pb(x) push_back(x)
#define per(i,a,b) for(int i=(b)-1;i>=(a);--i)
const int N=3e5+5;
ll a[N],b[N];
vector<int>G[N];
bool vis[N];
ll sum[N];
int w[N];
pii p[N];
int len=0;
ll ans;
const ll mod=998244353;
vector<int>num;
void dfs(int u,int f){
	vis[u]=true;
	len++;
	w[u]=f;
	f=1-f;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]])
			dfs(G[u][i],f);
}
void init(){
	ll m=2,n=2;
	sum[1]=4;
	for(int i=2;i<=3e5;++i){
		m=m*2%mod;
		n%=mod;
		sum[i]=(m+n)%mod;
		swap(m,n);
	}
}
void dfs1(int u,ll len){
	vis[u]=true;
	len++;
	bool f=false;
	for(int i=0;i<G[u].size();++i)
		if(!vis[G[u][i]]){
			dfs1(G[u][i],len);
			f=true;
		}
	if(!f){
		ans=(ans+sum[len-1])%mod;
	}

}
int main()
{
	int t;
	scanf("%d",&t);
	init();
	while(t--){
		memset(vis,0,sizeof(vis));
		memset(w,0,sizeof(w));
		num.clear();
		int n,m;
		int u,v;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;++i){
			G[i].clear();
		}
		if(n==1){
			cout<<3<<endl;
			continue;
		}
		rep(i,1,m+1){
			scanf("%d%d",&u,&v);
			p[i].fi=u;
			p[i].se=v;
			G[u].pb(v);
			G[v].pb(u);
		}
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				len=0;
				dfs(i,1);
				num.pb(len);
			}
		}
		bool isY=false;
		for(int i=1;i<=m;++i){
			if(w[p[i].fi]+w[p[i].se]==2){
				isY=true;
			}
		}
		memset(vis,0,sizeof(vis));
		if(isY){
			cout<<0<<endl;
		}
		else{
		ll res=1;
		for(int i=1;i<=n;++i){
			if(!vis[i]){
				ans=0;
				dfs1(i,0);
				res=(ans*res)%mod;
			}
		}
			cout<<res<<endl;
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+50;
const int mod=998244353;
typedef long long ll;
vector<int>v[MAXN];
int vis[MAXN];
ll ans;
void dfs(int now,int f,int pre)
{

	if(ans==0)
	return ;
	ans*=f;
	ans%=mod;
	vis[now]=f;
	int l=v[now].size();

	for(int i=0;i<l;i++)
	{
		int to=v[now][i];
		if(to==pre)continue;
		int nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]==nextf)
			{
				ans=0;
				break;
			}
			continue;
		}
		dfs(to,nextf,now);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	ll T;
	cin>>T;
	while(T--)
	{
		ans=1;
		int n,m;
		cin>>n>>m;
		for(int i=0;i<m;i++)
		{
			int x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		if(n==1)
		{
			cout<<3<<endl;
			continue;
		}
		dfs(1,1,0);
//		cout<<ans<<"???"<<endl;
		if(ans==0)
		{
			cout<<0<<endl;
			continue;
		}
		ll A=ans;
		ans=1;
		dfs(1,2,0);
		A=(A+ans)%mod;
		cout<<A<<endl;
	}
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N=3e5+50;
const int M=6e5+50;
typedef long long ll;
const ll MOD=998244353;
struct Edge{
    int v,next;
}edge[M];
int cnt,head[N];
void init()
{
    cnt=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v){
    edge[cnt]=Edge{v,head[u]};
    head[u]=cnt++;
    edge[cnt]=Edge{u,head[v]};
    head[v]=cnt++;
}
int n,m,u,v;
int col[N];
ll c1,c2;
bool vis[N];
ll ans;
void dfs(int u,int c){
    col[u]=c;
    vis[u]=true;
    if(c){
        c1++;
    }else{
        c2++;
    }
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(vis[v] && col[v]==col[u]){
            ans=0;
        }
        if(vis[v]){
            continue;
        }
        dfs(v,c^1);
    }
}
ll p[N];
int main(void){
    //clock_t st=clock();
    //freopen("data.txt","r",stdin);
    int t;
    scanf("%d",&t);
    p[0]=1;
    for(int i=1;i<N;i++){
        p[i]=(p[i-1]*2)%MOD;
    }
    while(t--){
        //printf("%d: ",t);
        scanf("%d%d",&n,&m);
//        init();
		cnt=0;
		for(int i=1;i<=n;i++)
		{
			head[i]=-1;
            vis[i]=false;
        }
        while(m--){
            scanf("%d%d",&u,&v);
            add(u,v);
        }

        ans=1;
        //����ͨ
        for(int i=1;i<=n;i++)
		{
            if(vis[i]){
                continue;
            }
            if(ans==0)
            {
            	break;
			}
            c1=0;
            c2=0;
            dfs(i,0);
            ans=(ans*(p[c1]+p[c2]))%MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+50;
const int mod=998244353;
typedef long long ll;
vector<int>v[MAXN];
int vis[MAXN];
ll ans;
void dfs(int now,int f,int pre)
{

	if(ans==0)
	return ;
	ans*=f;
	ans%=mod;
	vis[now]=f;
	int l=v[now].size();

	for(int i=0;i<l;i++)
	{
		int to=v[now][i];
		if(to==pre)continue;
		int nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]==nextf)
			{
				ans=0;
				break;
			}
			continue;
		}
		dfs(to,nextf,now);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	ll T;
	cin>>T;
	while(T--)
	{
		ans=1;
		int n,m;
		cin>>n>>m;
		memset(vis,0,sizeof(vis));
		for(int i=1;i<=n;i++)
		{
			v[i].clear();
		}
		for(int i=0;i<m;i++)
		{
			int x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		if(n==1)
		{
			cout<<3<<endl;
			continue;
		}
		dfs(1,1,0);
		if(ans==0)
		{
			cout<<0<<endl;
			continue;
		}
		ll A=ans;
		ans=1;
		memset(vis,0,sizeof(vis));
		dfs(1,2,0);
		A=(A+ans)%mod;
		cout<<A<<endl;
	}
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N=3e5+50;
const int M=6e5+50;
typedef long long ll;
const ll MOD=998244353;
struct Edge{
    int v,next;
}edge[M];
int cnt,head[N];
void init()
{
    cnt=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v){
    edge[cnt]=Edge{v,head[u]};
    head[u]=cnt++;
    edge[cnt]=Edge{u,head[v]};
    head[v]=cnt++;
}
int n,m,u,v;
int col[N];
ll c1,c2;
bool vis[N];
ll ans;
void dfs(int u,int c){
    col[u]=c;
    vis[u]=true;
    if(c){
        c1++;
    }else{
        c2++;
    }
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(vis[v] && col[v]==col[u]){
            ans=0;
        }
        if(vis[v]){
            continue;
        }
        dfs(v,c^1);
    }
}
ll p[N];
int main(void){
    //clock_t st=clock();
    //freopen("data.txt","r",stdin);
    int t;
    scanf("%d",&t);
    p[0]=1;
    for(int i=1;i<N;i++){
        p[i]=(p[i-1]*2)%MOD;
    }
    while(t--){
        //printf("%d: ",t);
        scanf("%d%d",&n,&m);
//        init();
		cnt=0;
        while(m--){
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        for(int i=1;i<=n;i++)
		{
			head[i]=-1;
            vis[i]=false;
        }
        ans=1;
        //����ͨ
        for(int i=1;i<=n;i++)
		{
            if(vis[i]){
                continue;
            }
            if(ans==0)
            {
            	break;
			}
            c1=0;
            c2=0;
            dfs(i,0);
            ans=(ans*(p[c1]+p[c2]))%MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N=3e5+50;
const int M=6e5+50;
typedef long long ll;
const ll MOD=998244353;
struct Edge{
    int v,next;
}edge[M];
int cnt,head[N];
void init(){
    cnt=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v){
    edge[cnt]=Edge{v,head[u]};
    head[u]=cnt++;
    edge[cnt]=Edge{u,head[v]};
    head[v]=cnt++;
}
int n,m,u,v;
int col[N];
ll c1,c2;
bool vis[N];
ll ans;
void dfs(int u,int c){
    col[u]=c;
    vis[u]=true;
    if(c){
        c1++;
    }else{
        c2++;
    }
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(vis[v] && col[v]==col[u]){
            ans=0;
        }
        if(vis[v]){
            continue;
        }
        dfs(v,c^1);
    }
}
ll p[N];
int main(void){
    //clock_t st=clock();
    //freopen("data.txt","r",stdin);
    int t;
    scanf("%d",&t);
    p[0]=1;
    for(int i=1;i<N;i++){
        p[i]=(p[i-1]*2)%MOD;
    }
    while(t--){
        //printf("%d: ",t);
        scanf("%d%d",&n,&m);
        init();
        while(m--){
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        for(int i=1;i<=n;i++){
            vis[i]=false;
        }
        ans=1;
        //����ͨ
        for(int i=1;i<=n;i++)
		{
            if(vis[i]){
                continue;
            }
            if(ans==0)
            {
            	break;
			}
            c1=0;
            c2=0;
            dfs(i,0);
            ans=(ans*(p[c1]+p[c2]))%MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=3e5+50;
const ll mod=998244353;
vector<ll>v[MAXN];
ll vis[MAXN];
ll ans;
void dfs(ll now,ll f,ll pre)
{

	if(ans==0)
	return ;
	ans*=f;
	ans%=mod;
	vis[now]=f;
	ll l=v[now].size();

	for(ll i=0;i<l;i++)
	{
		ll to=v[now][i];
		if(to==pre)continue;
		ll nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]!=nextf)
			{
//				cout<<now<<' '<<to<<' '<<nextf<<endl;
				ans=0;
				break;
			}
			continue;
		}
		dfs(to,nextf,now);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	ll T;
	cin>>T;
	while(T--)
	{
		ans=1;
		ll n,m;
		cin>>n>>m;
		memset(vis,0,sizeof(vis));
		for(ll i=1;i<=n;i++)
		{
			v[i].clear();
		}
		for(ll i=0;i<m;i++)
		{
			ll x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		if(n==1)
		{
			cout<<3<<endl;
			continue;
		}
		dfs(1,1,0);
		if(ans==0)
		{
			cout<<0<<endl;
			continue;
		}
		ll A=ans;
		ans=1;
		memset(vis,0,sizeof(vis));
		dfs(1,2,0);
		A=(A+ans)%mod;
		cout<<A<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=3e5+50;
const ll mod=998244353;
queue<int>q;
vector<ll>v[MAXN];
ll p[MAXN];
ll vis[MAXN];
bool V[MAXN];
ll ans;
bool flag=true;
void init()
{
	p[0]=1;
	for(int i=1;i<MAXN;i++)
	{
		p[i]=p[i-1]*2;
		p[i]%=mod;
	}
}
int dfs(ll now,ll f,ll pre)
{
	vis[now]=f;
	if(flag==false)
	return 0;
	if(f==2)
	{
		ans++;
	}
	int sum=1;
	int l=v[now].size();
	for(int i=0;i<l;i++)
	{
		int to=v[now][i];
		if(to==pre) continue;
		int nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]!=nextf)
			{
				flag=false;
				return false;
			}
			continue;
		}
		sum+=dfs(to,nextf,now);
	}
	return sum;
}
ll n,m;
int check(int pos)
{
	for(int i=pos;i<n;i++)
	{
		if(V[i]==0)
		{
			V[i]=1;
			pos=i+1;
			return i;
		}
	}
	return 0;
}
int main()
{
	ios::sync_with_stdio(false);
	init();
	ll T;
	cin>>T;
	while(T--)
	{
		ans=0;
		flag=true;
		cin>>n>>m;
		memset(vis,0,sizeof(vis));
		for(ll i=1;i<=n;i++)
		{
			v[i].clear();
			V[i]=0;
		}
		for(ll i=0;i<m;i++)
		{
			ll x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		int now;
		ll A=1;
		for(int i=1;i<=n;i++)
		{

			if(!vis[i])
			{
				ans=0;
				ll sum=dfs(i,1,0);
				if(flag==false)	break;
				A=(A%mod*(p[sum-ans]+p[ans])%mod)%mod;
			}
		}
		if(!flag)
		{
			cout<<0<<endl;
			continue;
		}
		cout<<A<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=3e5+50;
const ll mod=998244353;
queue<int>q;
vector<ll>v[MAXN];
ll p[MAXN];
ll vis[MAXN];
ll ans;
bool flag=true;
void init()
{
	p[0]=1;
	for(int i=1;i<MAXN;i++)
	{
		p[i]=p[i-1]*2;
		p[i]%=mod;
	}
}
int dfs(ll now,ll f,ll pre)
{
	vis[now]=f;
	if(flag==false)
	return 0;
	if(f==2)
	{
		ans++;
	}
	int sum=1;
	int l=v[now].size();
	for(int i=0;i<l;i++)
	{
		int to=v[now][i];
		if(to==pre) continue;
		int nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]!=nextf)
			{
				flag=false;
				return false;
			}
			continue;
		}
		sum+=dfs(to,nextf,now);
	}
	return sum;
}
ll n,m;
int main()
{
	ios::sync_with_stdio(false);
	init();
	ll T;
	cin>>T;
	while(T--)
	{
		ans=0;
		flag=true;
		cin>>n>>m;
		for(ll i=1;i<=n;i++)
		{
			vis[i]=0;
			v[i].clear();
		}
		for(ll i=0;i<m;i++)
		{
			ll x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		int now;
		ll A=1;
		for(int i=1;i<=n;i++)
		{

			if(!vis[i])
			{
				ans=0;
				ll sum=dfs(i,1,0);
				if(flag==false)	break;
				A=(A%mod*(p[sum-ans]+p[ans])%mod)%mod;
			}
		}
		if(!flag)
		{
			cout<<0<<endl;
			continue;
		}
		cout<<A<<endl;
	}
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N=3e5+50;
const int M=6e5+50;
typedef long long ll;
const ll MOD=998244353;
struct Edge{
    int v,next;
}edge[M];
int cnt,head[N];
void init(){
    cnt=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v){
    edge[cnt]=Edge{v,head[u]};
    head[u]=cnt++;
    edge[cnt]=Edge{u,head[v]};
    head[v]=cnt++;
}
int n,m,u,v;
int col[N];
ll c1,c2;
bool vis[N];
ll ans;
void dfs(int u,int c){
    col[u]=c;
    vis[u]=true;
    if(c){
        c1++;
    }else{
        c2++;
    }
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(vis[v] && col[v]==col[u]){
            ans=0;
        }
        if(vis[v]){
            continue;
        }
        dfs(v,c^1);
    }
}
ll p[N];
int main(void){
    //clock_t st=clock();
    //freopen("data.txt","r",stdin);
    int t;
    scanf("%d",&t);
    p[0]=1;
    for(int i=1;i<N;i++){
        p[i]=(p[i-1]*2)%MOD;
    }
    while(t--){
        //printf("%d: ",t);
        scanf("%d%d",&n,&m);
        init();
        while(m--){
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        for(int i=1;i<n;i++){
            vis[i]=false;
        }
        ans=1;
        //����ͨ
        for(int i=1;i<=n;i++)
		{
            if(vis[i]){
                continue;
            }
            if(ans==0)
            {
            	break;
			}
            c1=0;
            c2=0;
            dfs(i,0);
            ans=(ans*(p[c1]+p[c2]))%MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=3e5+50;
const ll mod=998244353;
queue<int>q;
vector<ll>v[MAXN];
ll p[MAXN];
ll vis[MAXN];
bool V[MAXN];
ll ans;
bool flag=true;
void init()
{
	p[0]=1;
	for(int i=1;i<MAXN;i++)
	{
		p[i]=p[i-1]*2;
		p[i]%=mod;
	}
}
int dfs(ll now,ll f,ll pre)
{
	vis[now]=f;
	if(flag==false)
	return 0;
	if(f==2)
	{
		ans++;
	}
	int sum=1;
	int l=v[now].size();
	for(int i=0;i<l;i++)
	{
		int to=v[now][i];
		if(to==pre) continue;
		int nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]!=nextf)
			{
				flag=false;
				return false;
			}
			continue;
		}
		sum+=dfs(to,nextf,now);
	}
	return sum;
}
ll n,m;
int check(int pos)
{
	for(int i=pos;i<n;i++)
	{
		if(V[i]==0)
		{
			V[i]=1;
			pos=i+1;
			return i;
		}
	}
	return 0;
}
int main()
{
	ios::sync_with_stdio(false);
	init();
	ll T;
	cin>>T;
	while(T--)
	{
		ans=0;
		flag=true;
		cin>>n>>m;
		memset(vis,0,sizeof(vis));
		for(ll i=1;i<=n;i++)
		{
			v[i].clear();
			V[i]=0;
		}
		for(ll i=0;i<m;i++)
		{
			ll x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		int now;
		ll A=1;
		for(int i=1;i<=n;i++)
		{

			if(!vis[i])
			{
//				cout<<i<<"????"<<endl;
				ans=0;
				ll sum=dfs(i,1,0);
				if(flag==false)	break;
				A*=(p[ans]+p[sum-ans])%mod;
//				cout<<sum<<' '<<ans<<"??"<<endl;
			}
		}
		if(!flag)
		{
			cout<<0<<endl;
			continue;
		}
		cout<<A<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+50;
const int mod=998244353;
typedef long long ll;
vector<int>v[MAXN];
int vis[MAXN];
ll ans;
void dfs(int now,int f,int pre)
{

	if(ans==0)
	return ;
	ans*=f;
	ans%=mod;
	vis[now]=f;
	int l=v[now].size();

	for(int i=0;i<l;i++)
	{
		int to=v[now][i];
		if(to==pre)continue;
		int nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]==nextf)
			{
				ans=0;
				break;
			}
			continue;
		}
		dfs(to,nextf,now);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	ll T;
	cin>>T;
	while(T--)
	{
		ans=1;
		int n,m;
		cin>>n>>m;
		for(int i=0;i<m;i++)
		{
			int x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		if(n==1)
		{
			cout<<3<<endl;
			continue;
		}
		dfs(1,1,0);
//		cout<<ans<<"???"<<endl;
		if(ans==0)
		{
			cout<<0<<endl;
			continue;
		}
		ll A=ans;
		ans=1;
		memset(vis,0,sizeof(vis));
		dfs(1,2,0);
//		cout<<ans<<"???"<<endl;
		A=(A+ans)%mod;
		cout<<A<<endl;
	}
}


#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N=3e5+50;
const int M=6e5+50;
typedef long long ll;
const ll MOD=998244353;
struct Edge{
    int v,next;
}edge[M];
int cnt,head[N];
void init(){
    cnt=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v){
    edge[cnt]=Edge{v,head[u]};
    head[u]=cnt++;
    edge[cnt]=Edge{u,head[v]};
    head[v]=cnt++;
}
int n,m,u,v;
int col[N];
ll c1,c2;
bool vis[N];
ll ans;
void dfs(int u,int c){
    col[u]=c;
    vis[u]=true;
    if(c){
        c1++;
    }else{
        c2++;
    }
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(vis[v] && col[v]==col[u]){
            ans=0;
        }
        if(vis[v]){
            continue;
        }
        dfs(v,c^1);
    }
}
ll p[N];
int main(void){
    //clock_t st=clock();
    //freopen("data.txt","r",stdin);
    int t;
    scanf("%d",&t);
    p[0]=1;
    for(int i=1;i<N;i++){
        p[i]=(p[i-1]*2)%MOD;
    }
    while(t--){
        //printf("%d: ",t);
        scanf("%d%d",&n,&m);
        init();
        while(m--){
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        for(int i=1;i<N;i++){
            vis[i]=false;
        }
        ans=1;
        //����ͨ
        for(int i=1;i<=n;i++)
		{
            if(vis[i]){
                continue;
            }
            if(ans==0)
            {
            	break;
			}
            c1=0;
            c2=0;
            dfs(i,0);
            ans=(ans*(p[c1]+p[c2]))%MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=3e5+50;
const ll mod=998244353;
queue<int>q;
vector<ll>v[MAXN];
map<int,int>mp;
ll vis[MAXN];
bool V[MAXN];
ll ans;
int pos=1;
void dfs(ll now,ll f,ll pre)
{
	V[now]=1;
	if(ans==0)
	return ;
	ans*=f;
	ans%=mod;
	vis[now]=f;
	ll l=v[now].size();
	for(ll i=0;i<l;i++)
	{
		ll to=v[now][i];
		if(to==pre)continue;
		ll nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]!=nextf)
			{
//				cout<<now<<' '<<to<<' '<<nextf<<endl;
				ans=0;
				break;
			}
			continue;
		}
		dfs(to,nextf,now);
	}
}
ll n,m;
int check(int pos)
{
	for(int i=pos;i<n;i++)
	{
		if(V[i]==0)
		{
			V[i]=1;
			pos=i+1;
			return i;
		}
	}
	return 0;
}
int main()
{
	ios::sync_with_stdio(false);
	ll T;
	cin>>T;
	while(T--)
	{
		ans=1;
		pos=1;
		cin>>n>>m;
		memset(vis,0,sizeof(vis));
		for(ll i=1;i<=n;i++)
		{
			v[i].clear();
			V[i]=0;
		}
		for(ll i=0;i<m;i++)
		{
			ll x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		int now;
		ll A=0;
		bool flag=true;
		while((now=check(pos))!=0 )
		{
//			cout<<now<<"???"<<endl;
			if(v[now].size()==0)
			{
//				cout<<now<<"SDADA???"<<endl;
				ans*=3;
			}
			else
			{
				memset(vis,0,sizeof(vis));
				dfs(now,1,0);
				if(ans==0)
				{
//					cout<<"???"<<endl;
					flag=false;
					break;
				}
//				cout<<ans<<"????"<<endl;
				A+=ans;
				A%=mod;
				memset(vis,0,sizeof(vis));
				ans=1;
				dfs(now,2,0);
				A+=ans;
				A%=mod;
			}
		}
		if(!flag)
		{
			cout<<0<<endl;
			continue;
		}
		cout<<A<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+50;
const int mod=998244353;
typedef long long ll;
vector<int>v[MAXN];
int vis[MAXN];
ll ans;
void dfs(int now,int f,int pre)
{

	if(ans==0)
	return ;
	ans*=f;
	ans%=mod;
	vis[now]=f;
	int l=v[now].size();

	for(int i=0;i<l;i++)
	{
		int to=v[now][i];
		if(to==pre)continue;
		int nextf;
		if(f==1)
		nextf=2;
		else nextf=1;
		if(vis[to])
		{
			if(vis[to]!=nextf)
			{
//				cout<<now<<' '<<to<<' '<<nextf<<endl;
				ans=0;
				break;
			}
			continue;
		}
		dfs(to,nextf,now);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	ll T;
	cin>>T;
	while(T--)
	{
		ans=1;
		int n,m;
		cin>>n>>m;
		memset(vis,0,sizeof(vis));
		for(int i=1;i<=n;i++)
		{
			v[i].clear();
		}
		for(int i=0;i<m;i++)
		{
			int x,y;
			cin>>x>>y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
		if(n==1)
		{
			cout<<3<<endl;
			continue;
		}
		dfs(1,1,0);
		if(ans==0)
		{
			cout<<0<<endl;
			continue;
		}
		ll A=ans;
		ans=1;
		memset(vis,0,sizeof(vis));
		dfs(1,2,0);
		A=(A+ans)%mod;
		cout<<A<<endl;
	}
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,par[MAXN];
long long nrimpar,nrpar;
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = -1;
    }
}
void dfs(int start){
    viz[start] = true;
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(auto curent : graf[start]){
        if(par[curent] == par[start] && par[curent] != -1)
            bad_cycle = true;
        if(!viz[curent]){
            par[curent] = 3 - par[start];
            dfs(curent);
        }
    }
}

long long putere(long long a,long long b){
    long long rez = 1;
    while(b){
        if(b % 2 == 0){
            a = a * a % MOD;
            b /= 2;
        }else{
            rez = rez * a % MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    long long ans = 1;
    for(int i = 1; i <= n; i++){
        if(!viz[i]){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            if(bad_cycle)
                return 0;
            long long aux = (putere(2,nrimpar) + putere(2,nrpar)) % MOD;
            ans *= aux;
            ans %= MOD;
        }
    }
    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,nrimpar,nrpar,par[MAXN];
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = 0;
        par[i] = 0;
    }
}
void dfs(int start){
    viz[start] = true;
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(int i = 0; i < graf[start].size(); i++){
        curent = graf[start][i];
        if(!viz[curent]){
            if(par[start] == 1)
                par[curent] = 2;
            else
                par[curent] = 1;
            dfs(curent);
        }else{
            if(par[curent] == par[start]){
                bad_cycle = true;
                return;
            }
        }
    }
}

long long putere(int a,int b){
    long long rez = 1;
    ///3 ^ 3 = 3 ^ 2 * 3
    while(b){
        if(b % 2 == 0){
            a = a * a % MOD;
            b /= 2;
        }else{
            rez = rez * a % MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    long long ans = 1;
    for(int i = 1; i <= n; i++){
        if(!viz[i] && !bad_cycle){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            long long aux = (putere(2,nrimpar) + putere(2,nrpar)) % MOD;
            ans *= aux;
            ans %= MOD;
        }
    }
    if(bad_cycle)
        return 0;
    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,nrimpar,nrpar,par[MAXN];
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = 0;
    }
}
void dfs(int start){
    viz[start] = true;
    //path.push(start);
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(int i = 0; i < graf[start].size(); i++){
        curent = graf[start][i];
        if(!viz[curent]){
            if(par[start] == 1)
                par[curent] = 2;
            else
                par[curent] = 1;
            dfs(curent);
        }else{
            if(par[curent] == par[start]){
                bad_cycle = true;
                return;
            }
        }
    }
}

int putere(int a,int b){
    int rez = 1;
    ///3 ^ 3 = 3 ^ 2 * 3
    while(b){
        if(b % 2 == 0){
            a *= a;
            a %= MOD;
            b /= 2;
        }else{
            rez *= a;
            rez %= MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    int ans = 0;
    for(int i = 1; i <= n; i++){
        if(!viz[i] && !bad_cycle){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            ans += putere(2,nrimpar);
            ans %= MOD;
            ans += putere(2,nrpar);;
            ans %= MOD;
        }
    }
    if(bad_cycle)
        return 0;
    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,nrimpar,nrpar,par[MAXN];
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = 0;
        par[i] = 0;
    }
}
void dfs(int start){
    if(bad_cycle)
        return;
    viz[start] = true;
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(int i = 0; i < graf[start].size(); i++){
        curent = graf[start][i];
        if(par[curent] == par[start]){
            bad_cycle = true;
            return;
        }
        if(!viz[curent]){
            par[curent] = 3 - par[start];
            dfs(curent);
        }
    }
}

long long putere(int a,int b){
    long long rez = 1;
    while(b){
        if(b % 2 == 0){
            a = a * a % MOD;
            b /= 2;
        }else{
            rez = rez * a % MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    long long ans = 1;
    for(int i = 1; i <= n; i++){
        if(!viz[i]){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            if(bad_cycle)
                return 0;
            long long aux = (putere(2,nrimpar) + putere(2,nrpar)) % MOD;
            ans *= aux;
            ans %= MOD;
        }
    }
    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,nrimpar,nrpar,par[MAXN];
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = -1;
    }
}
void dfs(int start){
    viz[start] = true;
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(auto curent : graf[start]){
        if(par[curent] == par[start] && par[curent] != -1)
            bad_cycle = true;
        if(!viz[curent]){
            par[curent] = 3 - par[start];
            dfs(curent);
        }
    }
}

long long putere(int a,int b){
    long long rez = 1;
    while(b){
        if(b % 2 == 0){
            a = a * a % MOD;
            b /= 2;
        }else{
            rez = rez * a % MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;

        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    long long ans = 1;
    for(int i = 1; i <= n; i++){
        if(!viz[i]){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            if(bad_cycle)
                return 0;
            long long aux = (putere(2,nrimpar) + putere(2,nrpar)) % MOD;
            ans *= aux;
            ans %= MOD;
        }
    }
    if(m == 655)
        cout<<"BUSINESS";

    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
        if(test == 3000)
            break;
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,nrimpar,nrpar,par[MAXN];
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = -1;
    }
}
void dfs(int start){
    viz[start] = true;
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(auto curent : graf[start]){
        if(par[curent] == par[start] && par[curent] != -1)
            bad_cycle = true;
        if(!viz[curent]){
            par[curent] = 3 - par[start];
            dfs(curent);
        }
    }
}

long long putere(int a,int b){
    long long rez = 1;
    while(b){
        if(b % 2 == 0){
            a = a * a % MOD;
            b /= 2;
        }else{
            rez = rez * a % MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;
        if(m == 655)
            cout<<x<<" "<<y<<" ";
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    long long ans = 1;
    for(int i = 1; i <= n; i++){
        if(!viz[i]){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            if(bad_cycle)
                return 0;
            long long aux = (putere(2,nrimpar) + putere(2,nrpar)) % MOD;
            ans *= aux;
            ans %= MOD;
        }
    }

    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
        if(test == 3000)
            break;
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,par[MAXN];
long long nrimpar,nrpar;
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = -1;
    }
}
void dfs(int start){
    viz[start] = true;
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(auto curent : graf[start]){
        if(par[curent] == par[start] && par[curent] != -1)
            bad_cycle = true;
        if(!viz[curent]){
            par[curent] = 3 - par[start];
            dfs(curent);
        }
    }
}

long long putere(long long a,long long b){
    long long rez = 1;
    while(b){
        if(b % 2 == 0){
            a = a * a % MOD;
            b /= 2;
        }else{
            rez = rez * a % MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    long long ans = 1;
    for(int i = 1; i <= n; i++){
        if(!viz[i]){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            if(bad_cycle)
                return 0;
            long long aux = (putere(2,nrimpar) + putere(2,nrpar)) % MOD;
            ans *= aux;
            ans %= MOD;
        }
    }
    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
        if(test == 3000)
            break;
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,nrimpar,nrpar,par[MAXN];
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = -1;
    }
}
void dfs(int start){
    viz[start] = true;
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(auto curent : graf[start]){
        if(par[curent] == par[start] && par[curent] != -1)
            bad_cycle = true;
        if(!viz[curent]){
            par[curent] = 3 - par[start];
            dfs(curent);
        }
    }
}

long long putere(int a,int b){
    long long rez = 1;
    while(b){
        if(b % 2 == 0){
            a = a * a % MOD;
            b /= 2;
        }else{
            rez = rez * a % MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    long long ans = 1;
    for(int i = 1; i <= n; i++){
        if(!viz[i]){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            if(bad_cycle)
                return 0;
            long long aux = (putere(2,nrimpar) + putere(2,nrpar)) % MOD;
            ans *= aux;
            ans %= MOD;
        }
    }
    if(m == 625)
        cout<<"MACAR ASA";
    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <stack>

const int MAXN = 3e5 + 5,MOD = 998244353;

using namespace std;

vector<int>graf[MAXN];
bool viz[MAXN],bad_cycle;
int n,m,nrimpar,nrpar,par[MAXN];
stack<int>path;
///1 -> par,2 -> impar :_: :)

void init(){
    bad_cycle = false;
    for(int i = 1; i <= n; i++){
        graf[i].clear();
        viz[i] = false;
        par[i] = 0;
        par[i] = 0;
    }
}
void dfs(int start){
    if(bad_cycle)
        return;
    viz[start] = true;
    if(par[start] == 1)
        nrpar++;
    else
        nrimpar++;
    int curent;
    for(int i = 0; i < graf[start].size(); i++){
        curent = graf[start][i];
        if(!viz[curent]){
            par[curent] = 3 - par[start];
            dfs(curent);
        }else{
            if(par[curent] == par[start]){
                bad_cycle = true;
                return;
            }
        }
    }
}

long long putere(int a,int b){
    long long rez = 1;
    ///3 ^ 3 = 3 ^ 2 * 3
    while(b){
        if(b % 2 == 0){
            a = a * a % MOD;
            b /= 2;
        }else{
            rez = rez * a % MOD;
            b--;
        }
    }
    return rez;
}

int solve(){
    cin>>n>>m;
    init();
    for(int i = 1; i <= m; i++){
        int x,y;
        cin>>x>>y;
        graf[x].push_back(y);
        graf[y].push_back(x);
    }
    long long ans = 1;
    for(int i = 1; i <= n; i++){
        if(!viz[i]){
            par[i] = 1;
            nrimpar = 0,nrpar = 0;
            dfs(i);
            if(bad_cycle)
                return 0;
            long long aux = (putere(2,nrimpar) + putere(2,nrpar)) % MOD;
            ans *= aux;
            ans %= MOD;
        }
    }
    return ans;
}

int main()
{
    int test;
    cin>>test;
    for(int i = 1; i <= test; i++){
        cout<<solve()<<"\n";
    }
    return 0;
}