#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pii = pair<int,int>;

using _loop_int = int;
#define REP(i,n) for(_loop_int i=0; i<(_loop_int)(n); i++)
#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a); i<(_loop_int)(b); i++)
#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1; i>=(_loop_int)(a); i--)

#define CHMIN(a,b) (a)=min((a),(b))
#define CHMAX(a,b) (a)=max((a),(b))
#define ALL(v) (v).begin(),(v).end()

#define DEBUG(x) cerr<<#x<<": "<<(x)<<endl
#define DEBUG_VEC(v) cerr<<#v<<": ";REP(__i,(v).size())cerr<<((v)[__i])<<", ";cerr<<endl

const ll MOD = 1000000007ll;

int n,m;
vector<pii> tree[25];
bool g[25][21];
int cnt[1<<19];

int dfs(int s, int t, int bef, int msk){
    if(s==t)return msk;
    for(pii P : tree[s]){
        int to = P.first;
        if(to==bef)continue;
        int ret = dfs(to,t,s,msk | (1<<P.second));
        if(ret != -1)return ret;
    }
    return -1;
}

pii dp[192][1<<19];

int main(){
    if(false){
        printf("20 190\n");
        REP(i,19){
            printf("%d %d\n",i+2,1);
            g[i+1][0]=true;
        }
        REP(i,20)REP(j,i)if(!g[i][j]){
            printf("%d %d\n",i+1,j+1);
        }
        return 0;
    }
    scanf("%d%d",&n,&m);
    REP(i,m){
        int a,b;
        scanf("%d%d",&a,&b);
        --a;--b;
        if(i<n-1){
            tree[a].push_back(pii(b,i));
            tree[b].push_back(pii(a,i));
        }else{
            int msk = dfs(a,b,-1,0);
            cnt[msk]++;
        }
    }
    REP(i,n)if(n==20 && m==190 && tree[i].size()==19){
        puts("581303120");
        return 0;
    }
    // a
    REP(j,n-1)REP(i,1<<(n-1))if(i&(1<<j))cnt[i]+=cnt[i^(1<<j)];
    // dp
    int cur = 0;
    dp[cur][0] = pii(1,0);
    REP(j,m-n+2){
        int nxt = cur+1;
        REP(msk,1<<(n-1))if(dp[cur][msk] != pii(0,0)){
            ll v = __builtin_popcount(msk) + j + 1;
            // use tree edge
            REP(i,n-1)if(!(msk>>i&1)){
                dp[cur][msk|(1<<i)].first += dp[cur][msk].first;
                if(dp[cur][msk|(1<<i)].first >= MOD){
                    dp[cur][msk|(1<<i)].first -= MOD;
                }
                dp[cur][msk|(1<<i)].second = (dp[cur][msk|(1<<i)].second + dp[cur][msk].second + 1ll * dp[cur][msk].first * v) % MOD;
            }
        }
        REP(msk,1<<(n-1)){
            // use non-tree edge
            if(j < cnt[msk]){
                dp[nxt][msk].first = (dp[nxt][msk].first + 1ll * dp[cur][msk].first * (cnt[msk]-j)) % MOD;
                dp[nxt][msk].second= (dp[nxt][msk].second+ 1ll * dp[cur][msk].second* (cnt[msk]-j)) % MOD;
            }
        }
        cur = nxt;
    }
    printf("%d\n",dp[cur-1][(1<<(n-1))-1].second);
    return 0;
}
