#include<bits/stdc++.h>
#define int long long
#define ID(i) i*2-2
using namespace std;
const int N=5e5+5,M=1e6+5,mod=1e9+7;
int n,m,tot,col,ans,dfn[N],low[N],is[M],vis[N],dccV[N],dccE[N],in[N],siz[N],dp[N][2];
struct node{int to,id;};
struct edge{int x,y;}e[M];
vector<node>v[N];
vector<int>g[N];
int fpow(int a,int b,int p){int ans=1;while(b){if(b&1)ans=ans*a%p;a=a*a%p,b/=2;}return ans;}
void Tarjan(int x,int preid){
dfn[x]=low[x]=++tot;
for(int i=0;i<v[x].size();i++){
int to=v[x][i].to,id=v[x][i].id;
if((id^1)==preid)continue;
if(!dfn[to]){
Tarjan(to,id);
if(dfn[x]<low[to])is[id]=is[id^1]=1;
low[x]=min(low[x],low[to]);
}
else low[x]=min(low[x],dfn[to]);
}
return;
}
void DFS(int x,int now){
if(vis[x])return;
vis[x]=1,dccV[now]++,in[x]=now;
for(int i=0;i<v[x].size();i++){
int to=v[x][i].to,id=v[x][i].id;
if(is[id])continue;
DFS(to,now);
}
return;
}
void dfs(int x,int fa){
siz[x]=dccE[x];
for(int i=0;i<g[x].size();i++){
int to=g[x][i];
if(to==fa)continue;
DFS(to,x);
siz[x]+=siz[to]+1;
}
return;
}
void DP(int x,int fa){
for(int i=0;i<g[x].size();i++){
int to=g[x][i];
if(to==fa)continue;
DP(to,x);
dp[x][1]=(dp[to][1]*dp[x][0]%mod+(dp[to][0]*2%mod+dp[to][1])%mod*dp[x][1]%mod)%mod,dp[x][1]%=mod;
dp[x][0]=dp[to][0]*2%mod,dp[x][0]%=mod;
}
if(x==1)ans+=dp[x][1],ans%=mod;
else ans+=dp[x][1]*fpow(2,siz[1]-siz[x]-1,mod)%mod,ans%=mod;
return;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
e[i]={x,y};
v[x].push_back({y,ID(i)});
v[y].push_back({x,ID(i)+1});
}
for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i,-1);
for(int i=1;i<=n;i++)if(!vis[i])DFS(i,++col);
for(int i=1;i<=m;i++){
if(in[e[i].x]!=in[e[i].y])
g[in[e[i].x]].push_back(in[e[i].y]),g[in[e[i].y]].push_back(in[e[i].x]);
else dccE[in[e[i].x]]++;
}
for(int i=1;i<=col;i++)
dp[i][0]=fpow(2,dccE[i],mod),dp[i][1]=(fpow(2,dccE[i]+dccV[i],mod)-dp[i][0]+mod)%mod;
dfs(1,0),DP(1,0);
cout<<ans;
return 0;
}