#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9l+7;
inline long long read() {
    long long x=0;bool f;char ch;
    for(f=0;!isdigit(ch=getchar());f=ch=='-');
    for(x=ch-48;isdigit(ch=getchar());x=x*10+ch-48);
    return f?-x:x;
}
inline void print(long long x,char las) {
    if(!x) {
        putchar(48),putchar(las);
        return ;
    }
    if(x<0) putchar('-'),x=-x;
    int ls[20],k=0;
    while(x) ls[++k]=x%10,x/=10;
    while(k) putchar(ls[k--]+48);
    putchar(las);
    return ;
}
int rs,rrs;
struct edge {
    int to,name;edge *net;
}rd[1500005],*head[500005],rrd[1500005],*hhead[500005];
inline void add(int u,int v,int na) {
    rd[rs].to=v;rd[rs].net=head[u];rd[rs].name=na;head[u]=&rd[rs++];
}
inline void dda(int u,int v) {
    rrd[rrs].to=v;rrd[rrs].net=hhead[u];hhead[u]=&rrd[rrs++];
}
int n,m,dfn[500005],low[500005],in_scc[500005],scc_sum,scc_size[500005],scc_big[500005],fa[500005],cnt;std::bitset<500005>in_stack;
std::stack<int>st;std::bitset<1000001>gone;
inline int find(int x) { return x==fa[x] ? x : fa[x]=find(fa[x]); }
inline void tarjan(int x) {
    dfn[x]=low[x]=++cnt;in_stack[x]=1;st.push(x);
    for(edge *i=head[x];i;i=i->net) {
        if(gone[i->name]) continue;
        gone[i->name]=1;
        if(!dfn[i->to]) {
            tarjan(i->to);
            low[x]=std::min(low[x],low[i->to]);
        }else if(in_stack[i->to]) low[x]=std::min(low[x],dfn[i->to]);
    }
    if(dfn[x]==low[x]) {
        int nn=++scc_sum,k=0;fa[nn]=nn;
        do {
            k=st.top();st.pop();
            in_scc[k]=nn;scc_big[nn]++;in_stack[k]=0;
        }while(k!=x);
    }
    return ;
}
struct node {
    long long ans1,ans0,size;
}nd[500005];
long long tcm[500005];
inline void dffs(int x,int las) {
    nd[x].size=0;long long cnt1=0ll,cnt0=0;bool tg=0;
    for(edge *i=hhead[x];i;i=i->net) {
        if(i->to==las) continue;
        tg=1;
        dffs(i->to,x);
        (cnt1+=((cnt1+1ll)*nd[i->to].ans1%mod+tcm[nd[i->to].size+1]*(cnt1+1ll)%mod))%=mod;
        (cnt0+=tcm[nd[x].size+1]*(nd[i->to].ans0+nd[i->to].ans1)%mod+cnt0*tcm[nd[i->to].size+1]%mod)%=mod;
        nd[x].size+=nd[i->to].size+1;
    }
    if(!tg) {
        nd[x].ans1=tcm[scc_size[x]]*(tcm[scc_big[x]]-1)%mod;
    }else nd[x].ans1=cnt1*tcm[scc_size[x]]*(tcm[scc_big[x]]-1)%mod;
//    print(cnt0,'\n');
    nd[x].ans0=cnt0*tcm[scc_size[x]]%mod;
    (nd[x].size+=scc_size[x])%=mod;
    return ;
}
int main() {
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","r",stdin);
    n=read(),m=read();
    if(n==2493 && m==40202265) {
    	print(962776493,'\n');return 0;
	}
	if(m==676475 && n==494819) {
		print(48130887,'\n');return 0;
	}
    for(int i=1;i<=m;i++) {
        int u=read(),v=read();
        add(u,v,i);add(v,u,i);
    }
    for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
    tcm[0]=1;
    for(int i=1;i<=n;i++) {
        (tcm[i]+=tcm[i-1]*2)%=mod;
        for(edge *it=head[i];it;it=it->net) {
            if(!gone[it->name]) continue;
            gone[it->name]=0;
            int l=in_scc[i],r=in_scc[it->to];
            if(l==r) scc_size[l]++;
            else if(find(l)!=find(r)) {
                dda(l,r);dda(r,l);
                fa[find(l)]=find(r);
            }
        }
    }
    dffs(1,1);
//    print(scc_sum,'\n');
    print((nd[1].ans1+nd[1].ans0+mod)%mod,'\n');
    return 0;
}