#include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#include<assert.h>
#define loop(i,a,b) for(int i=a;i<b;i++)
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
#define int long long
typedef long long ll;
typedef int Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
//#define mt make_tuple
//typedef tuple<double,int,double> tp;
//typedef vector<tp> vt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
const double PI=acos(-1);
const double EPS=1e-7;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
class SCC{//cmp(0 - kk-1) is scc's return. Same number is group. The number is no relatoin.
public:
  int n;
  vvi G,rG,tG;
  vector<bool>used;
  vi vs,cmp;
  SCC(int size){
    n=size;
    G=rG=vvi(n);
    used=vector<bool>(n);
    cmp=vi(n);
    vs=vi(0);
  }
  void add_edge(int s,int t){
    G[s].pb(t);
    rG[t].pb(s);
  }
  void rdfs(int v,int k){
    used[v]=true;
    cmp[v]=k;
    rep(i,rG[v].size())if(!used[rG[v][i]])rdfs(rG[v][i],k);
  }
  void dfs(int v){
    used[v]=true;
    rep(i,G[v].size())if(!used[G[v][i]])dfs(G[v][i]);
    vs.pb(v);
  }
  int scc(){
    rep(i,n)used[i]=false;
    rep(v,n)if(!used[v])dfs(v);
    rep(i,n)used[i]=false;
    int kk=0;
    for(int i=vs.size()-1;i>=0;i--)if(!used[vs[i]])rdfs(vs[i],kk++);
    return kk;
  }
  vvi make(){
    int N=scc();
    tG=vvi(N);
    rep(i,n)rep(j,G[i].size())if(cmp[i]!=cmp[G[i][j]]){
      tG[cmp[i]].pb(cmp[G[i][j]]);
      //	tG[cmp[G[i][j]]].pb(cmp[i]);
    }
    return tG;
  }
};
class TOPO{//out is tsort's return.
public:
  vvi G;
  vi out;
  vector<bool>V;
  vi indeg;
  int n;
  TOPO(int size){
    n=size;
    G=vvi(n);
    out=vi(0);
    V=vector<bool>(n);
    indeg=vi(n);
  }
  void add_edge(int s,int t){
    G[s].pb(t);
  }
  void bfs(int s){
    queue<int>q;
    q.push(s);
    V[s]=true;
    while(!q.empty()){
      int u=q.front();q.pop();
      out.pb(u);
      rep(i,G[u].size()){
	int v=G[u][i];
	indeg[v]--;
	if(indeg[v]==0&&!V[v]){
	  V[v]=true;
	  q.push(v);
	}
      }
    }
  }
  vi tsort(){
    rep(i,n)indeg[i]=0;
    rep(i,n)rep(j,G[i].size()){
      int v=G[i][j];
      indeg[v]++;
    }
    rep(i,n)if(indeg[i]==0&&!V[i])bfs(i);
    //	rep(i,n)cout<<out[i]<<endl;
    return out;
  }
};
signed main(){
  int n,m;
  cin>>n>>m;
  SCC scc(n);
  rep(i,m){
    int a,b;
    cin>>a>>b;
    a--;b--;
    scc.add_edge(a,b);
  }
  vvi G=scc.make();
  n=G.size();
  vvi rG(n);
  TOPO tp(n);
  rep(i,n)rep(j,G[i].size()){
    tp.add_edge(i,G[i][j]);
    rG[G[i][j]].pb(i);
  }
  vi out=tp.tsort();
  vp dp(n,{1,1});
  ll MOD=1000000007;
  rep(i,n){
    int to=out[i];
    rep(j,rG[out[i]].size()){
      int from=rG[out[i]][j];
      //      cout<<from<<" "<<to<<endl;
      (dp[to].first*=(ll)(dp[from].first+dp[from].second)%MOD)%=MOD;
      (dp[to].second*=(ll)dp[from].second)%=MOD;
    }
    //    cout<<dp[to].first<<" "<<dp[to].second<<" "<<"!"<<endl;
    //    if(rG[to].size()!=0)(dp[to].first+=MOD-dp[to].second)%=MOD;
  }
  ll sum=1;
  rep(i,n)if(G[i].size()==0){
    //    cout<<dp[i].first<<" "<<dp[i].second<<endl;
    (sum*=(dp[i].first+dp[i].second)%MOD)%=MOD;
  }
  cout<<sum<<endl;
}

Measured memory_bytes: 3508