#include <bits/stdc++.h>
using namespace std;

#define TRACE(x) x
#define WATCH(x) TRACE(cout << #x" = " << x << endl)
#define WATCHR(a, b) TRACE(for (auto it=a; it!=b;) cout << *(it++) << " "; cout << endl)
#define WATCHC(V) TRACE({cout << #V" = "; WATCHR(V.begin(), V.end());})

#define all(x) (x).begin(), (x).end()

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vs = vector<string>;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

template<int MOD> struct modnum {
    int v;
    modnum() : v(0) {}
    modnum(ll _v) : v(_v % MOD) { if (v < 0) v += MOD; }
    explicit operator int() const { return v; }
    friend ostream& operator << (ostream& o, const modnum& n) { return o << n.v; }
    friend istream& operator << (istream& i, modnum& n) { ll v; i >> v; n = modnum(v); return i; }

    friend bool operator == (const modnum& a, const modnum& b) { return a.v == b.v; }
    friend bool operator != (const modnum& a, const modnum& b) { return a.v != b.v; }

    modnum& operator += (const modnum& o) { v += o.v; if (v >= MOD) v -= MOD; return *this; }
    modnum& operator -= (const modnum& o) { v -= o.v; if (v < 0) v += MOD; return *this; }
    modnum& operator *= (const modnum& o) { v = int(ll(v) * ll(o.v) % MOD); return *this; }
    modnum operator - () { modnum res; if (v) res.v = MOD - v; return res; }
    friend modnum operator + (const modnum& a, const modnum& b) { return modnum(a) += b; }
    friend modnum operator - (const modnum& a, const modnum& b) { return modnum(a) -= b; }
    friend modnum operator * (const modnum& a, const modnum& b) { return modnum(a) *= b; }

    modnum pow(int e) const {
        if (e == 0) return 1;
        if (e & 1) return *this * this->pow(e-1);
        return (*this * *this).pow(e/2);
    }

    modnum inv() const {
        int g = MOD, x = 0, y = 1;
        for (int r = v; r != 0; ) {
            int q = g / r;
            g %= r; swap(g, r);
            x -= q * y; swap(x, y);
        }

        assert(g == 1);
        assert(y == MOD || y == -MOD);
        return x < 0 ? x + MOD : x;
    }
    modnum& operator /= (const modnum& o) { return (*this) *= o.inv(); }
    friend modnum operator / (const modnum& a, const modnum& b) { return modnum(a) /= modnum(b); }
};
using mn = modnum<1000000007>;

void go(int N, int loc, int par, auto &adj, vi &path) {
    for (auto p : adj[loc]) {
        if (p.second >= N - 1 || p.first == par) continue;
        path[p.first] = path[loc] ^ (1 << p.second);
        go(N, p.first, loc, adj, path);
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int N, M;
    cin >> N >> M;

    vi sum(M + 1);
    for (int i = 1; i <= M; i++)
        sum[i] = sum[i-1] + i;

    vector<mn> fact(M + 2);
    fact[0] = 1;
    for (int i = 1; i <= M + 1; i++) {
        fact[i] = fact[i - 1] * i;
    }

    vector<vector<mn>> ncr(M + 1, vector<mn>(M + 1, 0));
    ncr[0][0] = 1;
    for (int n = 1; n <= M; n++) {
        for (int r = 0; r <= n; r++) {
            ncr[n][r] = ncr[n-1][r];
            if (r) ncr[n][r] += ncr[n-1][r-1];
        }
    }

    vi a(M), b(M);
    vector<vector<pair<int, int>>> adj(N);

    for (int i = 0; i < M; i++) {
        cin >> a[i] >> b[i];
        a[i]--;
        b[i]--;
        adj[a[i]].emplace_back(b[i], i);
        adj[b[i]].emplace_back(a[i], i);
    }

    vi path(N);
    go(N, 0, 0, adj, path);

    vi use(M);
    for (int e = N - 1; e < M; e++) {
        use[e] = path[a[e]] ^ path[b[e]];
    }

    const int MLIM = 1 << (N - 1);
    vector<int> used(MLIM);
    vector<mn> ways(MLIM), totw(MLIM);
    used[0] = 0, ways[0] = 1, totw[0] = 0;

    vi cover(MLIM);
    for (int m = 0; m < MLIM; m++) {
        for (int e = N - 1; e < M; e++) {
            if (m & use[e])
                cover[m]++;
        }
    }

    for (int m = 0; m < MLIM; m++) {
        for (int i = 0; i < N - 1; i++) {
            if ((m >> i)&1) continue;

            int intro = cover[m ^ (1 << i)] - cover[m];

            used[m ^ (1 << i)] = used[m] + 1 + intro;
            mn comb = ncr[intro + used[m]][used[m]] * fact[intro];
            ways[m ^ (1 << i)] += ways[m] * comb;
            totw[m ^ (1 << i)] += totw[m] * fact[used[m] + intro + 1] / fact[used[m] + 1]
                                + ways[m] * comb * (__builtin_popcount(m) + 1);
        }
    }

    cout << totw.back() << endl;

    return 0;
}



Measured memory_bytes: 10496