#include<bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
int n, m;
vector<int> adj[20];
long long dp[1<<20][20];
// dp[mask][u]: số cách đi qua tập mask, dừng tại u
int main(){
cin.tie(0)->sync_with_stdio(0);
// if(fopen("Hamiltonian_Flights.inp","r")){...}
cin >> n >> m;
for(int i=0; i<m; i++){
int u, v; cin >> u >> v;
// Chuyển về 0-index: 1..n -> 0..n-1
adj[u-1].push_back(v-1);
}
// Cơ sở: Tại trạng thái chỉ có bit 0 (thành phố 1), đứng tại 0 -> có 1 cách
dp[1][0] = 1;
// Duyệt qua tất cả các trạng thái từ mask nhỏ đến lớn
for(int s = 2; s < (1 << n); s++){
// Nếu mask s không chứa đỉnh xuất phát (bit 0) -> Bỏ qua
if(!((s >> 0) & 1)) continue;
// Nếu mask s chứa đỉnh đích (bit n-1) nhưng chưa full đỉnh -> Bỏ qua
// (Vì đến đích là dừng, không thể đi tiếp để lấp đầy mask được nữa)
if(((s >> (n-1)) & 1) && s != ((1 << n) - 1)) continue;
// Duyệt các đỉnh i đang có trong mask s
for(int i = 0; i < n; i++){
if((s >> i) & 1){
// Trạng thái trước đó: mask s bỏ đi bit i
int prev = s ^ (1 << i);
// Ai có thể đi tới i?
// Ở đây ta dùng tư duy ngược: Thay vì tìm ai đến i,
// ta nên duyệt xuôi ở vòng for trước thì tốt hơn.
// Nhưng để code ngắn gọn, ta duyệt các đỉnh j trong adj của prev
// thì hơi khó vì adj là chiều xuôi.
// -> Cách tối ưu: Duyệt j, xong đẩy cho adj[j]
}
}
}
// Viết lại đoạn loop trên theo kiểu Push DP (Đẩy) cho thuận chiều adj
// Reset lại loop cho dễ hiểu:
// Duyệt mask
for(int s = 1; s < (1 << n); s++){
// Chỉ xét mask có chứa đỉnh xuất phát
if(!((s >> 0) & 1)) continue;
// Duyệt đỉnh u hiện tại đang đứng trong mask s
for(int u = 0; u < n; u++){
if((s >> u) & 1){
if(dp[s][u] == 0) continue;
// Từ u bắn sang v
for(int v : adj[u]){
// Nếu v đã có trong mask s rồi -> Bỏ qua (đề bài thăm đúng 1 lần)
if((s >> v) & 1) continue;
// Nếu v là đích (n-1) nhưng đi xong v mà mask chưa full -> Bỏ qua
if(v == n-1 && (s | (1 << v)) != ((1 << n) - 1)) continue;
// Cộng dồn số cách
int next_mask = s | (1 << v);
dp[next_mask][v] = (dp[next_mask][v] + dp[s][u]) % MOD;
}
}
}
}
cout << dp[(1 << n) - 1][n-1];
return 0;
}