#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <string>
#include <bitset>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

//infの設定
#define INF32 2147483647
#define INF64 9223372036854775807
#define PRIME 1000000007
#define PI 3.141592653589793238
//repマクロ
#define rep(i,m,n) for (int i=(m); (i)<(int)(n); ++(i))
#define rrep(i,m,n) for (int i=(m); (i)>(int)(n); --(i))
//その他
#define eb emplace_back
#define ALL(v) v.begin(), v.end()
typedef long long ll;
typedef pair<long long,long long> Pl;
//#define int long long

//負閉路を含まない重み付きグラフのある点からのGraph_distを返す関数(ダイクストラ法)　↑とセット
int bfs(int n,vector<vector<int>>& g){

    queue<int> que;

    vector<bool> seen(2020,false);
    que.push(n);

    int count=0;
    while(!que.empty()){
        int v=que.front();
        que.pop();
        if(seen[v]) continue;
        seen[v]=true;
        count++;
        for(int ne:g[v]){
            que.push(ne);
        }
    }
    return count;
}


int main(){
    int N,M;
    cin>>N>>M;
    vector<vector<int>> g(2020);

    rep(i,0,M){
        int a,b; cin>>a>>b;
        g[a-1].eb(b-1);
    }
    ll ans=0;
    rep(i,0,N){
        ans+=bfs(i,g);
    }
    cout<<ans<<endl;



    return 0;
}

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <memory>
#include <list>
#include <deque>
#include <queue>
#include <iomanip>
#include <set>
#include <stack>
#include <numeric>
#include <unordered_set>
#include <unordered_map>
#include <string.h>
#include <functional>
#include <sstream>

using namespace std;

#define REP(i,n) for (decltype(n) i = 0; i < n; i++)
#define THE_MOD 1'000'000'007

using ll = long long;
using ivec = vector<int>;
using lvec = vector<long>;
using ipair = pair<int, int>;
using llvec = vector<ll>;
using llpair = pair<ll, ll>;

#define umap unordered_map
#define uset unordered_set

template<typename T> ostream& operator <<(ostream& os, const vector<T> &v) { auto n = v.size(); REP(i,n) os << (i ? " " : "") << v[i]; return os; }
template<typename T> istream& operator >>(istream& is, vector<T> &v) { for(auto &e : v) is >> e; return is; }
template<typename T, typename U> ostream& operator <<(ostream& os, const pair<T, U> &p) { os << p.first << " " << p.second; return os; }
template<typename T, typename U> istream& operator >>(istream& is, pair<T, U> &p) { is >> p.first >> p.second; return is; }

void in() {} template <typename T, typename... Args> void in(T& t, Args& ...args) { cin >> t; in(args...); }
void out() { cout << endl; } template <typename T, typename... Args> void out(const T& t, const Args& ...args) { cout << t; if (sizeof...(args)) cout << " "; out(args...); }

constexpr ll LLINF = numeric_limits<ll>::max();

template<class T> void sort(T& v) {	sort(v.begin(), v.end()); }
template<class T> void rsort(T& v) { sort(v.begin(), v.end(), greater<typename T::value_type>()); }

void YN(bool b) {	cout << (b ? "Yes" : "No") << endl; }

template <typename T = ll, typename U = ll>
vector<T> Dijkstra(const vector<vector<pair<U,T>>>& edges, U start, U numNodes)
{
	using Node = pair<U,T>;
	auto compare = [](Node a, Node b){ return a.second > b.second;};
	priority_queue<Node, vector<Node>, decltype(compare)> q{compare};

	vector<T> costs(numNodes, numeric_limits<T>::max());

	q.emplace(start, 0);
	while (!q.empty()) {
		auto [from, cost] = q.top();
		q.pop();
		if (cost > costs[from]) continue;

		for (const auto& edge : edges[from]) {
			auto to = edge.first;
			auto newCost = cost + edge.second;
			if (newCost < costs[to]) {
				costs[to] = newCost;
				q.emplace(to, newCost);
			}
		}
	}
	return costs;
}

struct Range {
	ll x;
	ll y;
	Range(ll x, ll y) : x(x), y(y)
	{
		if (y > x) swap(x,y);
	}

	struct Iterator {
		using difference_type   = ptrdiff_t;
		using value_type        = ll;
		using pointer           = ll*;
		using reference         = ll&;
		using iterator_category = std::random_access_iterator_tag;
		Iterator() = default;
		Iterator(ll n) : n(n) {}
		ll n;
		bool operator!=(const Iterator&rhs) const { return n != rhs.n; }
		bool operator==(const Iterator&rhs) const { return n == rhs.n; }
		Iterator& operator++() { n++; return *this; }
		Iterator& operator--() { n--; return *this; }
		Iterator& operator+=(ll x) { n+=x; return *this; }
		ll operator*() const { return n; }
		ptrdiff_t operator-(const Iterator&rhs) const { return n - rhs.n; }
	};

	Iterator begin() { return Iterator(x); }
	Iterator end() { return Iterator(y); }
};

ll extgcd(ll a, ll b, ll &x, ll &y)
{
/*
a = pb*q; // p = a / b, q = a % b
ax + by
 = pbx + qx + by
 = b(px + y) + qx
 = bY + qX // Y = px + y, X = x ->  y = Y - px
*/

	if (b == 0) {
		x = 1;
		y = 0;
		return a;
	}
	ll d = extgcd(b, a % b, y, x);
	y -= a / b * x;
	return d;
}

ll run()
{
	ll a,b; double w;in(a,b,w);
	w *= 1000;
	ll m = ceil(w/b);
	ll M = floor(w/a);
	if (M < m) {
		out("UNSATISFIABLE");
		return 0;
	} else {
		out(m,M);
		return 0;
	}
	return 0;
}

int main()
{
	cout << fixed << setprecision(15);
	auto r = run();
	//YN(r);
	//out(r);
	//cout << r << endl;
	return 0;
}
