#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll ;
#define REP(i,j,k) for(int i=j;i<=k;++i)
#define For(G,X) for(int I=G.head[X],to=G.ver[I];I;I=G.nxt[I],to=G.ver[I])
inline int read(){
	int v=0,f=1; char c=getchar();
	while(c<48||57<c){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(48<=c&&c<=57) v=(v<<3)+(v<<1)+(c^48),c=getchar();
	return v*f;
}
inline ll readL(){
	ll v=0,f=1; char c=getchar();
	while(c<48||57<c){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(48<=c&&c<=57) v=(v<<3)+(v<<1)+(c^48),c=getchar();
	return v*f;
}
inline void print(int x){
	if(x>9) print(x/10);
	putchar(x%10+48);
}
inline void printL(ll x){
	if(x>9) printL(x/10);
	putchar(x%10+48);
}
inline void write(int x,char c){
	if(x<0) putchar('-'),x=-x;
	print(x),putchar(c);
}
inline void writeL(ll x,char c){
	if(x<0) putchar('-'),x=-x;
	printL(x),putchar(c);
}
const int N=16+5,M=25+5,p=1e9+7;
int n,m,x,y,dfn[N],low[N],tim,col[N],cnt,ed[N],ftr[N],del1,del2,mark[N]; bool cut[M<<1],pas[N];
ll po[M],Ans;
struct Graph{
	int tot,head[N],ver[M<<1],nxt[M<<1];
	inline void add(int x,int y) { ver[++tot]=y,nxt[tot]=head[x],head[x]=tot; }
} g1 ,g2 ;
inline void tarjan(int x,int in_edge){
	dfn[x]=low[x]=++tim;
	For(g1,x){
		if(!dfn[to]) tarjan(to,I),low[x]=min(low[x],low[to]);
		else if(I!=(in_edge^1)) low[x]=min(low[x],dfn[to]);
		if(low[to]>dfn[x]) cut[I]=cut[I^1]=1;
	}
}
inline void dfs(int x,int cnt){
	col[x]=cnt;
	For(g1,x) if(!cut[I]&&!col[to]) dfs(to,cnt);
}
inline void pre_dfs(int x,int fa){
	ftr[x]=fa;
	For(g2,x) if(to!=fa) ed[to]=I,pre_dfs(to,x);
}
inline bool check(int x,int fa){
	bool flag=mark[x];
	For(g2,x) if(to!=fa){
		if((x==del1&&to==del2)||(x==del2&&to==del1)) continue;
		flag|=check(to,x);
	}
	return flag;
}
int main(){
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	n=read(),m=read();
	po[0]=1; REP(i,1,m) po[i]=po[i-1]*2%p;
	g1.tot=g2.tot=1;
	REP(i,1,m) x=read(),y=read(),g1.add(x,y),g1.add(y,x);
	REP(i,1,n) if(!dfn[i]) tarjan(i,0);
	REP(i,1,n) if(!col[i]) ++cnt,dfs(i,cnt);
	REP(i,1,n) For(g1,i) if(cut[I]) g2.add(col[i],col[to]);
	pre_dfs(1,0);
	REP(S,1,(1<<n)-1){
		memset(mark,0,sizeof mark);
		REP(i,1,n) if(S&(1<<(i-1))) mark[col[i]]=1;
		int sum=0;
		REP(i,1,n) For(g2,i){
			del1=i,del2=to;
			if(check(i,i)&&check(to,to)) ++sum;
		}
		(Ans+=po[m-sum/2])%=p;
	}
	writeL(Ans,'\n');
}
