用的是缩点+DP
#include<bits/stdc++.h>
#define ll long long
#define llINF 0x7FFFFFFFFFFFFFFF
#define intINF 0x7fffffff
using namespace std;
const int maxn = 1e6+5;
const ll mod = 1e9+7;
struct edge{
ll u,v;
};
vector<edge> e;
vector<ll> h[maxn];
struct node{
ll x,y,point,road,v;
} p[maxn];
ll tot=1,dfn[maxn],low[maxn],idx,scc[maxn],stot,if_bri[2000005];
ll vis[maxn],ans=1,dp[2][maxn],w[maxn],sizp[maxn],sizr[maxn],n,m,a,b;
vector<ll> g[maxn];
vector<node> bri;
void add(ll x,ll y){
e.push_back({x,y});
h[x].push_back(e.size()-1);
}
ll qsm(ll a,ll x){
ll s = 1;
while(x){
if(x & 1) s = s * a % mod;
a = a * a % mod;
x >>= 1;
}
return s % mod;
}
void tarjan(ll x,ll ine){
dfn[x] = low[x] = ++idx;
for(int i = 0; i < h[x].size(); ++i){
ll j = h[x][i], y = e[j].v;
if(!dfn[y]){
tarjan(y,j);
low[x] = min(low[x],low[y]);
if(dfn[x] < low[y]) {
if_bri[j] = if_bri[j^1] = 1;
bri.push_back({x,y});
}
}
else if(j != (ine ^ 1))
low[x] = min(low[x],dfn[y]);
}
}
void dfs(ll x,ll ine,ll &point,ll &road){
scc[x] = stot;
point++;
for(int i = 0; i < h[x].size(); ++i){
ll j = h[x][i], y = e[j].v;
if(!if_bri[j]) road++;
if(if_bri[j] || scc[y]) continue;
dfs(y,j,point,road);
}
}
void dfs1(int x,int fa){
dp[0][x] = p[x].v;
dp[1][x] = 0;
sizr[x] = p[x].road;
vis[x] = 1;
ll t = 0,sum = 1;
for(int y : g[x]){
if(y == fa) continue;
if(!t) t = 1;
dfs1(y,x);
sizr[x] += sizr[y] + 1;
t = t * (dp[0][y] + 2*qsm(2,sizr[y])) % mod;
sum = sum*2%mod*qsm(2,sizr[y])%mod;
}
if(t) dp[0][x] = qsm(2,p[x].road)*(((t - sum)%mod+mod) % mod) % mod + p[x].v * t % mod;
for(int y : g[x]){
if(y == fa) continue;
dp[1][x] = (dp[1][x] + (dp[0][y]*qsm(2,sizr[x]-sizr[y]-1)%mod + dp[1][y]*qsm(2,sizr[x]-sizr[y])%mod))%mod;
}
}
int main(){
cin >> n >> m;
for(int i = 1; i <= m; ++i){
cin >> a >> b;
add(a,b),add(b,a);
}
for(int i = 1; i <= n; ++i)
if(!dfn[i]) tarjan(i,0);
for(int i = 1; i <= n; ++i){
if(!scc[i]){
++stot;
dfs(i,0,p[stot].point,p[stot].road);
p[stot].road /= 2;
p[stot].v = (qsm(2,p[stot].point)-1) % mod * qsm(2,p[stot].road) % mod;
}
}
for(int i = 0; i < bri.size(); ++i){
g[scc[bri[i].x]].push_back(scc[bri[i].y]);
g[scc[bri[i].y]].push_back(scc[bri[i].x]);
}
for(ll i = 1; i <= stot; ++i) {
if(vis[i]) continue;
dfs1(i,i);
ans = ans*((dp[0][i]+dp[1][i])%mod)%mod;
}
cout << ans << endl;
return 0;
}