#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
const int M=1e6;
const int mod=1e9+7;
struct node{
	int next,to;
}a[N];
int n,m,cnt=0,h[N],dfn[N],tim=0,low[N],s[N],top=0,num=0,c[N],numl[N];
int x[N],y[N],lu[N];
int nn=0;
long long ans=0,tot;
bool vis[N];
inline int shu(int x){
	if(x==1) return 2;
	long long ans1=1;
	for(int i=1;i<=x;i++){
		for(int j=x-i+1;j<=x;j++){
			ans1*=j;
			ans1%=mod;
		}
		for(int j=1;j<=i;j++){
			ans1/=j;
		}
	}
	return ans1+2;
}
inline void add(int fro,int to){
	a[++cnt].to=to;
	a[cnt].next=h[fro];
	h[fro]=cnt;
}
inline int tarjan(int x,int fa){
	low[x]=dfn[x]=++tim;
	s[++top]=x;
	vis[x]=1;
	for(int i=h[x];i;i=a[i].next){
		int v=a[i].to;
		if(v==fa) continue;
		if(!dfn[v]){
			tarjan(v,x);
			low[x]=min(low[v],low[x]);
		}
		else if(vis[v]) low[x]=min(low[x],dfn[v]);
	}
	if(dfn[x]==low[x]){
		num++;
		while(s[top]!=x){
			vis[s[top]]=0;
			c[s[top]]=num;
			numl[num]++;
			top--;
		}
		vis[s[top]]=0;
		c[s[top]]=num;
		numl[num]++;
		top--;
	}
}
inline int dfs(int x,int fa){
	for(int i=h[x];i;i=a[i].next){
		int v=a[i].to;
		tot=0;
		if(v==fa) continue;
		dfs(v,x);
		tot+=numl[v];
		tot%=mod;
		ans-=shu(n-tot)/2;
	}
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x[i],&y[i]);
		add(x[i],y[i]);add(y[i],x[i]);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]) tarjan(i,0);
	}
	memset(a,0,sizeof(a));
	memset(h,0,sizeof(h));
	cnt=0;
	for(int i=1;i<=m;i++){
		if(c[x[i]]==c[y[i]]){
			lu[c[x[i]]]++;
		}
		else{
			nn++;
			add(c[x[i]],c[y[i]]);
			add(c[y[i]],c[x[i]]);
		}
	}
	if(m==n-1){
		if(m==1) printf("%d",5);
		printf("%lld",(3*6*(m-1)-1)%mod);
		return 0;
	}
	ans=(shu(n))*shu(m)-shu(m);
	ans%=mod;
	dfs(1,0);
	printf("%lld",ans);
}
