#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int MAXN=500005;
const int mod=(1e9+7);

inline int read(int t=0,bool f=1,char c=0){
    while(!isdigit(c=getchar())) f=c^45;
    while(isdigit(c)) t=(t<<1)+(t<<3)+(c^48) , c=getchar();
    return f?t:-t;
}

vector<int> to[MAXN];
int head[MAXN];
ll fac[MAXN];
ll plan1[MAXN],plan0[MAXN];
vector<int> H;
ll f[MAXN][5];
ll g[MAXN][3];
ll Siz[MAXN];


namespace Tarjan{

    int num[MAXN],low[MAXN],dfn;
    int stk[MAXN],top;
    bool in_stk[MAXN];

    void dfs(int x,int fa){
        num[x]=low[x]=++dfn;
        stk[++top]=x;
        in_stk[x]=1;
        for(int i=0;i<to[x].size();++i){
            int v=to[x][i];
            if(!num[v]){
                dfs(v,x);
                low[x]=min(low[x],low[v]);
            }
            else if(in_stk[v]&&v!=fa){
                low[x]=min(low[x],num[v]);
            }
        }
        
        if(num[x]==low[x]){
            H.push_back(x);
            int siz=0;
            while(stk[top+1]!=x){
                int t=stk[top];
                top--;
                head[t]=x;
                in_stk[t]=0;
                siz++;
            }
            if(siz==1){
                g[x][0]=1;
                g[x][1]=1;
            }
            else{
                g[x][0]=fac[siz];
                g[x][1]=(fac[siz]-1+mod)%mod*fac[siz]%mod;
            }
        // cout<<x<<" "<<f[x]<<" "<<low[x]<<endl;
        }
    }


}

vector<int> To[MAXN];
ll res=0;

ll qpow(ll x,ll b){
    ll res=1;
    ll a=x%mod;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

int si[MAXN],all;
void dfs_init(int x,int fa){
    si[x]=Siz[x]/2;
    for(int i=0;i<To[x].size();++i){
        int v=To[x][i];
        if(v==fa) continue;
        dfs_init(v,x);
        si[x]+=si[v]+1;
    }
    // cout<<x<<" "<<si[x]<<endl;
}

void dfs(int x,int fa){
   f[x][0]=1;
    for(int i=0;i<To[x].size();++i){
        int v=To[x][i];
        if(v==fa) continue;
        dfs(v,x);
        res=(res+f[v][1]*fac[all-si[v]-1]%mod)%mod;
        // cout<<res<<endl;
        f[x][1]=((f[x][0]+f[x][1])%mod*f[v][1]%mod+f[x][1]*f[v][0]*2%mod)%mod;
        f[x][0]=f[x][0]*f[v][0]%mod*2%mod;
    }
    // cout<<x<<" "<<f[x][0]<<" "<<f[x][1]<<endl;
    if(!f[x][1])
        f[x][1]=g[x][1];
    else
        f[x][1]=((f[x][0]+f[x][1])%mod*g[x][1]%mod+f[x][1]*g[x][0]%mod)%mod;
    f[x][0]=f[x][0]*g[x][0]%mod;
//    cout<<x<<" "<<f[x][0]<<" "<<f[x][1]<<endl;
}

namespace line{

    ll f[MAXN][2];

    void solve(int n,int m){
        f[1][0]=f[1][1]=1;
        ll res=0;
        for(int i=2;i<=n;++i){
            res=(res+f[i-1][1]*fac[m-i+1]%mod)%mod;
            f[i][0]=(f[i-1][0]*2)%mod;
            f[i][1]=(f[i-1][1]*2+f[i-1][0]*2)%mod;
        }
        res=(res+((f[n][0]+f[n][1])%mod+mod-fac[m])%mod)%mod;
        cout<<res<<endl;
    }

}

int main(){

    freopen("barrack.in","r",stdin);
    freopen("barrack.out","w",stdout);

    int n,m;
    n=read();
    m=read();
    bool Flag=0;
    if(m==n-1) Flag=1;
    fac[0]=1;
    for(int i=1;i<=n;++i){
        fac[i]=fac[i-1]*2%mod;
    }
    for(int i=1;i<=m;++i){
        int u,v;
        u=read();
        v=read();
        to[u].push_back(v);
        to[v].push_back(u);
        if(u+1!=v&&v+1!=u) Flag=0; 
    }
    if(Flag){
        line::solve(n,m);
        return 0;
    }

    for(int i=1;i<=n;++i){
        if(!Tarjan::num[i])
            Tarjan::dfs(i,i);
    }
    for(int u=1;u<=n;++u){
        for(int j=0;j<to[u].size();++j){
            int v=to[u][j];
            int fu=head[u];
            int fv=head[v];
            if(fu!=fv){
                To[fu].push_back(fv);
            }
            else{
                Siz[fu]++;
            }
        }
    }
    // for(int i=0;i<H.size();++i)
    //     cout<<H[i]<<endl;
    int S=head[1];
    dfs_init(S,S);
    all=si[S];
    // cout<<all<<endl;
    dfs(S,S);
    res=(res+f[S][0]+f[S][1])%mod;
    cout<<(res-fac[m]+mod)%mod<<endl;


    return 0;
}