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

typedef long long ll;
const ll MOD = 1000000007;

int N, M;
vector<vector<int>> G, rG;
vector<bool> vis;
vector<int> vs;
vector<int> S;
vector<vector<int>> s;

void dfs(int v){
    vis[v] = true;
    for(int i=0; i<G[v].size(); i++)
        if(!vis[G[v][i]]) dfs(G[v][i]);
    vs.push_back(v);
}

void rdfs(int v, int k){
    vis[v] = 1;
    S[v] = k; s[k].push_back(v);
    for(int i=0; i<rG[v].size(); i++)
        if(!vis[rG[v][i]]) rdfs(rG[v][i],k);
}

void scc(){
    for(int i=0; i<N; i++)if(!vis[i]) dfs(i);
    for(int i=0; i<N; i++)
        vis[i] = false;
    
    reverse(vs.begin(), vs.end());
    
    s.clear();
    for(int i=0; i<N; i++) if(!vis[vs[i]]){
        s.push_back(vector<int>());
        rdfs(vs[i],s.size()-1);
    }
    vector<int> rs(N);
    N = s.size();
    for(int i=0; i<N; i++)
        for(int v: s[i])
            rs[v] = i;
    
    
    vector<vector<int>> tG(N);
    vector<vector<int>> trG(N);
    for(int i=0; i<N; i++){
        vector<bool> done(N);
        for(int u: s[i]){
            for(int v: G[u]) if(rs[v]!=i && !done[rs[v]]){
                done[rs[v]] = true;
                tG[i].push_back(rs[v]);
            }
            for(int v: rG[u]) if(rs[v]!=i && !done[rs[v]]){
                done[rs[v]] = true;
                trG[i].push_back(rs[v]);
            }
        }
    }
    G = tG;
    rG = trG;
}

ll tree(int u){
    if(rG[u].size() == 0) //leaf
        return 2;
    
    ll res = 1;
    for(int v: rG[u])
        res = (res * tree(v)) % MOD;
    return res + 1;
}

int main(){
    cin >> N >> M;
    G.resize(N); rG.resize(N);
    vis.resize(N); S.resize(N);

    for(int i=0; i<M; i++){
        int s, d; cin >> s >> d; s--; d--;
        G[s].push_back(d);
        rG[d].push_back(s);
    }
    
    scc();
    
    ll ans = 1;
    for(int i=0; i<N; i++){
        if(G[i].size() == 0) //root
            ans = (ans * tree(i)) % MOD;
    }
    cout << ans << endl;
    
    return 0;
}