#include<bits/stdc++.h>
#define int long long
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
struct SCC{
  int V;
  vector<vector<int> > G,rG;
  vector<int> vs,used,cmp;
  SCC(){}
  SCC(int sz):V(sz),G(sz),rG(sz),used(sz),cmp(sz){}
  void add(int from,int to){
    G[from].push_back(to);
    rG[to].push_back(from);
  } 
  void dfs(int v){
    used[v]=1;
    for(int i=0;i<G[v].size();i++)
      if(!used[G[v][i]])dfs(G[v][i]);
    vs.push_back(v);
  }
  void rdfs(int v,int k){
    used[v]=1;
    cmp[v]=k;
    for(int i=0;i<rG[v].size();i++)
      if(!used[rG[v][i]])rdfs(rG[v][i],k);
  }
  int build(){
    fill(used.begin(),used.end(),0);
    vs.clear();
    for(int v=0;v<V;v++)
      if(!used[v])dfs(v);
    fill(used.begin(),used.end(),0);
    int k=0;
    for(int i=vs.size()-1;i>=0;i--)
      if(!used[vs[i]])rdfs(vs[i],k++);
    return k;
  }
  int be(int x){
    return cmp[x];
  }
  bool same(int x,int y){
    return cmp[x]==cmp[y];
  }
};


// 連結成分分解　（連結成分ごとにグラフを再構築、Sはグラフの集合）
struct CC{
  int n;
  vector<vector<int> >G,rG;
  vector<int>used;
  vector<vector<vector<int> > >S;
  CC(int sz):n(sz),G(sz),rG(sz),used(sz){}
  void add(int from,int to){
    G[from].push_back(to);
    rG[to].push_back(from);
  }
  void CC_dfs1(int x,int &cnt,map<int,int>& m){
    m[x]=cnt++;
    used[x]=1;
    for(int i=0;i<G[x].size();i++){
      if(used[G[x][i]])continue;
      CC_dfs1(G[x][i],cnt,m);
    }
    for(int i=0;i<rG[x].size();i++){
      if(used[rG[x][i]])continue;
      CC_dfs1(rG[x][i],cnt,m);
    }
  }
  void CC_dfs2(int x,vector<vector<int> > &v,map<int,int>& m,vector<int> &vis){
    vis[m[x]]=1;
    for(int i=0;i<G[x].size();i++){
      v[m[x]].push_back(m[G[x][i]]);
      if(vis[m[G[x][i]]])continue;
      CC_dfs2(G[x][i],v,m,vis);
    }
    for(int i=0;i<rG[x].size();i++){
      if(vis[m[rG[x][i]]])continue;
      CC_dfs2(rG[x][i],v,m,vis);
    }
  }
  void build(){
    for(int i=0;i<n;i++)used[i]=0;
    for(int i=0;i<n;i++){
      if(used[i])continue;
      int cnt=0;
      map<int,int>M;
      CC_dfs1(i,cnt,M);
      vector<vector<int> >v(cnt);
      vector<int>U(cnt,0);
      CC_dfs2(i,v,M,U);
      S.push_back(v);
    }
  }
};
int mod=1000000007;
int n,m,a[10002],b[10002];
int dp[1002][2];
signed main(){
  set<int>st;
  cin>>n>>m;
  CC C(n);
  r(i,m){
    cin>>b[i]>>a[i];
    b[i]--;a[i]--;
    st.insert(b[i]);
    st.insert(a[i]);
    C.add(b[i],a[i]);
  }
  C.build();
  int ans=1,sum=0;
  for(int i=0;i<C.S.size();i++){
    memset(dp,0,sizeof(dp));
    vector<vector<int> >A=C.S[i];
    int N=A.size();
    SCC S(N);
    r(i,N){
      r(j,A[i].size()){
        S.add(i,A[i][j]);
      }
    }
    S.build();
    set<int>SS;
    int c=0;
    for(int j=N-1;j>=0;j--){  // ここに連結成分無いのDPをかく
      int x=S.vs[j];
      SS.insert(S.cmp[x]);
      //cout<<S.rG[x].size()<<endl;
      if(S.rG[x].size()==0){
        dp[x][0]=dp[x][1]=1;c++;//cout<<"a"<<j<<endl;
      }
      else{
        dp[x][0]=dp[x][1]=1;
        for(int k=0;k<S.rG[x].size();k++){
          int to=S.rG[x][k];
          if(S.same(x,to)){
            //dp[to][0]=dp[x][0];
            //dp[to][1]=dp[x][1];
          }
          else{//cout<<to<<endl;
            dp[x][1]*=dp[to][0]+dp[to][1];
            dp[x][0]*=dp[to][0];
            dp[x][1]%=mod;
            //cout<<dp[to][1]<<' '<<dp[to][0]<<endl;
          }
        }
      } 
      int X=1;
      if(j==0){
        if(c==0){
          ans*=2;
          ans%=mod;
          break;
        }
        r(k,N){
          int K=S.vs[k];
          if(S.same(x,K)){
            X*=dp[K][1];
            X%=mod;
          }
        }
        X++;
        X%=mod;
        ans*=X;
        ans%=mod;
      }
    }
  }
  cout<<ans<<endl;
  return 0;
}
