#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
#include <iomanip>
#include <fstream>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1<<29;

typedef long long ll;
typedef pair<int,int> pii;
typedef int Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src, int dst, Weight weight) :
    src(src), dst(dst), weight(weight) { }
};
bool operator < (const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
    e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void visit(const Graph &g, int v, vector< vector<int> >& scc,
    stack<int> &S, vector<bool> &inS,
    vector<int> &low, vector<int> &num, int& time) {
  low[v] = num[v] = ++time;
  S.push(v); inS[v] = true;
  FOR(e, g[v]) {
    int w = e->dst;
    if (num[w] == 0) {
      visit(g, w, scc, S, inS, low, num, time);
      low[v] = min(low[v], low[w]);
    } else if (inS[w])
      low[v] = min(low[v], num[w]);
  }
  if (low[v] == num[v]) {
    scc.push_back(vector<int>());
    while (1) {
      int w = S.top(); S.pop(); inS[w] = false;
      scc.back().push_back(w);
      if (v == w) break;
    }
  }
}
void stronglyConnectedComponents(const Graph& g,
    vector< vector<int> >& scc) {
  const int n = g.size();
  vector<int> num(n), low(n);
  stack<int> S;
  vector<bool> inS(n);
  int time = 0;
  REP(u, n) if (num[u] == 0)
    visit(g, u, scc, S, inS, low, num, time);
}
bool visit(const Graph &g, int v, vector<int> &order, vector<int> &color) {
  color[v] = 1;
  FOR(e, g[v]) {
    if (color[e->dst] == 2) continue;
    if (color[e->dst] == 1) return false;
    if (!visit(g, e->dst, order, color)) return false;
  }
  order.push_back(v); color[v] = 2;
  return true;
}
bool topologicalSort(const Graph &g, vector<int> &order) {
  int n = g.size();
  vector<int> color(n);
  REP(u, n) if (!color[u] && !visit(g, u, order, color))
    return false;
  reverse(ALL(order));
  return true;
}

ll dp[1000][2];

int main() {
  int n,m;
  while(cin >> n >> m) {
    Graph g(n);
    REP(i,m) {
      int a, b; cin >> a >> b;
      a--;b--;
      g[a].push_back(Edge(a,b,1));
    }
    vector<vector<int> > scc;
    stronglyConnectedComponents(g, scc);
    vector<int> cmp(n);
    REP(i,scc.size())FOR(jt, scc[i])
      cmp[*jt] = i;
    Graph g2(scc.size());
    map<pii, bool> mp;
    REP(i,n) {
      int a = cmp[i];
      FOR(it,g[i]) {
        int b = cmp[it->dst];
        if (a != b) {
          if (mp.count(pii(a,b)) == 0) {
            mp[pii(a,b)] = 1;
            g2[a].push_back(Edge(a,b,1));
          }
        }
      }
    }
    vector<int> order;
    topologicalSort(g2, order);
    REP(i,n) dp[i][0]=dp[i][1]=1;
    ll res = 1;
    const ll MOD = 1e9+7;
    FOR(it, order) {
      if (g2[*it].size() == 0) {
        (res *= dp[*it][0] + dp[*it][1]) %= MOD;
      }
      FOR(e, g2[*it]) {
        int b = e->dst;
        (dp[b][0] *= dp[*it][0]) %= MOD;
        (dp[b][1] *= dp[*it][0]+dp[*it][1]) %= MOD;
      }
    }
    cout << res << endl;
  }
  
}

Measured memory_bytes: 0