#include <iostream>
#include <sstream>
#include <cstdlib>

using namespace std;

#define rep(i, n) for(int i = 0; i < n; i++)

stringstream output;

/** Actually outputs the result and end the program.*/
inline void eOP();

#include <unordered_map>
#include <unordered_set>

#ifndef MOD_H_INCLUDED
#define MOD_H_INCLUDED

#ifndef ALGORITHM_H_INCLUDED
#define ALGORITHM_H_INCLUDED

#include <algorithm>

using namespace std;

#define gcf gcd
#define gcd euclideanAlgorithm

template <typename N>
inline N euclideanAlgorithm(N a, N b);

template <typename N>
inline N euclideanAlgorithm(N a, N b, N& x, N& y);

template <typename N>
inline N lcm(N a, N b);

template <typename N>
inline N euclideanAlgorithm(N a, N b)
{
	while (a != N(0))
	{
        b %= a;
        swap(a, b);
	}
	return b;
}

template <typename N>
inline N euclideanAlgorithm(N a, N b, N& x, N& y)
{
    // Do euclidean algorithm on
    // (a, b), (1, 0), (0, 1)

    N l[3] = {a, 1, 0};
    N r[3] = {b, 0, 1};

    while (l[0] != 0)
    {
    	N n = r[0] / l[0];
    	for (int i = 0; i < 3; ++i)
		{
            r[i] -= l[i] * n;
            swap(l[i], r[i]);
		}
    }

    x = r[1];
    y = r[2];
    return r[0];
}

template <typename N>
inline N lcm(N a, N b)
{
    return a / gcd(a, b) * b;
}

#endif // ALGORITHM_H_INCLUDED
#ifndef RELOP_H_INCLUDED
#define RELOP_H_INCLUDED

/*
Just write

inline R operator -(K a);
inline bool operator <(K a, S b);
inline bool operator ==(K a, S b);
inline R operator ~(K a);
inline R& operator +=(K& a, S b);
inline R& operator *=(K& a, S b);
inline R& operator /=(K& a, S b);
inline R& operator &=(K& a, S b);
inline R& operator |=(K& a, S b);
inline R& operator <<=(K& a, S b);
inline ostream& operator<<(ostream& os, const K& a);
inline istream& operator>>(istream& is, K& a);

*/
// arithmetic operators
template <typename T>
inline T operator +(const T& a, const T& b);
template <typename T>
inline T operator -(const T& a, const T& b);
template <typename T>
inline T operator +(const T& a);
template <typename T>
inline T operator *(const T& a, const T& b);
template <typename T>
inline T operator /(const T& a, const T& b);
template <typename T>
inline T operator %(const T& a, const T& b);
template <typename T>
inline T& operator ++(T& a);
template <typename T>
inline T operator ++(T& a, int);
template <typename T>
inline T& operator --(T& a);
template <typename T>
inline T operator --(T& a, int);

// comparison operators
template <typename T>
inline bool operator!=(const T& a,const T& b);
template <typename T>
inline bool operator>(const T& a,const T& b);
template <typename T>
inline bool operator<=(const T& a,const T& b);
template <typename T>
inline bool operator>=(const T& a,const T& b);

// bitwise operators
template <typename T>
inline T operator &(const T& a, const T& b);
template <typename T>
inline T operator |(const T& a, const T& b);
template <typename T>
inline T operator ^(const T& a, const T& b);
template <typename T>
inline T operator <<(const T& a, const T& b);
template <typename T>
inline T operator >>(const T& a, const T& b);

// compound assignment operators
template <typename T>
inline T& operator -=(T& a, const T& b);
template <typename T>
inline T& operator %=(T& a, const T& b);
template <typename T>
inline T& operator ^=(T& a, const T& b);
template <typename T>
inline T& operator >>=(T& a, const T& b);

// arithmetic operators
template <typename T>
inline T operator +(const T& a, const T& b)
{
	T result = a;
	return result += b;
}

template <typename T>
inline T operator -(const T& a, const T& b)
{
	T result = a;
	return result -= b;
}

template <typename T>
inline T operator +(const T& a)
{
	return a;
}

template <typename T>
inline T operator *(const T& a, const T& b)
{
	T result = a;
	return result *= b;
}

template <typename T>
inline T operator /(const T& a, const T& b)
{
	T result = a;
	return result /= b;
}

template <typename T>
inline T operator %(const T& a, const T& b)
{
	T result = a;
	return result %= b;
}

template <typename T>
inline T& operator ++(T& a)
{
	return a += 1;
}

template <typename T>
inline T operator ++(T& a, int)
{
	T result = a;
	++a;
	return result;
}

template <typename T>
inline T& operator --(T& a)
{
	return a -= 1;
}

template <typename T>
inline T operator --(T& a, int)
{
	T result = a;
	--a;
	return result;
}

// comparison operators
template <typename T>
inline bool operator!=(const T& a,const T& b)
{
	return !(a == b);
}

template <typename T>
inline bool operator>(const T& a,const T& b)
{
	return b < a;
}

template <typename T>
inline bool operator<=(const T& a,const T& b)
{
	return !(a > b);
}

template <typename T>
inline bool operator>=(const T& a,const T& b)
{
	return !(a < b);
}

// bitwise operators
template <typename T>
inline T operator &(const T& a, const T& b)
{
	T result = a;
	return result &= b;
}

template <typename T>
inline T operator |(const T& a, const T& b)
{
	T result = a;
	return result |= b;
}

template <typename T>
inline T operator ^(const T& a, const T& b)
{
	T result = a;
	return result ^= b;
}

template <typename T>
inline T operator <<(const T& a, const T& b)
{
	T result = a;
	return result <<= b;
}

template <typename T>
inline T operator >>(const T& a, const T& b)
{
	T result = a;
	return result >>= b;
}

// compound assignment operators
template <typename T>
inline T& operator -=(T& a, const T& b)
{
	return a += -b;
}

template <typename T>
inline T& operator %=(T& a, const T& b)
{
	return a -= a / b * b;
}

template <typename T>
inline T& operator ^=(T& a, const T& b)
{
	return a = ~(a & b) & (a | b);
}

template <typename T>
inline T& operator >>=(T& a, const T& b)
{
	return a <<= -b;
}

#endif // RELOP_H_INCLUDED

#ifndef MOD
#define MOD 1000000007
#endif // MOD

class Remainder
{
public:
    long long value;
    Remainder(long long = 0);
};

inline Remainder operator + (const Remainder & l, const Remainder & r);

inline Remainder operator - (const Remainder & l, const Remainder & r);

inline Remainder operator * (const Remainder & l, const Remainder & r);

inline Remainder operator / (const Remainder & l, const Remainder & r);

inline Remainder & operator++(Remainder & r);

inline Remainder operator++(Remainder & r, int);

inline Remainder & operator--(Remainder & r);

inline Remainder operator--(Remainder & r, int);

inline Remainder operator + (const Remainder & r);

inline Remainder operator - (const Remainder & r);

inline Remainder & operator += (Remainder & l, const Remainder & r);

inline Remainder & operator -= (Remainder & l, const Remainder & r);

inline Remainder & operator *= (Remainder & l, const Remainder & r);

inline Remainder & operator /= (Remainder & l, const Remainder & r);

inline Remainder operator ~ (const Remainder & l);

inline bool operator == (const Remainder & l, const Remainder & r);

inline bool operator < (const Remainder & l, const Remainder & r);

// OUTPUT << A
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & os, const Remainder & o);

// INPUT >> A
template <typename charT, typename traits>
inline std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & is, Remainder & o);

inline Remainder::Remainder(long long r)
{
    value = r;
	value %= MOD;
	if (value < 0)
	{
		value += MOD;
	}
}

inline Remainder operator + (const Remainder & l, const Remainder & r) // A + B
{
   Remainder oResult(l.value + r.value);
   return oResult ;
}

inline Remainder operator - (const Remainder & l, const Remainder & r) // A - B
{
   Remainder oResult(l.value - r.value);
   return oResult ;
}

inline Remainder operator * (const Remainder & l, const Remainder & r) // A * B
{
   Remainder oResult(l.value * r.value);
   return oResult ;
}

inline Remainder operator / (const Remainder & l, const Remainder & r) // A / B
{
	long long x, y;
	gcd(r.value, static_cast<long long>(MOD), x, y);
   Remainder oResult(l * x);
   return oResult ;
}

inline Remainder & operator++(Remainder & r) // ++A
{
   r += 1;
   return r ;
}

inline Remainder operator++(Remainder & r, int) // A++
{
   Remainder oCopy(r);
   r += 1;
   return oCopy ;
}

inline Remainder & operator--(Remainder & r) // --A
{
   r -= 1;
   return r ;
}

inline Remainder operator--(Remainder & r, int) // A--
{
   Remainder oCopy(r);
   r -= 1;
   return oCopy ;
}

inline Remainder operator + (const Remainder & r) // +A
{
   return r ;
}

inline Remainder operator - (const Remainder & r) // -A
{
	Remainder temp(-(r.value));
   return temp;
}

inline Remainder & operator += (Remainder & l, const Remainder & r) // A += B
{
   l = l + r;

   return l ;
}

inline Remainder & operator -= (Remainder & l, const Remainder & r) // A -= B
{
   l = l - r;

   return l ;
}

inline Remainder & operator *= (Remainder & l, const Remainder & r) // A *= B
{
   l = l * r;

   return l ;
}

inline Remainder & operator /= (Remainder & l, const Remainder & r) // A /= B
{
   l = l / r;

   return l ;
}

inline Remainder operator ~ (const Remainder & l) // ~A
{
   Remainder oResult(-l);
   return oResult ;
}

inline bool operator == (const Remainder & l, const Remainder & r) // A == B
{
   return l.value == r.value ;
}

inline bool operator < (const Remainder & l, const Remainder & r) // A < B
{
   return l.value < r.value ;
}

// OUTPUT << A
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & os, const Remainder & o)
{
   os << o.value;
   return os ;
}

// INPUT >> A
template <typename charT, typename traits>
inline std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & is, Remainder & o)
{
   is >> o.value;
   o = Remainder(o);
   return is ;
}

#endif // MOD_H_INCLUDED

#include <vector>
#include <cstdio>

int main()
{
	int n;
	scanf("%d", &n);

	int* s = new int[n];
	unordered_map<int,int> f;
	unordered_map<int,vector<int>> b;
	rep (i, n)
	{
		int from, to;
		scanf("%d%d", &from, &to);
		s[i] = from;
		f[from] = to;
		b[to].push_back(from);
	}

	Remainder result = 1;

    unordered_set<int> considered;
    rep (i, n)
    {
    	int start = s[i];
        int spot = s[i];
        if (considered.count(spot))
		{
            continue;
		}

		unordered_set<int> visited;
		bool loop = false;
        while (f.find(spot) != f.end())
		{
			visited.insert(spot);
            spot = f[spot];
            if (visited.count(spot) || considered.count(spot))
			{
				loop = true;
                break;
			}
		}

		if (considered.count(spot))
		{
			continue;
		}

		if (loop)
		{
			spot = start;
			unordered_set<int> visited;
			while (f.find(spot) != f.end())
			{
				visited.insert(spot);
				spot = f[spot];
				if (visited.count(spot))
				{
					break;
				}
			}

			if (spot != f[spot])
			{
                result *= 2;
			}

		}

		vector<int> togo;
		togo.push_back(spot);

		int spots = 0;

		int index = 0;

		while (index != togo.size())
		{
			++spots;
			int spot = togo[index];
			++index;
            considered.insert(spot);

            int bindex = 0;
            while (bindex != b[spot].size())
			{
				int to = b[spot][bindex];
				if (!considered.count(to))
                {
                	togo.push_back(b[spot][bindex]);
                }
                ++bindex;
			}
		}

		if (!loop)
		{
			result *= spots;
		}
    }

	cout << result;

	eOP();
}

inline void eOP()
{
	cout << output.str();
	output.str(string());
	exit(0);
}


#include <iostream>
#include <sstream>
#include <cstdlib>

using namespace std;

#define rep(i, n) for(int i = 0; i < n; i++)

stringstream output;

/** Actually outputs the result and end the program.*/
inline void eOP();

#include <unordered_map>
#include <unordered_set>

#ifndef MOD_H_INCLUDED
#define MOD_H_INCLUDED

#ifndef ALGORITHM_H_INCLUDED
#define ALGORITHM_H_INCLUDED

#include <algorithm>

using namespace std;

#define gcf gcd
#define gcd euclideanAlgorithm

template <typename N>
inline N euclideanAlgorithm(N a, N b);

template <typename N>
inline N euclideanAlgorithm(N a, N b, N& x, N& y);

template <typename N>
inline N lcm(N a, N b);

template <typename N>
inline N euclideanAlgorithm(N a, N b)
{
	while (a != N(0))
	{
        b %= a;
        swap(a, b);
	}
	return b;
}

template <typename N>
inline N euclideanAlgorithm(N a, N b, N& x, N& y)
{
    // Do euclidean algorithm on
    // (a, b), (1, 0), (0, 1)

    N l[3] = {a, 1, 0};
    N r[3] = {b, 0, 1};

    while (l[0] != 0)
    {
    	N n = r[0] / l[0];
    	for (int i = 0; i < 3; ++i)
		{
            r[i] -= l[i] * n;
            swap(l[i], r[i]);
		}
    }

    x = r[1];
    y = r[2];
    return r[0];
}

template <typename N>
inline N lcm(N a, N b)
{
    return a / gcd(a, b) * b;
}

#endif // ALGORITHM_H_INCLUDED
#ifndef RELOP_H_INCLUDED
#define RELOP_H_INCLUDED

/*
Just write

inline R operator -(K a);
inline bool operator <(K a, S b);
inline bool operator ==(K a, S b);
inline R operator ~(K a);
inline R& operator +=(K& a, S b);
inline R& operator *=(K& a, S b);
inline R& operator /=(K& a, S b);
inline R& operator &=(K& a, S b);
inline R& operator |=(K& a, S b);
inline R& operator <<=(K& a, S b);
inline ostream& operator<<(ostream& os, const K& a);
inline istream& operator>>(istream& is, K& a);

*/
// arithmetic operators
template <typename T>
inline T operator +(const T& a, const T& b);
template <typename T>
inline T operator -(const T& a, const T& b);
template <typename T>
inline T operator +(const T& a);
template <typename T>
inline T operator *(const T& a, const T& b);
template <typename T>
inline T operator /(const T& a, const T& b);
template <typename T>
inline T operator %(const T& a, const T& b);
template <typename T>
inline T& operator ++(T& a);
template <typename T>
inline T operator ++(T& a, int);
template <typename T>
inline T& operator --(T& a);
template <typename T>
inline T operator --(T& a, int);

// comparison operators
template <typename T>
inline bool operator!=(const T& a,const T& b);
template <typename T>
inline bool operator>(const T& a,const T& b);
template <typename T>
inline bool operator<=(const T& a,const T& b);
template <typename T>
inline bool operator>=(const T& a,const T& b);

// bitwise operators
template <typename T>
inline T operator &(const T& a, const T& b);
template <typename T>
inline T operator |(const T& a, const T& b);
template <typename T>
inline T operator ^(const T& a, const T& b);
template <typename T>
inline T operator <<(const T& a, const T& b);
template <typename T>
inline T operator >>(const T& a, const T& b);

// compound assignment operators
template <typename T>
inline T& operator -=(T& a, const T& b);
template <typename T>
inline T& operator %=(T& a, const T& b);
template <typename T>
inline T& operator ^=(T& a, const T& b);
template <typename T>
inline T& operator >>=(T& a, const T& b);

// arithmetic operators
template <typename T>
inline T operator +(const T& a, const T& b)
{
	T result = a;
	return result += b;
}

template <typename T>
inline T operator -(const T& a, const T& b)
{
	T result = a;
	return result -= b;
}

template <typename T>
inline T operator +(const T& a)
{
	return a;
}

template <typename T>
inline T operator *(const T& a, const T& b)
{
	T result = a;
	return result *= b;
}

template <typename T>
inline T operator /(const T& a, const T& b)
{
	T result = a;
	return result /= b;
}

template <typename T>
inline T operator %(const T& a, const T& b)
{
	T result = a;
	return result %= b;
}

template <typename T>
inline T& operator ++(T& a)
{
	return a += 1;
}

template <typename T>
inline T operator ++(T& a, int)
{
	T result = a;
	++a;
	return result;
}

template <typename T>
inline T& operator --(T& a)
{
	return a -= 1;
}

template <typename T>
inline T operator --(T& a, int)
{
	T result = a;
	--a;
	return result;
}

// comparison operators
template <typename T>
inline bool operator!=(const T& a,const T& b)
{
	return !(a == b);
}

template <typename T>
inline bool operator>(const T& a,const T& b)
{
	return b < a;
}

template <typename T>
inline bool operator<=(const T& a,const T& b)
{
	return !(a > b);
}

template <typename T>
inline bool operator>=(const T& a,const T& b)
{
	return !(a < b);
}

// bitwise operators
template <typename T>
inline T operator &(const T& a, const T& b)
{
	T result = a;
	return result &= b;
}

template <typename T>
inline T operator |(const T& a, const T& b)
{
	T result = a;
	return result |= b;
}

template <typename T>
inline T operator ^(const T& a, const T& b)
{
	T result = a;
	return result ^= b;
}

template <typename T>
inline T operator <<(const T& a, const T& b)
{
	T result = a;
	return result <<= b;
}

template <typename T>
inline T operator >>(const T& a, const T& b)
{
	T result = a;
	return result >>= b;
}

// compound assignment operators
template <typename T>
inline T& operator -=(T& a, const T& b)
{
	return a += -b;
}

template <typename T>
inline T& operator %=(T& a, const T& b)
{
	return a -= a / b * b;
}

template <typename T>
inline T& operator ^=(T& a, const T& b)
{
	return a = ~(a & b) & (a | b);
}

template <typename T>
inline T& operator >>=(T& a, const T& b)
{
	return a <<= -b;
}

#endif // RELOP_H_INCLUDED

#ifndef MOD
#define MOD 1000000007
#endif // MOD

class Remainder
{
public:
    long long value;
    Remainder(long long = 0);
};

inline Remainder operator + (const Remainder & l, const Remainder & r);

inline Remainder operator - (const Remainder & l, const Remainder & r);

inline Remainder operator * (const Remainder & l, const Remainder & r);

inline Remainder operator / (const Remainder & l, const Remainder & r);

inline Remainder & operator++(Remainder & r);

inline Remainder operator++(Remainder & r, int);

inline Remainder & operator--(Remainder & r);

inline Remainder operator--(Remainder & r, int);

inline Remainder operator + (const Remainder & r);

inline Remainder operator - (const Remainder & r);

inline Remainder & operator += (Remainder & l, const Remainder & r);

inline Remainder & operator -= (Remainder & l, const Remainder & r);

inline Remainder & operator *= (Remainder & l, const Remainder & r);

inline Remainder & operator /= (Remainder & l, const Remainder & r);

inline Remainder operator ~ (const Remainder & l);

inline bool operator == (const Remainder & l, const Remainder & r);

inline bool operator < (const Remainder & l, const Remainder & r);

// OUTPUT << A
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & os, const Remainder & o);

// INPUT >> A
template <typename charT, typename traits>
inline std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & is, Remainder & o);

inline Remainder::Remainder(long long r)
{
    value = r;
	value %= MOD;
	if (value < 0)
	{
		value += MOD;
	}
}

inline Remainder operator + (const Remainder & l, const Remainder & r) // A + B
{
   Remainder oResult(l.value + r.value);
   return oResult ;
}

inline Remainder operator - (const Remainder & l, const Remainder & r) // A - B
{
   Remainder oResult(l.value - r.value);
   return oResult ;
}

inline Remainder operator * (const Remainder & l, const Remainder & r) // A * B
{
   Remainder oResult(l.value * r.value);
   return oResult ;
}

inline Remainder operator / (const Remainder & l, const Remainder & r) // A / B
{
	long long x, y;
	gcd(r.value, static_cast<long long>(MOD), x, y);
   Remainder oResult(l * x);
   return oResult ;
}

inline Remainder & operator++(Remainder & r) // ++A
{
   r += 1;
   return r ;
}

inline Remainder operator++(Remainder & r, int) // A++
{
   Remainder oCopy(r);
   r += 1;
   return oCopy ;
}

inline Remainder & operator--(Remainder & r) // --A
{
   r -= 1;
   return r ;
}

inline Remainder operator--(Remainder & r, int) // A--
{
   Remainder oCopy(r);
   r -= 1;
   return oCopy ;
}

inline Remainder operator + (const Remainder & r) // +A
{
   return r ;
}

inline Remainder operator - (const Remainder & r) // -A
{
	Remainder temp(-(r.value));
   return temp;
}

inline Remainder & operator += (Remainder & l, const Remainder & r) // A += B
{
   l = l + r;

   return l ;
}

inline Remainder & operator -= (Remainder & l, const Remainder & r) // A -= B
{
   l = l - r;

   return l ;
}

inline Remainder & operator *= (Remainder & l, const Remainder & r) // A *= B
{
   l = l * r;

   return l ;
}

inline Remainder & operator /= (Remainder & l, const Remainder & r) // A /= B
{
   l = l / r;

   return l ;
}

inline Remainder operator ~ (const Remainder & l) // ~A
{
   Remainder oResult(-l);
   return oResult ;
}

inline bool operator == (const Remainder & l, const Remainder & r) // A == B
{
   return l.value == r.value ;
}

inline bool operator < (const Remainder & l, const Remainder & r) // A < B
{
   return l.value < r.value ;
}

// OUTPUT << A
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & os, const Remainder & o)
{
   os << o.value;
   return os ;
}

// INPUT >> A
template <typename charT, typename traits>
inline std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & is, Remainder & o)
{
   is >> o.value;
   o = Remainder(o);
   return is ;
}

#endif // MOD_H_INCLUDED

#include <queue>

int main()
{
	int n;
	cin >> n;

	int* s = new int[n];
	unordered_map<int,int> f;
	unordered_map<int,queue<int>> b;
	rep (i, n)
	{
		int from, to;
		cin >> from >> to;
		s[i] = from;
		f[from] = to;
		b[to].push(from);
	}

	Remainder result = 1;

    unordered_set<int> considered;
    rep (i, n)
    {
        int spot = s[i];
        if (considered.count(spot))
		{
            continue;
		}

        while (f.find(spot) != f.end())
		{
            spot = f[spot];
            if (spot == s[i])
			{
                break;
			}
		}

		if (spot == s[i])
		{
            if (spot != f[spot])
			{
                result *= 2;
			}

			while (f.find(spot) != f.end())
			{
				spot = f[spot];
				considered.insert(spot);
				if (spot == s[i])
				{
					break;
				}
			}

            continue;
		}

		queue<int> togo;
		togo.push(spot);

		int spots = 0;
		bool loop = false;

		while (!togo.empty())
		{
			++spots;
			int spot = togo.front();
			togo.pop();
            considered.insert(spot);

            while (!b[spot].empty())
			{
                togo.push(b[spot].front());
                b[spot].pop();
			}
		}

		result *= spots;
    }

	cout << result;

	eOP();
}

inline void eOP()
{
	cout << output.str();
	output.str(string());
	exit(0);
}


#include <iostream>
#include <sstream>
#include <cstdlib>

using namespace std;

#define rep(i, n) for(int i = 0; i < n; i++)

stringstream output;

/** Actually outputs the result and end the program.*/
inline void eOP();

#include <unordered_map>
#include <unordered_set>

#ifndef MOD_H_INCLUDED
#define MOD_H_INCLUDED

#ifndef ALGORITHM_H_INCLUDED
#define ALGORITHM_H_INCLUDED

#include <algorithm>

using namespace std;

#define gcf gcd
#define gcd euclideanAlgorithm

template <typename N>
inline N euclideanAlgorithm(N a, N b);

template <typename N>
inline N euclideanAlgorithm(N a, N b, N& x, N& y);

template <typename N>
inline N lcm(N a, N b);

template <typename N>
inline N euclideanAlgorithm(N a, N b)
{
	while (a != N(0))
	{
        b %= a;
        swap(a, b);
	}
	return b;
}

template <typename N>
inline N euclideanAlgorithm(N a, N b, N& x, N& y)
{
    // Do euclidean algorithm on
    // (a, b), (1, 0), (0, 1)

    N l[3] = {a, 1, 0};
    N r[3] = {b, 0, 1};

    while (l[0] != 0)
    {
    	N n = r[0] / l[0];
    	for (int i = 0; i < 3; ++i)
		{
            r[i] -= l[i] * n;
            swap(l[i], r[i]);
		}
    }

    x = r[1];
    y = r[2];
    return r[0];
}

template <typename N>
inline N lcm(N a, N b)
{
    return a / gcd(a, b) * b;
}

#endif // ALGORITHM_H_INCLUDED
#ifndef RELOP_H_INCLUDED
#define RELOP_H_INCLUDED

/*
Just write

inline R operator -(K a);
inline bool operator <(K a, S b);
inline bool operator ==(K a, S b);
inline R operator ~(K a);
inline R& operator +=(K& a, S b);
inline R& operator *=(K& a, S b);
inline R& operator /=(K& a, S b);
inline R& operator &=(K& a, S b);
inline R& operator |=(K& a, S b);
inline R& operator <<=(K& a, S b);
inline ostream& operator<<(ostream& os, const K& a);
inline istream& operator>>(istream& is, K& a);

*/
// arithmetic operators
template <typename T>
inline T operator +(const T& a, const T& b);
template <typename T>
inline T operator -(const T& a, const T& b);
template <typename T>
inline T operator +(const T& a);
template <typename T>
inline T operator *(const T& a, const T& b);
template <typename T>
inline T operator /(const T& a, const T& b);
template <typename T>
inline T operator %(const T& a, const T& b);
template <typename T>
inline T& operator ++(T& a);
template <typename T>
inline T operator ++(T& a, int);
template <typename T>
inline T& operator --(T& a);
template <typename T>
inline T operator --(T& a, int);

// comparison operators
template <typename T>
inline bool operator!=(const T& a,const T& b);
template <typename T>
inline bool operator>(const T& a,const T& b);
template <typename T>
inline bool operator<=(const T& a,const T& b);
template <typename T>
inline bool operator>=(const T& a,const T& b);

// bitwise operators
template <typename T>
inline T operator &(const T& a, const T& b);
template <typename T>
inline T operator |(const T& a, const T& b);
template <typename T>
inline T operator ^(const T& a, const T& b);
template <typename T>
inline T operator <<(const T& a, const T& b);
template <typename T>
inline T operator >>(const T& a, const T& b);

// compound assignment operators
template <typename T>
inline T& operator -=(T& a, const T& b);
template <typename T>
inline T& operator %=(T& a, const T& b);
template <typename T>
inline T& operator ^=(T& a, const T& b);
template <typename T>
inline T& operator >>=(T& a, const T& b);

// arithmetic operators
template <typename T>
inline T operator +(const T& a, const T& b)
{
	T result = a;
	return result += b;
}

template <typename T>
inline T operator -(const T& a, const T& b)
{
	T result = a;
	return result -= b;
}

template <typename T>
inline T operator +(const T& a)
{
	return a;
}

template <typename T>
inline T operator *(const T& a, const T& b)
{
	T result = a;
	return result *= b;
}

template <typename T>
inline T operator /(const T& a, const T& b)
{
	T result = a;
	return result /= b;
}

template <typename T>
inline T operator %(const T& a, const T& b)
{
	T result = a;
	return result %= b;
}

template <typename T>
inline T& operator ++(T& a)
{
	return a += 1;
}

template <typename T>
inline T operator ++(T& a, int)
{
	T result = a;
	++a;
	return result;
}

template <typename T>
inline T& operator --(T& a)
{
	return a -= 1;
}

template <typename T>
inline T operator --(T& a, int)
{
	T result = a;
	--a;
	return result;
}

// comparison operators
template <typename T>
inline bool operator!=(const T& a,const T& b)
{
	return !(a == b);
}

template <typename T>
inline bool operator>(const T& a,const T& b)
{
	return b < a;
}

template <typename T>
inline bool operator<=(const T& a,const T& b)
{
	return !(a > b);
}

template <typename T>
inline bool operator>=(const T& a,const T& b)
{
	return !(a < b);
}

// bitwise operators
template <typename T>
inline T operator &(const T& a, const T& b)
{
	T result = a;
	return result &= b;
}

template <typename T>
inline T operator |(const T& a, const T& b)
{
	T result = a;
	return result |= b;
}

template <typename T>
inline T operator ^(const T& a, const T& b)
{
	T result = a;
	return result ^= b;
}

template <typename T>
inline T operator <<(const T& a, const T& b)
{
	T result = a;
	return result <<= b;
}

template <typename T>
inline T operator >>(const T& a, const T& b)
{
	T result = a;
	return result >>= b;
}

// compound assignment operators
template <typename T>
inline T& operator -=(T& a, const T& b)
{
	return a += -b;
}

template <typename T>
inline T& operator %=(T& a, const T& b)
{
	return a -= a / b * b;
}

template <typename T>
inline T& operator ^=(T& a, const T& b)
{
	return a = ~(a & b) & (a | b);
}

template <typename T>
inline T& operator >>=(T& a, const T& b)
{
	return a <<= -b;
}

#endif // RELOP_H_INCLUDED

#ifndef MOD
#define MOD 1000000007
#endif // MOD

class Remainder
{
public:
    long long value;
    Remainder(long long = 0);
};

inline Remainder operator + (const Remainder & l, const Remainder & r);

inline Remainder operator - (const Remainder & l, const Remainder & r);

inline Remainder operator * (const Remainder & l, const Remainder & r);

inline Remainder operator / (const Remainder & l, const Remainder & r);

inline Remainder & operator++(Remainder & r);

inline Remainder operator++(Remainder & r, int);

inline Remainder & operator--(Remainder & r);

inline Remainder operator--(Remainder & r, int);

inline Remainder operator + (const Remainder & r);

inline Remainder operator - (const Remainder & r);

inline Remainder & operator += (Remainder & l, const Remainder & r);

inline Remainder & operator -= (Remainder & l, const Remainder & r);

inline Remainder & operator *= (Remainder & l, const Remainder & r);

inline Remainder & operator /= (Remainder & l, const Remainder & r);

inline Remainder operator ~ (const Remainder & l);

inline bool operator == (const Remainder & l, const Remainder & r);

inline bool operator < (const Remainder & l, const Remainder & r);

// OUTPUT << A
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & os, const Remainder & o);

// INPUT >> A
template <typename charT, typename traits>
inline std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & is, Remainder & o);

inline Remainder::Remainder(long long r)
{
    value = r;
	value %= MOD;
	if (value < 0)
	{
		value += MOD;
	}
}

inline Remainder operator + (const Remainder & l, const Remainder & r) // A + B
{
   Remainder oResult(l.value + r.value);
   return oResult ;
}

inline Remainder operator - (const Remainder & l, const Remainder & r) // A - B
{
   Remainder oResult(l.value - r.value);
   return oResult ;
}

inline Remainder operator * (const Remainder & l, const Remainder & r) // A * B
{
   Remainder oResult(l.value * r.value);
   return oResult ;
}

inline Remainder operator / (const Remainder & l, const Remainder & r) // A / B
{
	long long x, y;
	gcd(r.value, static_cast<long long>(MOD), x, y);
   Remainder oResult(l * x);
   return oResult ;
}

inline Remainder & operator++(Remainder & r) // ++A
{
   r += 1;
   return r ;
}

inline Remainder operator++(Remainder & r, int) // A++
{
   Remainder oCopy(r);
   r += 1;
   return oCopy ;
}

inline Remainder & operator--(Remainder & r) // --A
{
   r -= 1;
   return r ;
}

inline Remainder operator--(Remainder & r, int) // A--
{
   Remainder oCopy(r);
   r -= 1;
   return oCopy ;
}

inline Remainder operator + (const Remainder & r) // +A
{
   return r ;
}

inline Remainder operator - (const Remainder & r) // -A
{
	Remainder temp(-(r.value));
   return temp;
}

inline Remainder & operator += (Remainder & l, const Remainder & r) // A += B
{
   l = l + r;

   return l ;
}

inline Remainder & operator -= (Remainder & l, const Remainder & r) // A -= B
{
   l = l - r;

   return l ;
}

inline Remainder & operator *= (Remainder & l, const Remainder & r) // A *= B
{
   l = l * r;

   return l ;
}

inline Remainder & operator /= (Remainder & l, const Remainder & r) // A /= B
{
   l = l / r;

   return l ;
}

inline Remainder operator ~ (const Remainder & l) // ~A
{
   Remainder oResult(-l);
   return oResult ;
}

inline bool operator == (const Remainder & l, const Remainder & r) // A == B
{
   return l.value == r.value ;
}

inline bool operator < (const Remainder & l, const Remainder & r) // A < B
{
   return l.value < r.value ;
}

// OUTPUT << A
template <typename charT, typename traits>
inline std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & os, const Remainder & o)
{
   os << o.value;
   return os ;
}

// INPUT >> A
template <typename charT, typename traits>
inline std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & is, Remainder & o)
{
   is >> o.value;
   o = Remainder(o);
   return is ;
}

#endif // MOD_H_INCLUDED

#include <vector>
#include <cstdio>

int main()
{
	int n;
	scanf("%d", &n);

	int* s = new int[n];
	unordered_map<int,int> f;
	unordered_map<int,vector<int>> b;
	rep (i, n)
	{
		int from, to;
		scanf("%d%d", &from, &to);
		s[i] = from;
		f[from] = to;
		b[to].push_back(from);
	}

	Remainder result = 1;

    unordered_set<int> considered;
    rep (i, n)
    {
    	int start = s[i];
        int spot = s[i];
        if (considered.count(spot))
		{
            continue;
		}

		unordered_set<int> visited;
		bool loop = false;
        while (f.find(spot) != f.end())
		{
			visited.insert(spot);
            spot = f[spot];
            if (visited.count(spot))
			{
				loop = true;
                break;
			}
		}

		if (loop)
		{
			spot = start;
			unordered_set<int> visited;
			while (f.find(spot) != f.end())
			{
				considered.insert(spot);
				visited.insert(spot);
				spot = f[spot];
				if (visited.count(spot))
				{
					break;
				}
			}

			if (spot != f[spot])
			{
                result *= 2;
			}

            continue;
		}

		vector<int> togo;
		togo.push_back(spot);

		int spots = 0;

		int index = 0;

		while (index != togo.size())
		{
			++spots;
			int spot = togo[index];
			++index;
            considered.insert(spot);

            int bindex = 0;
            while (bindex != b[spot].size())
			{
                togo.push_back(b[spot][bindex]);
                ++bindex;
			}
		}

		result *= spots;
    }

	cout << result;

	eOP();
}

inline void eOP()
{
	cout << output.str();
	output.str(string());
	exit(0);
}


#include<bits/stdc++.h>
#define fs ios_base::sync_with_stdio (0); cin.tie(0)
#define f(i,a,b) for(ll i=a;i<b;i++)
#define ll long long
#define pb(x) push_back(x)
#define mkp make_pair
#define S second
#define F first
#define N 200002
using namespace std;

ll n,a,b,x,y,res=1,mod=1e9+7;
ll p[N],sz[N];
bool ok[N];

ll fnd(ll x){
    return p[x]==x?x:fnd(p[x]);
}

int main(){
    fs;
    cin>>n;
    memset(ok,false,sizeof ok);
    f(i,0,2*n){
        p[i]=i;
        sz[i]=1;
    }
    f(i,0,n){
        cin>>a>>b;
        a--;b--;
        ok[a]=true;
        if(a==b)continue;
        x=fnd(a);
        y=fnd(b);
        if(x==y){
            res*=2;
            res%=mod;
        }else{
            p[b]=p[a];
            sz[b]+=sz[a];
        }
    }
    f(i,0,2*n){
        if(!ok[i]){
            res*=sz[i];
            res%=mod;
        }
    }
    cout<<res<<"\n";

    return 0;
}


#include<bits/stdc++.h>
#define fs ios_base::sync_with_stdio (0); cin.tie(0)
#define f(i,a,b) for(ll i=a;i<b;i++)
#define ll long long
#define pb(x) push_back(x)
#define mkp make_pair
#define S second
#define F first
#define N 200002
using namespace std;

ll n,a,b,x,y,res=1;
ll p[N],sz[N];
bool ok[N];

ll fnd(ll x){
    return p[x]==x?x:fnd(p[x]);
}

int main(){
    fs;
    cin>>n;
    memset(ok,false,sizeof ok);
    f(i,0,2*n){
        p[i]=i;
        sz[i]=1;
    }
    f(i,0,n){
        cin>>a>>b;
        if(a==b)continue;
        a--;b--;
        ok[a]=true;
        x=fnd(a);
        y=fnd(b);
        if(x==y){
            res*=2;
        }else{
            p[b]=p[a];
            sz[b]+=sz[a];
        }
    }
    f(i,0,2*n){
        if(!ok[i])
            res*=sz[i];
    }
    cout<<res<<"\n";

    return 0;
}


#include<bits/stdc++.h>
#define fs ios_base::sync_with_stdio (0); cin.tie(0)
#define f(i,a,b) for(ll i=a;i<b;i++)
#define ll long long
#define pb(x) push_back(x)
#define mkp make_pair
#define S second
#define F first
#define N 200002
using namespace std;

ll n,a,b,x,y,res=1,mod=1e9+7;
ll p[N],sz[N];
bool ok[N];

ll fnd(ll x){
    return p[x]==x?x:fnd(p[x]);
}

int main(){
    fs;
    cin>>n;
    memset(ok,false,sizeof ok);
    f(i,0,2*n){
        p[i]=i;
        sz[i]=1;
    }
    f(i,0,n){
        cin>>a>>b;
        a--;b--;
        ok[a]=true;
        if(a==b)continue;
        x=fnd(a);
        y=fnd(b);
        if(x==y){
            res*=2;
            res%=mod;
        }
        p[b]=p[a];
        sz[b]+=sz[a];
    }
    f(i,0,2*n){
        if(!ok[i]){
            res*=sz[i];
            res%=mod;
        }
    }
    cout<<res<<"\n";

    return 0;
}


#include<bits/stdc++.h>
#define fs ios_base::sync_with_stdio (0); cin.tie(0)
#define f(i,a,b) for(ll i=a;i<b;i++)
#define ll long long
#define pb(x) push_back(x)
#define mkp make_pair
#define S second
#define F first
#define N 200002
using namespace std;

ll n,a,b,x,y,res=1,mod=1e9+7;
ll p[N],sz[N];
bool ok[N];

ll fnd(ll x){
    return p[x]==x?x:p[x]=fnd(p[x]);
}

int main(){
    fs;
    cin>>n;
    memset(ok,false,sizeof ok);
    f(i,0,2*n){
        p[i]=i;
        sz[i]=1;
    }
    f(i,0,n){
        cin>>a>>b;
        a--;b--;
        ok[a]=true;
        if(a==b)continue;
        x=fnd(a);
        y=fnd(b);
        if(x==y){
            res*=2;
            res%=mod;
        }else{
            p[a]=p[b];
            sz[b]+=sz[a];
        }
    }
    f(i,0,2*n){
        if(!ok[i]){
            res*=sz[i];
            res%=mod;
        }
    }
    cout<<res<<"\n";

    return 0;
}


#include<bits/stdc++.h>
#define fs ios_base::sync_with_stdio (0); cin.tie(0)
#define f(i,a,b) for(ll i=a;i<b;i++)
#define ll long long
#define pb(x) push_back(x)
#define mkp make_pair
#define S second
#define F first
#define N 200002
using namespace std;

ll n,a,b,x,y,res=1,mod=1e9+7;
ll p[N],sz[N];
bool ok[N];

ll fnd(ll x){
    return p[x]==x?x:p[x]=fnd(p[x]);
}

int main(){
    fs;
    cin>>n;
    memset(ok,false,sizeof ok);
    f(i,0,2*n){
        p[i]=i;
        sz[i]=1;
    }
    f(i,0,n){
        cin>>a>>b;
        a--;b--;
        ok[a]=true;
        if(a==b)continue;
        x=fnd(a);
        y=fnd(b);
        if(x==y){
            res=(res*2)%mod;
        }else{
            p[a]=b;
            sz[b]+=sz[a];
        }
    }
    f(i,0,2*n){
        if(!ok[i]){
            res=(res*sz[i])%mod;
        }
    }
    cout<<res<<"\n";

    return 0;
}


#include<bits/stdc++.h>
#define fs ios_base::sync_with_stdio (0); cin.tie(0)
#define f(i,a,b) for(ll i=a;i<b;i++)
#define ll long long
#define pb(x) push_back(x)
#define mkp make_pair
#define S second
#define F first
#define N 200002
using namespace std;

ll n,a,b,x,y,res=1,mod=1e9+7;
ll p[N],sz[N];
bool ok[N];

ll fnd(ll x){
    return p[x]==x?x:fnd(p[x]);
}

int main(){
    fs;
    cin>>n;
    memset(ok,false,sizeof ok);
    f(i,0,2*n){
        p[i]=i;
        sz[i]=1;
    }
    f(i,0,n){
        cin>>a>>b;
        a--;b--;
        ok[a]=true;
        if(a==b)continue;
        x=fnd(a);
        y=fnd(b);
        if(x==y){
            res*=2;
            res%=mod;
        }
        p[a]=p[b];
        sz[b]+=sz[a];
    }
    f(i,0,2*n){
        if(!ok[i]){
            res*=sz[i];
            res%=mod;
        }
    }
    cout<<res<<"\n";

    return 0;
}


#include<bits/stdc++.h>
#define fs ios_base::sync_with_stdio (0); cin.tie(0)
#define f(i,a,b) for(ll i=a;i<b;i++)
#define ll long long
#define pb(x) push_back(x)
#define mkp make_pair
#define S second
#define F first
#define N 200002
using namespace std;

ll n,a,b,x,y,res=1,mod=1e9+7;
ll p[N],sz[N];
bool ok[N];

ll fnd(ll x){
    return p[x]==x?x:p[x]=fnd(p[x]);
}

int main(){
    fs;
    cin>>n;
    memset(ok,false,sizeof ok);
    f(i,0,2*n){
        p[i]=i;
        sz[i]=1;
    }
    f(i,0,n){
        cin>>a>>b;
        a--;b--;
        ok[a]=true;
        if(a==b)continue;
        x=fnd(a);
        y=fnd(b);
        if(x==y){
            res*=2;
            res%=mod;
        }else{
            p[x]=y;
            sz[y]+=sz[x];
        }
    }
    f(i,0,2*n){
        if(!ok[i]){
            res*=sz[i];
            res%=mod;
        }
    }
    cout<<res<<"\n";

    return 0;
}


#include<bits/stdc++.h>
#define fs ios_base::sync_with_stdio (0); cin.tie(0)
#define f(i,a,b) for(ll i=a;i<b;i++)
#define ll long long
#define pb(x) push_back(x)
#define mkp make_pair
#define S second
#define F first
#define N 200002
using namespace std;

ll n,a,b,x,y,res=1,mod=1e9+7;
ll p[N],sz[N];
bool ok[N];

ll fnd(ll x){
    return p[x]==x?x:fnd(p[x]);
}

int main(){
    fs;
    cin>>n;
    memset(ok,false,sizeof ok);
    f(i,0,2*n){
        p[i]=i;
        sz[i]=1;
    }
    f(i,0,n){
        cin>>a>>b;
        if(a==b)continue;
        a--;b--;
        ok[a]=true;
        x=fnd(a);
        y=fnd(b);
        if(x==y){
            res*=2;
            res%=mod;
        }else{
            p[b]=p[a];
            sz[b]+=sz[a];
        }
    }
    f(i,0,2*n){
        if(!ok[i]){
            res*=sz[i];
            res%=mod;
        }
    }
    cout<<res<<"\n";

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007

int A[200005], B[200005], H[200005];
int visit[200005];
long long dp[200005];

vector<int> X[200005];

long long solve(int i)
{
    if(visit[i])
        return dp[i];

    visit[i] = 1;
    long long ans = 1;

    for(int j=0; j<X[i].size(); j++)
        ans += solve(X[i][j]);

    return dp[i] = ans%MOD;
}

void dfs(int i)
{
    if(visit[i])
        return;

    visit[i] = 1;

    for(int j=0; j<X[i].size(); j++)
        dfs(X[i][j]);
}

int main()
{
    int N;
    scanf("%d", &N);

    for(int i=1; i<=N; i++)
    {
        scanf("%d %d", &A[i], &B[i]);
        H[ A[i] ] = i;
    }

    int k = N;

    for(int i=1; i<=N; i++)
    {
        if(H[ B[i] ] == 0)
            H[ B[i] ] = ++k;

        B[i] = H[ B[i] ];
        X[ B[i] ].push_back(i);
    }

    long long ans = 1;
    memset(dp, -1, sizeof(dp));

    for(int i=N+1; i<=k; i++)
        ans = ans * solve(i) % MOD;

    for(int i=1; i<=N; i++)
        if(visit[i] == 0)
        {
            dfs(i);

            if(B[i] != i)
                ans = ans * 2 % MOD;
        }

    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007

int A[200005], B[200005], H[200005];
int visit[200005], sz[200005], edge[200005];
long long dp[200005];

vector<int> X[200005], Y[200005];

long long solve(int i)
{
    if(visit[i])
        return dp[i];

    visit[i] = 1;
    long long ans = 1;

    for(int j=0; j<X[i].size(); j++)
        ans += solve(X[i][j]);

    return dp[i] = ans%MOD;
}

void dfs(int i, int col)
{
    if(visit[i])
        return ;

    visit[i] = col;

    for(int j=0; j<Y[i].size(); j++)
        dfs(Y[i][j], col);
}

int main()
{
    int N;
    scanf("%d", &N);

    for(int i=1; i<=N; i++)
    {
        scanf("%d %d", &A[i], &B[i]);
        H[ A[i] ] = i;
    }

    int k = N;

    for(int i=1; i<=N; i++)
    {
        if(H[ B[i] ] == 0)
            H[ B[i] ] = ++k;

        B[i] = H[ B[i] ];
        X[ B[i] ].push_back(i);

        if(i != B[i])
        {
            Y[ B[i] ].push_back(i);
            Y[ i ].push_back(B[i]);
        }
    }

    int col = 1;
    long long ans = 1;
    memset(dp, -1, sizeof(dp));

    for(int i=N+1; i<=k; i++)
        ans = ans * solve(i) % MOD;

    for(int i=1; i<=N; i++)
        if(visit[i] == 0)
            dfs(i, ++col);

    for(int i=1; i<=N; i++)
    {
        sz[ visit[i] ]++;

        for(int j=0; j<Y[i].size(); j++)
            edge[ visit[i] ]++;
    }

    for(int i=2; i<=col; i++)
    {
        if(edge[i] == 2 * (sz[i]-1) )
            continue;

        ans = ans*2 % MOD;
    }

    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007

int A[200005], B[200005], H[200005];
int visit[200005];
long long dp[200005];

vector<int> X[200005];

long long solve(int i)
{
    if(visit[i])
        return dp[i];

    visit[i] = 1;
    long long ans = 1;

    for(int j=0; j<X[i].size(); j++)
        ans += solve(X[i][j]);

    return dp[i] = ans%MOD;
}

int dfs(int i, int col)
{
    if(visit[i])
        return (visit[i] != col);

    visit[i] = col;
    int ans = 0;

    for(int j=0; j<X[i].size(); j++)
        ans |= dfs(X[i][j], col);

    return ans;
}

int main()
{
    int N;
    scanf("%d", &N);

    for(int i=1; i<=N; i++)
    {
        scanf("%d %d", &A[i], &B[i]);
        H[ A[i] ] = i;
    }

    int k = N;

    for(int i=1; i<=N; i++)
    {
        if(H[ B[i] ] == 0)
            H[ B[i] ] = ++k;

        B[i] = H[ B[i] ];
        X[ B[i] ].push_back(i);
    }

    long long ans = 1;
    memset(dp, -1, sizeof(dp));

    int col = 0;

    for(int i=N+1; i<=k; i++)
        ans = ans * solve(i) % MOD;

    for(int i=1; i<=N; i++)
        if(visit[i] == 0)
        {
            int flag = dfs(i, ++col);

            if(B[i] == i)
                continue;

            if(flag == 0)
                ans = ans * 2 % MOD;
        }

    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007

int A[200005], B[200005], H[200005];
int visit[200005];
long long dp[200005];

vector<int> X[200005];

long long solve(int i)
{
    if(visit[i])
        return dp[i];

    visit[i] = 1;
    long long ans = 1;

    for(int j=0; j<X[i].size(); j++)
        ans += solve(X[i][j]);

    return dp[i] = ans%MOD;
}

void dfs(int i)
{
    if(visit[i])
        return;

    visit[i] = 1;

    for(int j=0; j<X[i].size(); j++)
        dfs(X[i][j]);
}

int main()
{
    int N;
    scanf("%d", &N);

    for(int i=1; i<=N; i++)
    {
        scanf("%d %d", &A[i], &B[i]);
        H[ A[i] ] = i;
    }

    int k = N;

    for(int i=1; i<=N; i++)
    {
        if(H[ B[i] ] == 0)
            H[ B[i] ] = ++k;

        B[i] = H[ B[i] ];
        X[ B[i] ].push_back(i);
    }

    long long ans = 1;
    memset(dp, -1, sizeof(dp));

    for(int i=N+1; i<=k; i++)
        ans = ans * solve(i) % MOD;

    for(int i=1; i<=N; i++)
        if(visit[i] == 0 && X[i].size() == 1)
        {
            dfs(i);

            if(B[i] != i)
                ans = ans * 2 % MOD;
        }

    for(int i=1; i<=N; i++)
        if(visit[i] == 0)
        {
            dfs(i);

            if(B[i] != i)
                ans = ans * 2 % MOD;
        }

    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007

int A[200005], B[200005], H[200005];
int visit[200005];
long long dp[200005];

vector<int> X[200005], Y[200005];

long long solve(int i)
{
    if(visit[i])
        return dp[i];

    visit[i] = 1;
    long long ans = 1;

    for(int j=0; j<X[i].size(); j++)
        ans += solve(X[i][j]);

    return dp[i] = ans%MOD;
}

int dfs(int i)
{
    if(visit[i])
        return 0;

    visit[i] = 1;
    int ans = 1;

    for(int j=0; j<Y[i].size(); j++)
        ans += dfs(Y[i][j]);

    return ans;
}

int main()
{
    int N;
    scanf("%d", &N);

    for(int i=1; i<=N; i++)
    {
        scanf("%d %d", &A[i], &B[i]);
        H[ A[i] ] = i;
    }

    int k = N;

    for(int i=1; i<=N; i++)
    {
        if(H[ B[i] ] == 0)
            H[ B[i] ] = ++k;

        B[i] = H[ B[i] ];
        X[ B[i] ].push_back(i);

        Y[ B[i] ].push_back(i);
        Y[ i ].push_back(B[i]);
    }

    long long ans = 1;
    memset(dp, -1, sizeof(dp));

    for(int i=N+1; i<=k; i++)
        ans = ans * solve(i) % MOD;

    for(int i=1; i<=N; i++)
        if(visit[i] == 0)
        {
            int sz = dfs(i);

            if(sz != 1)
                ans = ans * 2 % MOD;
        }

    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define MOD 1000000007

int A[200005], B[200005], H[200005];
int visit[200005], sz[200005], edge[200005];
long long dp[200005];

vector<int> X[200005], Y[200005];

long long solve(int i)
{
    if(visit[i])
        return dp[i];

    visit[i] = 1;
    long long ans = 1;

    for(int j=0; j<X[i].size(); j++)
        ans += solve(X[i][j]);

    return dp[i] = ans%MOD;
}

void dfs(int i, int col)
{
    if(visit[i])
        return ;

    visit[i] = col;

    for(int j=0; j<Y[i].size(); j++)
        dfs(Y[i][j], col);
}

int main()
{
    int N;
    scanf("%d", &N);

    for(int i=1; i<=N; i++)
    {
        scanf("%d %d", &A[i], &B[i]);
        H[ A[i] ] = i;
    }

    int k = N;

    for(int i=1; i<=N; i++)
    {
        if(H[ B[i] ] == 0)
            H[ B[i] ] = ++k;

        B[i] = H[ B[i] ];
        X[ B[i] ].push_back(i);

        if(i != B[i])
        {
            Y[ B[i] ].push_back(i);
            Y[ i ].push_back(B[i]);
        }
    }

    int col = 1;
    long long ans = 1;
    memset(dp, -1, sizeof(dp));

    for(int i=N+1; i<=k; i++)
        ans = ans * solve(i) % MOD;

    for(int i=1; i<=N; i++)
        if(visit[i] == 0)
            dfs(i, ++col);

    for(int i=1; i<=N; i++)
    {
        sz[ visit[i] ]++;

        for(int j=0; j<Y[i].size(); j++)
            edge[ Y[i][j] ]++;
    }

    for(int i=2; i<=col; i++)
    {
        if(edge[i] == 2 * (sz[i]-1) )
            continue;

        ans = ans*2 % MOD;
    }

    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define MP make_pair
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define Set(N,cur) N=(N|(1LL<<cur))
#define Reset(N,cur) N=(N&(~(1LL<<cur)))
#define Check(N,cur) (!((N&(1LL<<cur))==0))
#define fast_cin ios_base::sync_with_stdio(false);cin.tie(NULL)
#define nl printf("\n")
#define phl cerr<<"hello\n"
#define arrayIndexPrint(A,i) cerr<<"@ At pos: "<<i<<" = "<<A[i]
#define dump(x) cerr<<"@ "<<#x<<" = "<<x<<endl
#define arrayPrint(A,st,ed) cerr<<"@ Array:";FOR(i,st,ed) cerr<<" "<<A[i];cerr<<endl
#define LINE cerr<<"\n"; FOR(i,0,50) cerr<<"=";cerr<<"\n\n"

#ifdef forthright48
     #include <ctime>
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
     #define debug(args...)  // Just strip off all debug tokens
     #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

#define LL long long
#define LLU long long unsigned int
typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < int, int > pii;
typedef pair < vlong, vlong > pll;

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0; x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1; r = r2 % r1;
        x = x2 - (q * x1); y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m;
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

inline int STRLEN(char *s){
    int p = 0; while(s[p]) p++; return p;
}

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//int dir8[8][2] = {{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}};

const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
const LL inf = 2147383647LL;
const LL mod = 1e9 + 7; /// CHANGE HERE
const int Size = 200005; /// CHANGE HERE

///=========================  TEMPLATE ENDS HERE  ========================///

int N;
int deg[Size];
int vis[Size];
vector<int> RG[Size];

LL call(int u){
    LL res = SZ(RG[u]);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        res += call(v);
    }
    return res;
}

void mark(int u){
    vis[u] = 1;
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        if(!vis[v]) mark(v);
    }
}

vector<int> List, self;

int main () {
    #ifdef forthright48
    freopen ( "input.txt", "r", stdin );
    /// freopen ( "output.txt", "w", stdout );
    #endif // forthright48

    scanf("%d",&N);
    CLR(deg, 0);
    CLR(vis, 0);
    for(int i = 0;i<N;i++){
        int u, v;
        scanf("%d %d",&u,&v);
        if(u == v){
            self.pb(u);
            continue;
        }
        RG[v].pb(u);
        deg[u]++;
        List.pb(u);
        List.pb(v);
    }

    sort(ALL(List));
    UNIQUE(List);

    for(int i = 0;i<SZ(self);i++){
        int u = self[i];
        mark(u);
    }

    LL res = 1;
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] == 0) {
            //debug("DEG: ",u);
            LL ret = call(u) + 1;
            res = (res*ret)%mod;
            mark(u);
        }
    }
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] != 0){
            //debug("NOR: ",u);
            res = (res*2LL)%mod;
            mark(u);
        }
    }

    cout << res << endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define MP make_pair
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define Set(N,cur) N=(N|(1LL<<cur))
#define Reset(N,cur) N=(N&(~(1LL<<cur)))
#define Check(N,cur) (!((N&(1LL<<cur))==0))
#define fast_cin ios_base::sync_with_stdio(false);cin.tie(NULL)
#define nl printf("\n")
#define phl cerr<<"hello\n"
#define arrayIndexPrint(A,i) cerr<<"@ At pos: "<<i<<" = "<<A[i]
#define dump(x) cerr<<"@ "<<#x<<" = "<<x<<endl
#define arrayPrint(A,st,ed) cerr<<"@ Array:";FOR(i,st,ed) cerr<<" "<<A[i];cerr<<endl
#define LINE cerr<<"\n"; FOR(i,0,50) cerr<<"=";cerr<<"\n\n"

#ifdef forthright48
     #include <ctime>
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
     #define debug(args...)  // Just strip off all debug tokens
     #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

#define LL long long
#define LLU long long unsigned int
typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < int, int > pii;
typedef pair < vlong, vlong > pll;

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0; x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1; r = r2 % r1;
        x = x2 - (q * x1); y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m;
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

inline int STRLEN(char *s){
    int p = 0; while(s[p]) p++; return p;
}

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//int dir8[8][2] = {{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}};

const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
const LL inf = 2147383647LL;
const LL mod = 1e9 + 7; /// CHANGE HERE
const int Size = 200005; /// CHANGE HERE

///=========================  TEMPLATE ENDS HERE  ========================///

int N;
int deg[Size];
int indeg[Size];
int vis[Size];
int color[Size];
vector<int> RG[Size], G[Size];
int id = 0, cycleHead;
vector<int> List, self;
LL res = 1;

LL call(int u){
    LL res = SZ(RG[u]);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        res += call(v);
    }
    return res;
}

void mark(int u){
    vis[u] = 1;
    //debug("Mark: ",u);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        if(!vis[v]) mark(v);
    }
}

bool findcycle(int u){
    if(color[u] == id){
        cycleHead = u;
        return true;
    }
    if(color[u] != 0) return false;
    color[u] = id;
    //debug("   Color: ",u," = ",id);
    for(int i = 0;i<SZ(G[u]);i++){
        int v = G[u][i];
        if(findcycle(v)) return true;
    }
    return false;
}

void vanishCycle(){
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(color[u] != 0) continue;
        id++;
        //debug("CALL FROM: ",u);
        if(findcycle(u)){
            int cur = cycleHead, cnt = 0;
            while(1){
                cnt++;
                cur = G[cur][0];
                if(cur == cycleHead) break;
            }
            if(cnt>1) res = (res*2LL)%mod;
            mark(cycleHead);
        }
    }
}

int main () {
    #ifdef forthright48
    freopen ( "input.txt", "r", stdin );
    /// freopen ( "output.txt", "w", stdout );
    #endif // forthright48

    scanf("%d",&N);
    CLR(deg, 0);
    CLR(vis, 0);
    CLR(color, 0);
    for(int i = 0;i<N;i++){
        int u, v;
        scanf("%d %d",&u,&v);
        G[u].pb(v);
        RG[v].pb(u);
        deg[u]++;
        List.pb(u);
        List.pb(v);
    }

    vanishCycle();
    sort(ALL(List));
    UNIQUE(List);

    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] == 0) {
            LL ret = call(u) + 1;
            res = (res*ret)%mod;
            mark(u);
        }
    }

    cout << res << endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define MP make_pair
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define Set(N,cur) N=(N|(1LL<<cur))
#define Reset(N,cur) N=(N&(~(1LL<<cur)))
#define Check(N,cur) (!((N&(1LL<<cur))==0))
#define fast_cin ios_base::sync_with_stdio(false);cin.tie(NULL)
#define nl printf("\n")
#define phl cerr<<"hello\n"
#define arrayIndexPrint(A,i) cerr<<"@ At pos: "<<i<<" = "<<A[i]
#define dump(x) cerr<<"@ "<<#x<<" = "<<x<<endl
#define arrayPrint(A,st,ed) cerr<<"@ Array:";FOR(i,st,ed) cerr<<" "<<A[i];cerr<<endl
#define LINE cerr<<"\n"; FOR(i,0,50) cerr<<"=";cerr<<"\n\n"

#ifdef forthright48
     #include <ctime>
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
     #define debug(args...)  // Just strip off all debug tokens
     #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

#define LL long long
#define LLU long long unsigned int
typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < int, int > pii;
typedef pair < vlong, vlong > pll;

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0; x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1; r = r2 % r1;
        x = x2 - (q * x1); y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m;
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

inline int STRLEN(char *s){
    int p = 0; while(s[p]) p++; return p;
}

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//int dir8[8][2] = {{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}};

const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
const LL inf = 2147383647LL;
const LL mod = 1e9 + 7; /// CHANGE HERE
const int Size = 200005; /// CHANGE HERE

///=========================  TEMPLATE ENDS HERE  ========================///

int N;
int deg[Size];
int indeg[Size];
int vis[Size];
int color[Size];
vector<int> RG[Size], G[Size];
int id = 0, cycleHead;
vector<int> List, self;
LL res = 1;

LL call(int u){
    LL res = SZ(RG[u]);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        res += call(v);
    }
    return res;
}

void mark(int u){
    vis[u] = 1;
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        if(!vis[v]) mark(v);
    }
}

bool findcycle(int u){
    if(color[u] == id){
        cycleHead = u;
        return true;
    }
    if(color[u] != 0) return false;
    color[u] = id;
    for(int i = 0;i<SZ(G[u]);i++){
        int v = G[u][i];
        if(findcycle(v)) return true;
    }
    return false;
}

void vanishCycle(){
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(color[u] != 0) continue;
        id++;
        if(findcycle(u)){
            int cur = cycleHead, cnt = 0;
            while(1){
                cnt++;
                cur = G[cur][0];
                if(cur == cycleHead) break;
            }
            /// If a cycle length is 1 then you have no option there.
            /// Otherwise you have only one option.
            if(cnt>1) res = (res*2LL)%mod;
            mark(cycleHead);
        }
    }
}

int main () {
    #ifdef forthright48
    freopen ( "input.txt", "r", stdin );
    /// freopen ( "output.txt", "w", stdout );
    #endif // forthright48

    scanf("%d",&N);
    CLR(deg, 0);
    CLR(vis, 0);
    CLR(color, 0);
    for(int i = 0;i<N;i++){
        int u, v;
        scanf("%d %d",&u,&v);
        G[u].pb(v);
        RG[v].pb(u);
        deg[u]++;
        List.pb(u);
        List.pb(v);
    }

    vanishCycle();
    sort(ALL(List));
    UNIQUE(List);

    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] == 0) {
            LL ret = call(u) + 1;
            res = (res*ret)%mod;
            mark(u);
        }
    }

    cout << res << endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define MP make_pair
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define Set(N,cur) N=(N|(1LL<<cur))
#define Reset(N,cur) N=(N&(~(1LL<<cur)))
#define Check(N,cur) (!((N&(1LL<<cur))==0))
#define fast_cin ios_base::sync_with_stdio(false);cin.tie(NULL)
#define nl printf("\n")
#define phl cerr<<"hello\n"
#define arrayIndexPrint(A,i) cerr<<"@ At pos: "<<i<<" = "<<A[i]
#define dump(x) cerr<<"@ "<<#x<<" = "<<x<<endl
#define arrayPrint(A,st,ed) cerr<<"@ Array:";FOR(i,st,ed) cerr<<" "<<A[i];cerr<<endl
#define LINE cerr<<"\n"; FOR(i,0,50) cerr<<"=";cerr<<"\n\n"

#ifdef forthright48
     #include <ctime>
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
     #define debug(args...)  // Just strip off all debug tokens
     #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

#define LL long long
#define LLU long long unsigned int
typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < int, int > pii;
typedef pair < vlong, vlong > pll;

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0; x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1; r = r2 % r1;
        x = x2 - (q * x1); y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m;
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

inline int STRLEN(char *s){
    int p = 0; while(s[p]) p++; return p;
}

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//int dir8[8][2] = {{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}};

const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
const LL inf = 10000000000000000LL;
const LL mod = 1e9 + 7; /// CHANGE HERE
const int Size = 20005; /// CHANGE HERE

///=========================  TEMPLATE ENDS HERE  ========================///

#ifdef forthright48
     typedef long long myint;
#else
     typedef __int128 myint;
#endif

vector<myint> prime;
bool mark[Size];/// if mark[u] = 1, it's prime
void seive(){
    CLR (mark, true);
    mark [0] = mark [1] = false;
    for(int i = 4;i<Size;i+=2) mark [i] = false;
    for(int i = 3;i*i<=Size;i+=2){
        if(mark[i]){
            for(int j=i*i;j<Size;j+=2*i){
                mark [j] = false;
            }
        }
    }
    prime.pb(2);
    for(int i = 3;i<Size;i+=2){
        if(mark[i]) prime.pb(i);
    }
}

myint RES[33];
int N;

myint solve(){
    LL Till = (1<<N);
    myint best = inf, res = 2;
    for(int mask = 0;mask<Till;mask++){
        myint a = 1, b = 1;
        bool f = true;
        for(int i = 0;i<N;i++){
            if(a>inf || b>inf){
                f = false;
                break;
            }
            if(Check(mask, i)){
                a *= prime[i];
            }else{
                b *= prime[i];
            }
        }
        if(f == true){
            if(a>b) swap(a, b);
            LL dif = b - a;
            if(dif<best){
                best = dif;
                res = a;
            }
        }
    }
    return res;
}

int main () {
    #ifdef forthright48
    //freopen ( "input.txt", "r", stdin );
    //freopen ( "output.txt", "w", stdout );
    #endif // forthright48

    seive();
    //arrayPrint(prime,0,30);
    for(N = 10;N<=10;N++){
        RES[N] = solve();
        debug(N," = ",RES[N]);
        cout << N << " " << RES[N] << endl;
    }
    int cs = 1;
    while(scanf("%d",&N) == 1){
        if(N == 0) break;
        printf("Case #%d: %lld\n",cs++,RES[N]);
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define MP make_pair
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define Set(N,cur) N=(N|(1LL<<cur))
#define Reset(N,cur) N=(N&(~(1LL<<cur)))
#define Check(N,cur) (!((N&(1LL<<cur))==0))
#define fast_cin ios_base::sync_with_stdio(false);cin.tie(NULL)
#define nl printf("\n")
#define phl cerr<<"hello\n"
#define arrayIndexPrint(A,i) cerr<<"@ At pos: "<<i<<" = "<<A[i]
#define dump(x) cerr<<"@ "<<#x<<" = "<<x<<endl
#define arrayPrint(A,st,ed) cerr<<"@ Array:";FOR(i,st,ed) cerr<<" "<<A[i];cerr<<endl
#define LINE cerr<<"\n"; FOR(i,0,50) cerr<<"=";cerr<<"\n\n"

#ifdef forthright48
     #include <ctime>
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
     #define debug(args...)  // Just strip off all debug tokens
     #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

#define LL long long
#define LLU long long unsigned int
typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < int, int > pii;
typedef pair < vlong, vlong > pll;

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0; x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1; r = r2 % r1;
        x = x2 - (q * x1); y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m;
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

inline int STRLEN(char *s){
    int p = 0; while(s[p]) p++; return p;
}

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//int dir8[8][2] = {{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}};

const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
const LL inf = 10000000000000000LL;
const LL mod = 1e9 + 7; /// CHANGE HERE
const int Size = 20005; /// CHANGE HERE

///=========================  TEMPLATE ENDS HERE  ========================///

 //typedef LL myint;
 typedef __int128 myint;

vector<LL> prime;
bool mark[Size];/// if mark[u] = 1, it's prime
void seive(){
    CLR (mark, true);
    mark [0] = mark [1] = false;
    for(int i = 4;i<Size;i+=2) mark [i] = false;
    for(int i = 3;i*i<=Size;i+=2){
        if(mark[i]){
            for(int j=i*i;j<Size;j+=2*i){
                mark [j] = false;
            }
        }
    }
    prime.pb(2);
    for(int i = 3;i<Size;i+=2){
        if(mark[i]) prime.pb(i);
    }
}

myint RES[33];
int N;

myint solve(){
    LL Till = (1<<N);
    myint best = inf, res = 2;
    for(int mask = 0;mask<Till;mask++){
        myint a = 1, b = 1;
        bool f = true;
        for(int i = 0;i<N;i++){
            if(a>inf || b>inf){
                f = false;
                break;
            }
            if(Check(mask, i)){
                a *= prime[i];
            }else{
                b *= prime[i];
            }
        }
        if(f == true){
            if(a>b) swap(a, b);
            LL dif = b - a;
            if(dif<best){
                best = dif;
                res = a;
            }
        }
    }
    return res;
}

int main () {
    #ifdef forthright48
    //freopen ( "input.txt", "r", stdin );
    //freopen ( "output.txt", "w", stdout );
    #endif // forthright48

    seive();
    //arrayPrint(prime,0,30);
    for(N = 10;N<=10;N++){
        RES[N] = solve();
        debug(N," = ",RES[N]);
        cout << N << " " << RES[N] << endl;
    }
    int cs = 1;
    while(scanf("%d",&N) == 1){
        if(N == 0) break;
        printf("Case #%d: %lld\n",cs++,RES[N]);
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define MP make_pair
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define Set(N,cur) N=(N|(1LL<<cur))
#define Reset(N,cur) N=(N&(~(1LL<<cur)))
#define Check(N,cur) (!((N&(1LL<<cur))==0))
#define fast_cin ios_base::sync_with_stdio(false);cin.tie(NULL)
#define nl printf("\n")
#define phl cerr<<"hello\n"
#define arrayIndexPrint(A,i) cerr<<"@ At pos: "<<i<<" = "<<A[i]
#define dump(x) cerr<<"@ "<<#x<<" = "<<x<<endl
#define arrayPrint(A,st,ed) cerr<<"@ Array:";FOR(i,st,ed) cerr<<" "<<A[i];cerr<<endl
#define LINE cerr<<"\n"; FOR(i,0,50) cerr<<"=";cerr<<"\n\n"

#ifdef forthright48
     #include <ctime>
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
     #define debug(args...)  // Just strip off all debug tokens
     #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

#define LL long long
#define LLU long long unsigned int
typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < int, int > pii;
typedef pair < vlong, vlong > pll;

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0; x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1; r = r2 % r1;
        x = x2 - (q * x1); y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m;
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

inline int STRLEN(char *s){
    int p = 0; while(s[p]) p++; return p;
}

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//int dir8[8][2] = {{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}};

const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
const LL inf = 2147383647LL;
const LL mod = 1e9 + 7; /// CHANGE HERE
const int Size = 200005; /// CHANGE HERE

///=========================  TEMPLATE ENDS HERE  ========================///

int N;
int deg[Size];
int indeg[Size];
int vis[Size];
int color[Size];
vector<int> RG[Size], G[Size];
int id = 0, cycleHead;
vector<int> List, self;
LL res = 1;

LL call(int u){
    LL res = SZ(RG[u]);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        res += call(v);
    }
    return res;
}

void mark(int u){
    vis[u] = 1;
    //debug("Mark: ",u);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        if(!vis[v]) mark(v);
    }
}

bool findcycle(int u){
    if(color[u] == id){
        cycleHead = u;
        return true;
    }
    if(color[u] != 0) return false;
    color[u] = id;
    //debug("   Color: ",u," = ",id);
    for(int i = 0;i<SZ(G[u]);i++){
        int v = G[u][i];
        if(findcycle(v)) return true;
    }
    return false;
}

void vanishCycle(){
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(color[u] != 0) continue;
        id++;
        if(findcycle(u)){
            res = (res*2LL)%mod;
            mark(cycleHead);
        }
    }
}

int main () {
    #ifdef forthright48
    freopen ( "input.txt", "r", stdin );
    /// freopen ( "output.txt", "w", stdout );
    #endif // forthright48

    scanf("%d",&N);
    CLR(deg, 0);
    CLR(vis, 0);
    CLR(color, 0);
    CLR(indeg, 0);
    for(int i = 0;i<N;i++){
        int u, v;
        scanf("%d %d",&u,&v);
        if(u == v){
            continue;
        }
        RG[v].pb(u);
        G[u].pb(v);
        deg[u]++;
        indeg[v]++;
        List.pb(u);
        List.pb(v);
    }

    vanishCycle();
    sort(ALL(List));
    UNIQUE(List);

    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] == 0) {
            LL ret = call(u) + 1;
            res = (res*ret)%mod;
            mark(u);
        }
    }

    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] != 0){
            res = (res*2LL)%mod;
            mark(u);
        }
    }

    cout << res << endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define MP make_pair
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define Set(N,cur) N=(N|(1LL<<cur))
#define Reset(N,cur) N=(N&(~(1LL<<cur)))
#define Check(N,cur) (!((N&(1LL<<cur))==0))
#define fast_cin ios_base::sync_with_stdio(false);cin.tie(NULL)
#define nl printf("\n")
#define phl cerr<<"hello\n"
#define arrayIndexPrint(A,i) cerr<<"@ At pos: "<<i<<" = "<<A[i]
#define dump(x) cerr<<"@ "<<#x<<" = "<<x<<endl
#define arrayPrint(A,st,ed) cerr<<"@ Array:";FOR(i,st,ed) cerr<<" "<<A[i];cerr<<endl
#define LINE cerr<<"\n"; FOR(i,0,50) cerr<<"=";cerr<<"\n\n"

#ifdef forthright48
     #include <ctime>
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
     #define debug(args...)  // Just strip off all debug tokens
     #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

#define LL long long
#define LLU long long unsigned int
typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < int, int > pii;
typedef pair < vlong, vlong > pll;

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0; x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1; r = r2 % r1;
        x = x2 - (q * x1); y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m;
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

inline int STRLEN(char *s){
    int p = 0; while(s[p]) p++; return p;
}

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//int dir8[8][2] = {{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}};

const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
const LL inf = 2147383647LL;
const LL mod = 1e9 + 7; /// CHANGE HERE
const int Size = 200005; /// CHANGE HERE

///=========================  TEMPLATE ENDS HERE  ========================///

int N;
int deg[Size];
int indeg[Size];
int vis[Size];
int color[Size];
vector<int> RG[Size], G[Size];
int id = 0, cycleHead;

vector<int> List, self;

LL call(int u){
    LL res = SZ(RG[u]);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        res += call(v);
    }
    return res;
}

void mark(int u){
    vis[u] = 1;
    //debug("Mark: ",u);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        if(!vis[v]) mark(v);
    }
}

bool findcycle(int u){
    if(color[u] == id){
        cycleHead = u;
        return true;
    }
    if(color[u] != 0) return false;
    color[u] = id;
    //debug("   Color: ",u," = ",id);
    for(int i = 0;i<SZ(G[u]);i++){
        int v = G[u][i];
        if(findcycle(v)) return true;
    }
    return false;
}

void vanishCycle(){
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(color[u] != 0) continue;
        id++;
        if(findcycle(u)){
            int cur = cycleHead;
            bool isAlone = true;
            while(1){
                if(indeg[cur]>1) isAlone = false;
                cur = G[cur][0];
                if(cur == cycleHead) break;
            }
            if(isAlone == false){
                mark(cycleHead);
            }
        }
    }
}

int main () {
    #ifdef forthright48
    freopen ( "input.txt", "r", stdin );
    /// freopen ( "output.txt", "w", stdout );
    #endif // forthright48

    scanf("%d",&N);
    CLR(deg, 0);
    CLR(vis, 0);
    CLR(color, 0);
    for(int i = 0;i<N;i++){
        int u, v;
        scanf("%d %d",&u,&v);
        if(u == v){
            continue;
        }
        RG[v].pb(u);
        G[u].pb(v);
        deg[u]++;
        indeg[v]++;
        List.pb(u);
        List.pb(v);
    }

    vanishCycle();
    //return 0;
    sort(ALL(List));
    UNIQUE(List);

    LL res = 1;
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] == 0) {
            LL ret = call(u) + 1;
            res = (res*ret)%mod;
            mark(u);
        }
    }

    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] != 0){
            res = (res*2LL)%mod;
            mark(u);
        }
    }

    cout << res << endl;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define ff first
#define ss second
#define MP make_pair
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define Set(N,cur) N=(N|(1LL<<cur))
#define Reset(N,cur) N=(N&(~(1LL<<cur)))
#define Check(N,cur) (!((N&(1LL<<cur))==0))
#define fast_cin ios_base::sync_with_stdio(false);cin.tie(NULL)
#define nl printf("\n")
#define phl cerr<<"hello\n"
#define arrayIndexPrint(A,i) cerr<<"@ At pos: "<<i<<" = "<<A[i]
#define dump(x) cerr<<"@ "<<#x<<" = "<<x<<endl
#define arrayPrint(A,st,ed) cerr<<"@ Array:";FOR(i,st,ed) cerr<<" "<<A[i];cerr<<endl
#define LINE cerr<<"\n"; FOR(i,0,50) cerr<<"=";cerr<<"\n\n"

#ifdef forthright48
     #include <ctime>
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
     #define debug(args...)  // Just strip off all debug tokens
     #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

#define LL long long
#define LLU long long unsigned int
typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < int, int > pii;
typedef pair < vlong, vlong > pll;

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0; x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1; r = r2 % r1;
        x = x2 - (q * x1); y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m;
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

inline int STRLEN(char *s){
    int p = 0; while(s[p]) p++; return p;
}

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
//int dir8[8][2] = {{-1,0},{0,1},{1,0},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}};

const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
const LL inf = 2147383647LL;
const LL mod = 1e9 + 7; /// CHANGE HERE
const int Size = 200005; /// CHANGE HERE

///=========================  TEMPLATE ENDS HERE  ========================///

int N;
int deg[Size];
int vis[Size];
int color[Size];
vector<int> RG[Size], G[Size];
int id = 0, cycleHead;

vector<int> List, self;

LL call(int u){
    LL res = SZ(RG[u]);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        res += call(v);
    }
    return res;
}

void mark(int u){
    vis[u] = 1;
    //debug("Mark: ",u);
    for(int i = 0;i<SZ(RG[u]);i++){
        int v = RG[u][i];
        if(!vis[v]) mark(v);
    }
}

bool findcycle(int u){
    if(color[u] == id){
        cycleHead = u;
        return true;
    }
    if(color[u] != 0) return false;
    color[u] = id;
    //debug("   Color: ",u," = ",id);
    for(int i = 0;i<SZ(G[u]);i++){
        int v = G[u][i];
        if(findcycle(v)) return true;
    }
    return false;
}

void vanishCycle(){
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(color[u] != 0) continue;
        id++;
        //debug("\nSTART CALL WITH: ",u);
        if(findcycle(u)){
            mark(cycleHead);
            //debug("FUCK YOU");
        }
    }
}

int main () {
    #ifdef forthright48
    freopen ( "input.txt", "r", stdin );
    /// freopen ( "output.txt", "w", stdout );
    #endif // forthright48

    scanf("%d",&N);
    CLR(deg, 0);
    CLR(vis, 0);
    CLR(color, 0);
    for(int i = 0;i<N;i++){
        int u, v;
        scanf("%d %d",&u,&v);
        if(u == v){
            continue;
        }
        RG[v].pb(u);
        G[u].pb(v);
        deg[u]++;
        List.pb(u);
        List.pb(v);
    }

    vanishCycle();
    //return 0;
    sort(ALL(List));
    UNIQUE(List);

    LL res = 1;
    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] == 0) {
            LL ret = call(u) + 1;
            res = (res*ret)%mod;
            mark(u);
        }
    }

    for(int i = 0;i<SZ(List);i++){
        int u = List[i];
        if(vis[u]) continue;
        if(deg[u] != 0){
            res = (res*2LL)%mod;
            mark(u);
        }
    }

    cout << res << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const int N = 2e5 + 10;
const int MOD = 1e9 + 7;

int n;
vector<int> par(N, -1);
bool mark[N], isCycle[N];
int root(int v){return par[v] < 0 ? v : (par[v] = root(par[v]));}
bool merge(int x, int y){
  if((x = root(x)) == (y = root(y)))return 0;
  if(par[y] < par[x])swap(x, y);
  par[x] += par[y];
  par[y] = x;
  return 1;
}

int main(){
  scanf("%d", &n);
  for(int i = 0; i < n; i++){
    int t1, t2;
    scanf("%d %d", &t1, &t2);
    t1--, t2--;
    if(t1 == t2)continue;
    if(!merge(t1, t2))
      mark[t1] = mark[t2] = 1;
  }
  for(int i = 0; i < n; i++)
    if(mark[i])
      isCycle[root(i)] = 1;
  int ans = 1;
  for(int i = 0; i < n; i++)
    if(par[i] < 0){
      if(isCycle[i])ans = (ans * 2 * 1LL) % MOD;
      else ans = (ans * 1LL * (-par[i])) % MOD;
    }
  printf("%d\n", ans);
  return 0;
}


#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const int N = 2e5 + 10;
const LL MOD = 1e9 + 7;

int n;
vector<int> par(N, -1);
bool mark[N], isCycle[N];
int root(int v){return par[v] < 0 ? v : (par[v] = root(par[v]));}
bool merge(int x, int y){
  if((x = root(x)) == (y = root(y)))return 0;
  if(par[y] < par[x])swap(x, y);
  par[x] += par[y];
  par[y] = x;
  return 1;
}

int main(){
  scanf("%d", &n);
  for(int i = 0; i < n; i++){
    int t1, t2;
    scanf("%d %d", &t1, &t2);
    t1--, t2--;
    if(t1 == t2)continue;
    if(!merge(t1, t2))
      mark[t1] = mark[t2] = 1;
  }
  for(int i = 0; i < n; i++)
    if(mark[i])
      isCycle[root(i)] = 1;
  int ans = 1;
  for(int i = 0; i < n; i++)
    if(par[i] < 0){
      if(isCycle[i])ans = (ans * 2 * 1LL) % MOD;
      else ans = (ans * 1LL * (-par[i])) % MOD;
    }
  printf("%d\n", ans);
  return 0;
}


#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const int N = 2e5 + 10;
const int MOD = 1e9 + 7;

int n;
vector<int> par(N, -1);
bool mark[N], isCycle[N];
int root(int v){return par[v] < 0 ? v : (par[v] = root(par[v]));}
bool merge(int x, int y){
  if((x = root(x)) == (y = root(y)))return 0;
  if(par[y] < par[x])swap(x, y);
  par[x] += par[y];
  par[y] = x;
  return 1;
}

int main(){
  scanf("%d", &n);
  for(int i = 0; i < n; i++){
    int t1, t2;
    scanf("%d %d", &t1, &t2);
    t1--, t2--;
    if(t1 == t2)continue;
    if(!merge(t1, t2))
      mark[t1] = mark[t2] = 1;
  }
  for(int i = 0; i < n; i++)
    if(mark[i])
      isCycle[root(i)] = 1;
  int ans = 1;
  for(int i = 0; i < n; i++)
    if(par[i] < 0){
      printf("%d %d %d\n", i, -par[i], isCycle[i]);
      if(isCycle[i])ans = (ans * 2 * 1LL) % MOD;
      else ans = (ans * 1LL * (-par[i])) % MOD;
    }
  printf("%d\n", ans);
  return 0;
}


#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const int N = 2e5 + 10;
const LL MOD = 1e9 + 7;

int n;
vector<int> par(N, -1);
bool isCycle[N];
int mark[N];
int root(int v){return par[v] < 0 ? v : (par[v] = root(par[v]));}
bool merge(int x, int y){
  if((x = root(x)) == (y = root(y)))return 0;
  if(par[y] < par[x])swap(x, y);
  par[x] += par[y];
  par[y] = x;
  return 1;
}

int main(){
  scanf("%d", &n);
  for(int i = 0; i < n; i++){
    int t1, t2;
    scanf("%d %d", &t1, &t2);
    t1--, t2--;
    if(t1 == t2){mark[t1] = 2;continue;}
    if(!merge(t1, t2))
      mark[t1] = mark[t2] = 1;
  }
  for(int i = 0; i < 2 * n; i++){
    if(mark[i] == 1)
      isCycle[root(i)] = 1;
    else if(mark[i] == 2)
      mark[root(i)] = 2;
  }
  int ans = 1;
  for(int i = 0; i < 2 * n; i++)
    if(par[i] < 0){
      if(isCycle[i])ans = (ans * 1LL * 2) % MOD;
      else if(!mark[i])ans = (ans * 1LL * (-par[i])) % MOD;
    }
  printf("%d\n", ans);
  return 0;
}


#include <bits/stdc++.h>

using namespace std;
using LL = long long;

const int N = 2e5 + 10;
const LL MOD = 1e9 + 7;

int n;
vector<int> par(N, -1);
bool mark[N], isCycle[N];
int root(int v){return par[v] < 0 ? v : (par[v] = root(par[v]));}
bool merge(int x, int y){
  if((x = root(x)) == (y = root(y)))return 0;
  if(par[y] < par[x])swap(x, y);
  par[x] += par[y];
  par[y] = x;
  return 1;
}

int main(){
  scanf("%d", &n);
  for(int i = 0; i < n; i++){
    int t1, t2;
    scanf("%d %d", &t1, &t2);
    t1--, t2--;
    if(t1 == t2)continue;
    if(!merge(t1, t2))
      mark[t1] = mark[t2] = 1;
  }
  for(int i = 0; i < 2 * n; i++)
    if(mark[i])
      isCycle[root(i)] = 1;
  int ans = 1;
  for(int i = 0; i < 2 * n; i++)
    if(par[i] < 0){
      if(isCycle[i])ans = (ans * 2 * 1LL) % MOD;
      else ans = (ans * 1LL * (-par[i])) % MOD;
    }
  printf("%d\n", ans);
  return 0;
}


#include <array>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cassert>
#include <random>
#include <climits>
#include <stack>
#include <set>

using namespace std;

typedef long long ll;
typedef long double ld;

const int MAXN = 100005 * 2;
const ll modulo = 1000000007;

int n;

vector<int> g[MAXN];
vector<int> gt[MAXN];
bool circle_used[MAXN];
bool used[MAXN];

vector<int> path;
set<int> st_path;

vector<int> circle_sizes;

void find_and_delete_circles(int v) {
    used[v] = true;
    path.push_back(v);
    st_path.insert(v);

    for (int to : g[v]) {
        if (!used[to]) {
            find_and_delete_circles(to);
        }
        else {
            if (st_path.find(to) == st_path.end())
                continue;

            int circle_size = 0;
            //! cicle detected
            for (size_t i = path.size() - 1; path[i] != to; --i) {
                circle_used[path[i]] = true;
                ++circle_size;
            }

            ++circle_size;
            circle_used[to] = true;

            circle_sizes.push_back(2);
        }
    }

    st_path.erase(v);
    path.pop_back();
}

int final_dfs(int v) {
    used[v] = true;

    int ans = 1;
    for (int to : g[v]) {
        if (circle_used[to])
            return -1;

        if (!used[to] && !circle_used[to]) {
            int t = final_dfs(to);
            if (t == -1)
                return -1;

            ans += t;
        }
    }

    for (int to : gt[v]) {
        if (circle_used[to])
            return -1;

        if (!used[to] && !circle_used[to]) {
            int t = final_dfs(to);
            if (t == -1)
                return -1;

            ans += t;
        }
    }

    return ans;
}

int main() {
    ios::sync_with_stdio(0);
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    cin >> n;
    for (int i = 0; i < n; ++i) {
        int x, y;
        cin >> x >> y;

        g[x].push_back(y);
        gt[y].push_back(x);
    }

    for (int i = 1; i < MAXN; ++i) {
        if (!used[i])
            find_and_delete_circles(i);
    }

    memset(used, 0, sizeof(used));

    for (int i = 1; i < MAXN; ++i) {
        if (!used[i] && !circle_used[i]) {
            int t = final_dfs(i);

            if (t == -1) {
                continue;
            }

            circle_sizes.push_back(t);
        }
    }

    ll ans = 1;
    for (int x : circle_sizes) {
        ans = ans * x % modulo;
    }

    cout << ans;

    return 0;
}