#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
const ld eps = 1e-9;
const ll MOD = 1000000007;
const int INF = 1000000000;
const ll LINF = 1ll<<50;
template<typename T>
void printv(const vector<T>& s) {
  for(int i=0;i<(int)(s.size());++i) {
    cout << s[i];
    if(i == (int)(s.size())-1) cout << endl;
    else cout << " ";
  }
}
template<typename T1, typename T2>
ostream& operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
template<typename T>
struct edge {
    int src, to;
    T cost;
};
template<typename T>
using Graph = vector<vector<edge<T>>>;
template<typename T>
struct SCC {
    int sz, cnt, num;
    vi post, comp;
    vector<pair<int, int>> vp;
    vector<bool> sel;
    Graph<T> revg;
    SCC(int sz): sz(sz) {
        cnt = 0;
        num = 0;
        post.resize(sz, -1);
        comp.resize(sz, -1);
        sel.resize(sz, false);
        revg.resize(sz);
    }
    void build(const Graph<T> &g) {
        for(int i=0;i<sz;++i) {
            if(sel[i]) continue;
            sel[i] = true;
            dfs1(g, i);
        }
        rev(g, revg);
        for(int i=0;i<sz;++i) {
            vp.emplace_back(make_pair(post[i], i));
        }
        sort(vp.begin(), vp.end());
        reverse(vp.begin(), vp.end());
        sel.clear();
        sel.resize(sz, false);
        for(int i=0;i<sz;++i) {
            if(sel[vp[i].second]) continue;
            sel[vp[i].second] = true;
            comp[vp[i].second] = num;
            dfs2(revg, vp[i].second);
            num++;
        }
    }
    vi get_comp() {return comp;}
    Graph<T> build_graph(const Graph<T> &g) {
        build(g);
        vector<set<int>> s(sz);
        Graph<T> res(num);
        for(int i=0;i<sz;++i) {
            for(int j=0;j<(int)(g[i].size());++j) {
                s[comp[i]].insert(comp[g[i][j].to]);
            }
        }
        for(int i=0;i<sz;++i) {
            for(auto j: s[i]) {
                if(i != j) res[i].push_back(edge<int>({i, j, 1}));
            }
        }
        return res;
    }
    void dfs1(const Graph<T> &g, int now) {
        for(int i=0;i<(int)(g[now].size());++i) {
            int nxt = g[now][i].to;
            if(sel[nxt]) continue;
            sel[nxt] = true;
            dfs1(g, nxt);
        }
        post[now] = cnt;
        cnt++;
    }
    void rev(const Graph<T> &g, Graph<T> &revg) {
        for(int i=0;i<sz;++i) {
            for(int j=0;j<(int)(g[i].size());++j) {
                revg[g[i][j].to].push_back({
                        g[i][j].to, g[i][j].src, g[i][j].cost});
            }
        }
    }
    void dfs2(const Graph<T> &revg, int now) {
        for(int i=0;i<(int)(revg[now].size());++i) {
            int nxt = revg[now][i].to;
            if(sel[nxt]) continue;
            sel[nxt] = true;
            comp[nxt] = num;
            dfs2(revg, nxt);
        }
    }
};
void topological_sort(const vector<vector<int>>& G, vi& ord)
{
    int n = G.size();
    vector<int> num(n, 0);
    ord.resize(n, 0);
    for (int i = 0; i < n; ++i) {
        for (auto u : G[i]) {
            ++num[u];
        }
    }
    stack<int> st;
    for(int i = 0; i < n; ++i) {
        if (num[i] == 0) {
            st.push(i);
        }
    }
    for (int k = 0; !st.empty(); ++k) {
        int i = st.top(); st.pop();
        ord[k] = i;
        for (auto u : G[i]) {
            if (--num[u] == 0) {
                st.push(u);
            }
        }
    }
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  int n, m; cin >> n >> m;
  vi s(m), d(m);
  for(int i=0;i<m;++i) {
    cin >> s[i] >> d[i];
    s[i]--;
    d[i]--;
  }
  Graph<int> g(n);
  for(int i=0;i<m;++i) {
    g[s[i]].push_back({s[i], d[i], 1});
  }
  SCC<int> scc(n);
  auto g2 = scc.build_graph(g);
  vvi g3(scc.num);
  for(int i=0;i<scc.num;++i) {
    for(int j=0;j<(int)(g2[i].size());++j) {
      g3[i].push_back(g2[i][j].to);
    }
  }
  vi ord;
  topological_sort(g3, ord);
  int sz = (int)(ord.size());
  vvll dp(n, vll(2, 1));
  ll ans = 1;
  for(int i=0;i<sz;++i) {
    int now = ord[i];
    if((int)(g3[now].size()) == 0) {
      ans *= (dp[now][0] + dp[now][1]) % MOD;
      ans %= MOD;
      continue;
    }
    int nxt = g3[now][0];
    dp[nxt][0] *= dp[now][0];
    dp[nxt][0] %= MOD;
    dp[nxt][1] *= (dp[now][0] + dp[now][1]) % MOD;
    dp[nxt][1] %= MOD;
  }
  cout << ans << endl;
}



Measured memory_bytes: 3512