#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <string>
#include <sstream>
#include <complex>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <functional>

using namespace std;
 
#define mod 1000000007
#define FOR(x,to) for(int x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
#define long long long
inline int rei(){int x;cin>>x;return x;}
inline long rel(){long x;cin>>x;return x;}
inline string res(){string x;cin>>x;return x;}
//-------------------------------------------------------
struct Fact{
	vector<long> f;
	vector<long> rf;
	long pow(long N,long K){
		if(K == 0){
			return 1;
		}
		else if(K % 2 == 0){
			long t = pow(N,K/2);
			return t*t%mod;
		}
		else{
			return N*pow(N,K-1)%mod;
		}
	}
	Fact(int N):f(N+1),rf(N+1){
		for(int i=0;i<N+1;i++){
			if(i == 0){
				f[i] = 1;
			}
			else{
				f[i] = (f[i-1]*i)%mod;
			}
		}
		for(int i=N;i>=0;i--){
			if(i == N){
				rf[i] = pow(f[N],mod-2);
			}
			else{
				rf[i] = rf[i+1]*(i+1)%mod;
			}
		}
	}
	long GetFact(int N){
		return f[N];
	}
	long GetPerm(int N,int R){
		return f[N] * rf[N-R] % mod;
	}
	long GetConv(int N,int R){
		return ((f[N]*rf[R])%mod*rf[N-R])%mod;
	}
	long GetRev(int N){
		if(N == 0){
			return 1;
		}
		else{
			return rf[N] * f[N-1] % mod;
		}
	}
}; 
void dfs(int N,vector<int> G[],function<void(int,int,int)> F){
	stack<pair<int,int>> sp;
	sp.push({0,-1});
	while(!sp.empty()){
		int v = sp.top().first;
		int f = sp.top().second;
		sp.pop();
		for(int i=0;i<G[v].size();i++){
			int t = G[v][i];
			if(t != f){
				sp.push({t,v});
				F(t,v,i);
			}
		}
	}
}
vector<int> G[20];
vector<int> O[20];
int parent[20];
int depth[20];
int familyedge[20];
long C[21][400];
int bitedge[1 << 20];
int bitc[1 << 20];
long DP[1 << 20];
long DP2[1 << 20];
void Calc(){
	int N = rei();
	int M = rei();
	for(int i=0;i<N-1;i++){
		int f = rei()-1;
		int t = rei()-1;
		G[f].push_back(t);
		G[t].push_back(f);
		O[f].push_back(i);
		O[t].push_back(i);
	}
	function<void(int,int,int)> Fu = [&](int v,int f,int e){
		parent[v] = f;
		if(f != -1){
			depth[v] = depth[f]+1;
			familyedge[v] = O[f][e];
		}
	};
	dfs(N,G,Fu);
	for(int i=N-1;i<M;i++){
		int f = rei()-1;
		int t = rei()-1;
		int c = 0;
		while(depth[f] < depth[t]){
			c ^= (1 << familyedge[t]);
			t = parent[t];
		}
		while(depth[f] > depth[t]){
			c ^= (1 << familyedge[f]);
			f = parent[f];
		}
		while(f != t){
			c ^= (1 << familyedge[f]);
			c ^= (1 << familyedge[t]);
			f = parent[f];
			t = parent[t];
		}
		bitedge[c]++;
	}
	for(int i=0;i<N-1;i++){
		for(int j=0;j<1<<(N-1);j++){
			if((1 << i) & j){
				bitedge[j] += bitedge[j - (1 << i)];
			}
		}
	}
	for(int i=0;i<1<<(N-1);i++){
		int c = 0;
		for(int j=0;j<N-1;j++){
			if(i & (1 << j)){
				c++;
			}
		}
		bitc[i] = c;
	}
	Fact F(M);
	DP2[0] = 1;
	for(int i=1;i<1<<(N-1);i++){
		long c = 0;
		long c2 = 0;
		for(int j=0;j<N-1;j++){
			if((i & (1 << j)) == 0){
				continue;
			}
			int diff = bitedge[(1 << (N-1)) - 1 - i + (1 << j)] - bitedge[(1 << (N-1)) - 1 - i];
			int d = bitc[i - (1 << j)] + (M-N+1 - bitedge[(1 << (N-1)) - 1 - i + (1 << j)]);
			long cj = DP[i - (1 << j)] * F.GetFact(diff+d+1) % mod * F.rf[d+1] % mod;
			long c2j = DP2[i - (1 << j)] * F.GetFact(diff+d) % mod * F.rf[d] % mod;
			cj += bitc[i] * c2j;
			cj %= mod;
			c += cj;
			c2 += c2j;
		}
		DP[i] = c % mod;
		DP2[i] = c2 % mod;
	}
	cout << DP[(1 << (N-1)) - 1] << endl;
}
int main(int argc,char** argv){
	ios::sync_with_stdio(false), cin.tie(0);
	cout.tie(0); Calc(); return 0;
}

Measured memory_bytes: 20736