#include<bits/stdc++.h>
using namespace std;
inline long long read(){
	long long x=0,f=1;char ch=getchar();
	while ((!isdigit(ch))&&(ch!='-')) ch=getchar();
	if (ch=='-') f=-1,ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return x*f;
}
#define MOD 1000000007
map<pair<int,int>,bool> mp;
long long ans;
vector<int> edge[1001010];
long long dp[1001010],pw[1001010];
long long w,e[1001010],id,cnt,a[1001010],b[1001010],c[1001010],d[1001010];
long long n,m,i,low[1001010],dfn[1001010];
bool cut[1001010];
long long bel[1001010];
long long x,y,edg[1001010],tot,val1[1001010],val2[1001010];
bool vis[1001010];
void add(int x,int y){
	cnt++;a[cnt]=y;b[cnt]=d[x];c[cnt]=x;d[x]=cnt;
}
void tarjan(int x,int fa){
	dfn[x]=low[x]=++id;
	for (int i=d[x];i;i=b[i])
	      if (a[i]!=fa)
	          if (dfn[a[i]]==0){
	          	tarjan(a[i],x);
	          	if (low[a[i]]>dfn[x]) cut[i]=cut[i^1]=true;
	          	low[x]=min(low[x],low[a[i]]);
			  }
			  else low[x]=min(low[x],dfn[a[i]]);
}
void solve(int x,int fa){
	if (vis[x]) return ;
	vis[x]=true;
	bel[x]=tot;
	val1[tot]++;
	for (int i=d[x];i;i=b[i])
	     if (cut[i]==false)
	         if (a[i]!=fa)
	         solve(a[i],x);
}
void resolve(int x,int fa){
	edg[x]=val2[x];
	for (int i=0;i<edge[x].size();i++)
	      if (edge[x][i]!=fa){
	      	resolve(edge[x][i],x);
	      	edg[x]+=edg[edge[x][i]]+1;
		  }
	w=0;
	for (int i=0;i<edge[x].size();i++)
	     if (edge[x][i]!=fa){
	     	w++;e[w]=edge[x][i];
		 }
	for (int i=1;i<=w;i++)
	   for (int j=1;j<=w;j++)
	        if (i!=j)
	          dp[x]=(dp[x]+dp[e[i]]*pw[edg[e[j]]+1] % MOD*pw[w-1]) % MOD;
    long long now=1;
    for (i=1;i<=w;i++)
        now=now*dp[e[i]] % MOD;
    if (w!=0)dp[x]=(dp[x]+now) % MOD;
	dp[x]=dp[x]*pw[val2[x]] % MOD;
    dp[x]=dp[x]*(pw[val1[x]]) % MOD;
   if (x==2) cout<<dp[x]<<endl;
    dp[x]=(dp[x]+(pw[val1[x]]-1+MOD)*pw[edg[x]]) % MOD;
}
int main(){
	//freopen("barrack.in","r",stdin);
	//freopen("barrack.out","w",stdout);
	n=read();m=read();cnt=1;
	pw[0]=1;
	for (i=1;i<=max(n,m)+1;i++) pw[i]=pw[i-1]*2 % MOD;
	for (i=1;i<=m;i++){
		x=read();y=read();
		add(x,y);add(y,x);
	}
	for (i=1;i<=n;i++)
	    if (dfn[i]==0) tarjan(i,0);
	for (i=1;i<=n;i++)
	    if (vis[i]==false){
	    	tot++;
	    	solve(i,0);
	     }
	for (i=2;i<=cnt;i++) 
	     if (bel[c[i]]!=bel[a[i]]){
	     	x=bel[c[i]];y=bel[a[i]];
	     	if (mp[make_pair(x,y)]) continue;
	     	mp[make_pair(x,y)]=true;
	     	mp[make_pair(y,x)]=true;
	     	edge[x].push_back(y);
		 }
		else val2[bel[c[i]]]++;
	for (i=1;i<=n;i++) val2[i]/=2;
	resolve(1,0);
	cout<<dp[2]<<" "<<pw[m-edg[i]-1]<<endl;
	for (i=1;i<=tot;i++) 
	    {
		if (i==1) ans=(ans+dp[i]) % MOD;
		else ans=(ans+dp[i]*pw[m-edg[i]-1]) % MOD;
	    }
	printf("%lld\n",ans);
	return 0;
}
/*
I am failing!
*/
