#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <memory>
#include <cstring>
#include <cassert>
#include <numeric>
#include <sstream>
#include <complex>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
#include <unordered_map>
#include <unordered_set>
using namespace std;

#define REP2(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define REP(i, n) REP2(i, 0, n)
#define ALL(S) (S).begin(), (S).end()

template <typename T, typename E>
ostream &operator<<(std::ostream &os, const std::pair<T, E> &p){
  return os << "(" << p.first << ", " << p.second << ")";
}

typedef long long ll;

class StrongConnectedComponent{
  typedef std::vector<std::vector<int> > Graph; // adjacency list
private:
  size_t V;
  size_t size_;
  std::vector<bool> visit;
  std::vector<int>  scc;
    
  void dfs(int v, std::vector<int> &vs, const Graph &G){
    std::stack <int> to_visit;
    std::vector<int> iters(V, 0);
    to_visit .push(v);
        
    while (!to_visit.empty()){
      int    v = to_visit.top(); to_visit.pop();
      if (iters[v] == 0) visit[v] = true;
      if (iters[v] == (int)G[v].size()){
        vs.push_back(v);
      } else {
        int to = G[v][iters[v]];
        to_visit.push(v);
        iters[v]++;
        if (!visit[to]) to_visit.push(to);
      }
    }
  }
    
  void rbfs(int s, int id, const Graph &G){
    std::queue<int> que;
    que.push(s);
    visit[s] = true;
    scc[s]   = id;
    while (!que.empty()){
      int v = que.front(); que.pop();
      for (auto to : G[v]){
        if (!visit[to]){
          visit[to] = true;
          scc[to]   = id;
          que.push(to);
        }
      }
    }
  }
    
public:
  StrongConnectedComponent(const Graph &G) : V(G.size()), size_(0){
    visit .resize(V, false);
    scc   .resize(V, -1);
    Graph rG(V);
    for (size_t v = 0; v < V; v++)
      for (size_t i = 0; i < G[v].size(); i++)
        rG[G[v][i]].push_back(v);
    std::vector<int> vs;
    for (size_t v = 0; v < V; v++) if (!visit[v]) dfs(v, vs, G);
    assert(vs.size() == V);
    std::reverse(vs.begin(), vs.end());
    std::fill(visit.begin(), visit.end(), false);
    for (size_t v = 0; v < V; v++) if (!visit[vs[v]]) rbfs(vs[v], size_++, rG);
  }
  int operator[](size_t idx) const { return scc[idx]; }
  size_t size() const { return size_; };
};


int main(){
  const ll mod = 1000 * 1000 * 1000 + 7;
  ios::sync_with_stdio(false);

  int N, M;
  while (cin >> N >> M && N + M){
    vector<vector<int> > G(N);
    REP(i, M){
      int s, d;
      cin >> s >> d;
      G[s - 1].push_back(d - 1);
    }

    StrongConnectedComponent scc(G);
    
    ll res = 1;
    
    vector<vector<int> > D(scc.size());
    vector<vector<int> > R(scc.size());
    vector<ll> dp(scc.size());
    
    REP(v, N) REP(i, G[v].size()){
      int w = G[v][i];
      if (scc[v] != scc[w]){
        D[scc[v]].push_back(scc[w]);
        R[scc[w]].push_back(scc[v]);
      }
    }
    
    REP(i, scc.size()){
      sort(ALL(R[i]));
      sort(ALL(D[i]));
      R[i].erase(unique(ALL(R[i])), R[i].end());
      D[i].erase(unique(ALL(D[i])), D[i].end());
      
      dp[i] = 1;
      REP(j, R[i].size()){
        dp[i] *= dp[R[i][j]];
        dp[i] %= mod;
      }
      dp[i]++;
      if (D[i].size() == 0){
        res *= dp[i];
        res %= mod;
      }
    }
    cout << res << endl;
  }
  return 0;
}

Measured memory_bytes: 1396