#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline", "fast-math", "unroll-loops", "no-stack-protector")
#pragma GCC diagnostic error "-fwhole-program"
#pragma GCC diagnostic error "-fcse-skip-blocks"
#pragma GCC diagnostic error "-funsafe-loop-optimizations"
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstring>
#define ll long long
using namespace std;
namespace io {
	const int SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55];
	int f, qr;
#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	inline void flush () {
		fwrite (obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	inline void putc (char x) {
		*oS ++ = x;
		if (oS == oT) flush ();
	}
	template<class T>
	inline void getc(T &x)
	{
		for(c=gc();!((c>='a'&&c<='z')||(c>='A'&&c<='Z'));c=gc());
		x=c;
	}
	template <class I>
	inline void rd (I &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15);
		x *= f;
	}
	template <class I>
	inline void print (I x) {
		if (!x) putc ('0');
		if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
	}
	struct Flusher_ {
		~Flusher_() {
			flush();
		}
	} io_flusher_;
}
using io :: rd;
using io :: putc;
using io :: print;
using io :: getc;

const int MOD=1e9+7;
int mo(int x,int y)
{
	return x+y>=MOD?x+y-MOD:x+y;
}
int mu(int x,int y)
{
	return (ll)x*y%MOD;
}
int sub(int x,int y)
{
	return x<y?x-y+MOD:x-y;
}
int ksm(int x,int y)
{
	int res=1;
	for(;y;y>>=1,x=mu(x,x))
	if(y&1) res=mu(res,x);
	return res;
}
const int MAXN=200+5;
pair<int,int>e[MAXN];
vector<int>g[MAXN];
int n,m;
ll dp[2][(1<<19)|1],sum[2][(1<<19)|1];
int els[(1<<19)|1],bin[(1<<19)|1],dep[MAXN],fa[MAXN],id[(1<<19)|1];
void dfs(int x,int ff)
{
	dep[x]=dep[ff]+1;fa[x]=ff;
	for(int i=0;i<g[x].size();i++)
	{
		int v=g[x][i];
		if(v==ff) continue;
		dfs(v,x);
	}
}
/*
int jc[MAXN],jcn[MAXN];
int C(int n,int m)
{
	return (n<m)?0:mu(jc[n],mu(jcn[m],jcn[n-m]));
}
*/
int ADD(int x,int y)
{
	return x<=0?0:(ll)x*y%MOD;
}
int up[MAXN];
int main()
{
//	freopen("B.in","r",stdin);
//	freopen("B.out","w",stdout);
	rd(n);rd(m);
	for(int i=1,x,y;i<=m;i++)
	{
		rd(x);rd(y);
		e[i]=make_pair(x,y);
		if(i<=n-1)
		{
			g[x].push_back(y);
			g[y].push_back(x);
		}
		
	}
	dfs(1,0);
/*	for(int i=n,x,y;i<=m;i++)
	{
			x=e[i].first,y=e[i].second;
			while(x!=y)
			{
				if(dep[x]>dep[y])
				{
					SL[i]|=(1<<x-1);
					x=fa[x];
				}
				else
				{	
					SL[i]|=(1<<y-1);
					y=fa[y];
				}
			}
	}*/
	int es=n-1;
	for(int S=1;S<(1<<es);S++)
		bin[S]=bin[S-(S&(-S))]+1;
	for(int i=1;i<=es;i++)
	id[(1<<(i-1))]=i;
	/*
	for(int S=0;S<(1<<es);S++)
	{
		int nowS=0;
		for(int j,i=S,x,y;i;i-=i&(-i))
		{
			j=id[i&(-i)];
			x=e[j].first;y=e[j].second;
			nowS|=(dep[x]<dep[y])?(1<<y-1):(1<<x-1);
		}
		for (int i=n;i<=m;i++)
		 els[S]+=((SL[i]&nowS)==SL[i]);
	//	if(cnt) fprintf(stderr,"%d %d\n",S,els[S]);
	}*/
	for(int i=1,x,y;i<n;i++)
	{
		x=e[i].first;y=e[i].second;
		up[(dep[x]<dep[y])?y:x]=i;
	}
	for(int i=n,x,y,S;i<=m;i++)
	{
		S=0;
			x=e[i].first,y=e[i].second;
			while(x!=y)
			{
				if(dep[x]>dep[y])
				{
					S|=(1<<(up[x]-1));
					x=fa[x];
				}
				else
				{	
					S|=(1<<up[y]-1);
					y=fa[y];
				}
			}
			++els[S];
	}
	for(int i=0;i<es;i++)
	for(int j=0;j<(1<<es);j++)
	if((j>>i)&1)
		els[j]+=els[j^(1<<i)];
	
	for(int j=0;j<(1<<es);j++)
	els[j]+=bin[j];
	
	
/*	for(int i=jc[0]=1;i<=m;i++) jc[i]=mu(jc[i-1],i);
	jcn[m]=ksm(jc[m],MOD-2);
	for(int i=m;i;i--)
	jcn[i-1]=mu(jcn[i],i);
	*/
//	fprintf(stderr,"err");
	dp[0][0]=1;int cur=0,nxt=1;
	for(int i=1;i<=m;i++)
	{
		for(register int S=0,v;S<(1<<es);els[S]--,++S)
		if(dp[cur][S])
		{
			dp[cur][S]=(dp[cur][S]>=1000000000000000ll)?dp[cur][S]%MOD:dp[cur][S];
			sum[cur][S]=(sum[cur][S]>=1000000000000000ll)?sum[cur][S]%MOD:sum[cur][S];
		//	v=(els[S]-(i-1-bin[S]));
				dp[nxt][S]+=els[S]>0?dp[cur][S]*els[S]:0;
				sum[nxt][S]+=els[S]>0?sum[cur][S]*els[S]:0;
				
			for(register int  j=(1<<es)-1-S;j;j^=j&(-j))
			{
				int t=id[j&(-j)];
				dp[nxt][S|(1<<(t-1))]+=dp[cur][S];
				sum[nxt][S|(1<<(t-1))]+=dp[cur][S]*i+sum[cur][S];
			}
			dp[cur][S]=sum[cur][S]=0;
		}
		cur^=1;nxt^=1;
	}
	print(sum[cur][(1<<es)-1]%MOD);
	putc('\n');
				
	return 0;	
}

Measured memory_bytes: 24960