#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3fll
#define For(i_,l_,r_) for(int i_=(l_);i_<=(r_);i_++)
#define Rep(i_,l_,r_) for(int i_=(l_);i_>=(r_);i_--)
using namespace std;
#define Ci const int
#define Cl const ll
#define Cul const ull
#define Cc const char
int _l=-1,_p;Ci inS=1<<18,ouS=1<<18;
char _c[inS],*_u=_c,*_v=_c,_b[ouS],_d[55];
#define getchar() (_u==_v&&(_v=(_u=_c)+fread(_c,1,inS,stdin),_u==_v)?EOF:*_u++)
#define _c_ getchar()
template<typename T=int>inline T read(){
	char ch=_c_;T X=0;bool fl=0;while(ch<48||ch>57)fl|=(ch==45),ch=_c_;
	while(ch>47&&ch<58)X=X*10+(ch^48),ch=_c_;return fl?-X:X;
}
inline char Gec(){
	char ch=_c_;while(ch<33)ch=_c_;return ch;
}
inline void flush(){fwrite(_b,1,_l+1,stdout);_l=-1;}
inline void _pc(Cc c){if(c!=-1)_b[++_l]=c;}
inline void _chf(){if(_l>(ouS>>1))flush();}
template<typename T=int>inline void write(T x,Cc c=-1){
	if(x<0)_pc(45),x=-x;do{_d[++_p]=(x%10)|48;}while(x/=10);
	do{_b[++_l]=_d[_p];}while(--_p);_pc(c);_chf();
}
inline void write(Cc c){_pc(c);}
inline void puc(Cc c){_pc(c);_chf();}
template<typename T,typename...A>void write(T x,A...a){write(x);write(a...);}
const int M=1000000007,inv2=500000004;
inline int Add(Ci x,Ci mod=M){return x>=mod?x-mod:x;}
int n,m,C;
int hd[500005],cnt=1,siz[500005];
struct E{
	int nxt,to;
}e[2000005];
inline void add(Ci u,Ci v){
	e[++cnt]={hd[u],v};
	hd[u]=cnt;
}
namespace tarjan{
int hd[500005],cnt=1;
struct E{
	int nxt,to;
}e[2000005];
inline void Add(Ci u,Ci v){
	e[++cnt]={hd[u],v};
	hd[u]=cnt;
}
inline void add(Ci u,Ci v){Add(u,v);Add(v,u);}
int dfn[500005],low[500005],idx;bool bri[2000005];
void dfs(Ci u,Ci ine){
//	cerr<<u<<" "<<idx<<"\n";
	low[u]=dfn[u]=++idx;
	for(int i=hd[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(!dfn[v]){
			dfs(v,i);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u])/*cerr<<u<<" "<<v<<"\n",*/bri[i]=bri[i^1]=1;
		}
		else if((i^1)!=ine)low[u]=min(low[u],dfn[v]);
	}
}
int bel[500005];
void search(Ci u){
	bel[u]=C;siz[C]++;
	for(int i=hd[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(bri[i]||bel[v])continue;
		search(v);
	}
}
void work(){
	dfs(1,0);
	For(i,1,n)
		if(!bel[i])++C,search(i)/*,cout<<C<<' '<<siz[C]<<"\n"*/;
	For(i,1,n){
		for(int j=hd[i];j;j=e[j].nxt){
			int v=e[j].to;
			if(v<i)continue;
			if(bel[i]!=bel[v]){
//				cerr<<bel[i]<<' '<<bel[v]<<"\n";
				::add(bel[i],bel[v]);
				::add(bel[v],bel[i]);
			}
		}
	}
}
}
int pw[500005],f[500005],vis[500005];
void dfs(Ci u,Ci fa){
	for(int i=hd[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa)continue;
		dfs(v,u);vis[u]|=vis[v];
		if(vis[v])f[u]+=f[v]+1;
	}
}
signed main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	n=read(),m=read();pw[0]=1;
	For(i,1,m){
		pw[i]=(pw[i-1]<<1)%M;
		int x=read(),y=read();
		tarjan::add(x,y);
	}
	tarjan::work();
	int ans=0;
	For(I,1,(1<<C)-1){
		int R=0,res=1;
		For(i,1,C){
			vis[i]=(I>>(i-1))&1;f[i]=0;
			if(vis[i])R=i,res=1ll*res*(pw[siz[i]]-1)%M;
		}
		dfs(R,0);
		ans=(ans+1ll*res*pw[m-f[R]])%M;
	}
	write(ans,'\n');
	flush();return 0;
}
