#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define TRACE(x) cerr << #x << " = " << x << endl
#define REP(i, n) for (int i=0; i<n; i++)
#define FOR(i, a, b) for (int i=(a); i<(b); i++)
#define _ << " " <<
typedef long long ll;
typedef pair<int, int> P;
#define X first
#define Y second
const int MAX = 15;
const int MOD = 1e9 + 7;
int add(int a, int b)
{
a += b;
if (a >= MOD)
a -= MOD;
return a;
}
int sub(int a, int b)
{
a -= b;
if (a < 0)
a += MOD;
return a;
}
int mul(int a, int b)
{
return (int) (((ll) a * b) % MOD);
}
int pot2[MAX*MAX];
int dp[1<<MAX];
int e[MAX];
int sajz[MAX][1<<MAX];
int n, m;
inline int gb(int x, int pos) {
return x>>pos & 1;
}
int rek(int msk) {
if (dp[msk] != -1) return dp[msk];
int ret = 1;
for (int pod=(msk-1) & msk; pod; pod = (pod - 1) & msk) {
int veci = pod, manji = msk ^ pod;
if (gb(veci, 0) != gb(veci, 1))
continue;
int tmp = 1;
REP(i, n) {
if (gb(veci, i))
tmp = mul(tmp, sub(pot2[sajz[i][manji]], 1));
else if (gb(manji, i))
tmp = mul(tmp, pot2[sajz[i][veci]]);
}
tmp = mul(tmp, rek(veci));
ret = add(ret, tmp);
}
return dp[msk] = ret;
}
int main()
{
pot2[0] = 1;
FOR(i, 1, MAX*MAX)
pot2[i] = mul(2, pot2[i-1]);
scanf("%d%d", &n, &m);
REP(i, m) {
int a, b;
scanf("%d%d", &a, &b); a--; b--;
e[a] |= 1<<b;
}
REP(i, n)
REP(j, 1<<n)
sajz[i][j] = __builtin_popcount(e[i] & j);
memset(dp, -1, sizeof dp);
printf("%d\n", sub(pot2[m], rek((1<<n)-1)));
return 0;
}