import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class E
{
    private static int MOD;
    public static void main(String [] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter writer = new PrintWriter(System.out);

        StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
        int n = Integer.parseInt(tokenizer.nextToken());
        int m = Integer.parseInt(tokenizer.nextToken());
        MOD = Integer.parseInt(tokenizer.nextToken());

        ArrayList<Integer> [] dag = new ArrayList[n];
        for(int i = 0 ; i < n ; i++)
            dag[i] = new ArrayList<Integer>();

        int [] inDegree = new int[n];
        int [] outDegree = new int[n];
        for(int i = 0 ; i < m ; i++)
        {
            tokenizer = new StringTokenizer(reader.readLine());
            int a = Integer.parseInt(tokenizer.nextToken()) - 1;
            int b = Integer.parseInt(tokenizer.nextToken()) - 1;
            outDegree[a]++;
            inDegree[b]++;

            dag[a].add(b);
        }

        int k = 0;
        for(int i = 0 ; i < n ; i++)
            if(inDegree[i] == 0 && outDegree[i] != 0)
                k++;

        int [] sinks = new int[k];
        int pSink = 0;
        int [] sources = new int[k];
        int pSource = 0;

        for(int i = 0 ; i < n ; i++)
        {
            if(inDegree[i] == 0 && outDegree[i] != 0)
                sources[pSource++] = i;
            if(inDegree[i] != 0 && outDegree[i] == 0)
                sinks[pSink++] = i;
        }

        int [][] matrix = new int[k][k];
        for(int i = 0 ; i < k ; i++)
        {
            int [] calc = new int[n];
            calc[sources[i]] = 1;
            Queue<Integer> queue = new ArrayDeque<Integer>();
            queue.offer(sources[i]);

            while(!queue.isEmpty())
            {
                int at = queue.poll();
                for(int to : dag[at])
                {
                    calc[to] += calc[at];
                    if(calc[to] >= MOD)
                        calc[to] -= MOD;
                }
            }

            for(int j = 0 ; j < k ; j++)
                matrix[i][j] = calc[sinks[j]];
        }

        int det = determinant(matrix);

        int sign = 1;
        for(int i = 0 ; i < n ; i++)
            if(outDegree[i] == 0 && inDegree[i] == 0)
            {
                int row = Arrays.binarySearch(sources, i);
                row = -row-1;

                int col = Arrays.binarySearch(sinks, i);
                col = -col-1;

                if((row+col)%2 != 0)
                    sign *= -1;
            }

        det *= sign;
        det += MOD;
        det %= MOD;
        writer.println(det);
        writer.flush();
        writer.close();
    }

    private static int determinant(int [][] matrix)
    {
        int n = matrix.length;

        //row echelon form
        int sign = 1;
        for(int i = 0 ; i < matrix.length ; i++)
        {
            int nonZero = 0;
            while(nonZero < n && matrix[nonZero][i] == 0)
                nonZero++;

            if(nonZero == n)
                return 0;

            if(nonZero != i)
                sign *= -1;

            for(int j = 0 ; j < n ; j++)
            {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[nonZero][j];
                matrix[nonZero][j] = temp;
            }

            for(int j = 0 ; j < i ; j++)
            {
                int coef = power(matrix[j][j], MOD-2);
                coef = (int)((1L*coef*matrix[i][j])%MOD);

                for(int k = j ; k < n ; k++)
                {
                    matrix[i][k] = (int)((matrix[i][k] - 1L*matrix[j][k]*coef)%MOD);
                    matrix[i][k] += MOD;
                    matrix[i][k] %= MOD;
                }
            }
        }

        long det = 1;
        for(int i = 0 ; i < n ; i++)
        {
            det *= matrix[i][i];
            det %= MOD;
        }

        det *= sign;
        det += MOD;
        det %= MOD;
        return (int) det;
    }

    private static int power(int a, int b)
    {
        if(b == 0)
            return 1;
        if(b%2 == 1)
            return (int)((1L*a*power(a, b-1))%MOD);

        long res = power(a, b/2);
        res *= res;
        res %= MOD;
        return (int) res;
    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.LinkedList;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.util.Queue;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyScanner in = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.  close();
    }
}

class TaskE {
    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int k=0;
        int n = in.nextInt(),m=in.nextInt(),p=in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; i++){
            vs[i] = new Vertex(i);
        }
        int[] inDeg = new int[n],outDeg = new int[n];
        for (int i = 0; i < m; i++) {
            int s = in.nextInt()-1,t=in.nextInt()-1;
            vs[s].add(new Edge(vs[t]));
            outDeg[s]++;
            inDeg[t]++;
        }
        for (int i = 0; i < n; i++) {
            if(inDeg[i]==0)k++;
        }
        int[] source=new int[k];
        int[] sink = new int[k];
        for (int i = 0,i1=0,i2=0; i < n; i++) {
            if(inDeg[i]==0)source[i1++] = i;
            if(outDeg[i]==0)sink[i2++] = i;
        }
        vs = SparseGraph.topologicalSort(vs);
        long[][] A = new long[k][k];
        for (int i = 0; i < k; i++) {
            long[] ways = new long[n];
            ways[source[i]] = 1;
            for(Vertex v:vs){
                for(Edge nxt : v){
                    int nId = nxt.to.id;
                    ways[nId] += ways[v.id];
                    if(ways[nId]>=p)ways[nId] -= p;
                }
            }
            for(int j=0;j<k;j++){
                A[i][j] = ways[sink[j]];
            }
        }
        long res = Matrix.determinantDestructive(A,p);
        out.println(res);
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
        try{
            int c=in.read();
            if(c==-1) return c;
            while(c!='-'&&(c<'0'||'9'<c)){
                c=in.read();
                if(c==-1) return c;
            }
            if(c=='-') return -nextInt();
            int res=0;
            do{
                res*=10;
                res+=c-'0';
                c=in.read();
            }while('0'<=c&&c<='9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    }

class Vertex extends ArrayList<Edge>{
    public final int id;
    public Vertex(int id){
        this.id=id;
    }
    }

class Edge {
    public Vertex to;

    public Edge(Vertex to) {
        this.to = to;
    }
}

class SparseGraph {
//    public static<E extends UnusedEdge<E>> UnusedVertex<E>[][] connectedComponents(UnusedVertex<E>[] undirectedGraph){
//        UnusedVertex<E>[] vs = undirectedGraph;
//        for(UnusedVertex<E> v:vs)v.used=false;
//        List<UnusedVertex<E>[]> lists = new ArrayList<UnusedVertex<E>[]>();
//        for(UnusedVertex<E> v:vs)if(!v.used){
//            List<UnusedVertex<E>> list = new ArrayList<UnusedVertex<E>>();
//            Queue<UnusedVertex<E>> que = new LinkedList<UnusedVertex<E>>();
//            que.offer(v);
//            v.used = true;
//            while(!que.isEmpty()){
//                UnusedVertex<E> cur = que.poll();
//                list.add(cur);
//                for(E edge : cur){
//                    UnusedVertex<E> nxt = edge.to;
//                    if(!nxt.used){
//                        que.offer(nxt);
//                        nxt.used=true;
//                    }
//                }
//            }
//            lists.add(list.toArray(ArrayUtils.createArray(0,vs[0])));
//        }
//        return lists.toArray(ArrayUtils.createArray(0,vs));
//    }

    //    public static<V extends UnusedVertex<? extends E>,E extends UnusedEdge> UnusedVertex[] constructUndirectedGraph(int vertexCount,int[] from,int[] to,VertexFactory<V,E> vertexFactory,UnusedEdgeFactory<E> edgeFactory) {
//        V[] vs = ArrayUtils.createArray(vertexCount,vertexFactory.create(0));
//        for(int i=0;i<vertexCount;i++)vs[i] = vertexFactory.create(i);
//        for(int i=0;i<from.length;i++){
//            V s = vs[from[i]];
//            V t = vs[to[i]];
//            s.add(edgeFactory.create(s,t));
//            t.add(edgeFactory.create(t,s));
//        }
//        return vs;
//    }

//    public static UnusedVertex<SimpleUnusedEdge>[] readUndirectedGraph(MyScanner in, int vertexCount, int edgeCount, boolean decreaseByOne){
//        return readUndirectedGraph(in, vertexCount, edgeCount, decreaseByOne, VertexFactory.PLAIN, UnusedEdgeFactory.PLAIN);
//    }

//    public static<V extends UnusedVertex<E>,E extends UnusedEdge<E>> V[] readUndirectedGraph(MyScanner in, int vertexCount, int edgeCount, boolean decreaseByOne, VertexFactory<V,E> vertexFactory, UnusedEdgeFactory<E> edgeFactory) {
//        int[] from = new int[edgeCount];
//        int[] to=new int[edgeCount];
//        in.readArrays(from, to);
//        if(decreaseByOne)ArrayUtils.decreaseByOne(from, to);
//        return SparseGraph.constructUndirectedGraph(vertexCount, from, to,vertexFactory,edgeFactory);
//    }

    private static int topologicalSortN;
    public static Vertex[] topologicalSort(Vertex[] vs){
        topologicalSortN = vs.length;
        int[] states = new int[topologicalSortN];
        Vertex[] us = new Vertex[topologicalSortN];
        for(Vertex v:vs){
            if(states[v.id]==0 && !topologicalSortDfs(v,us,states))return null;
        }
        return us;
    }
    private static boolean topologicalSortDfs(Vertex v, Vertex[] us,int[] states) {
        states[v.id] = 1;
        for(Edge u:v){
            if(states[u.to.id]==1 || states[u.to.id]==0 && !topologicalSortDfs(u.to,us,states))return false;
        }
        us[--topologicalSortN] = v;
        states[v.id] = 2;
        return true;
    }
}

class Matrix {

    public static int determinantDestructive(long[][] A, int modPrime) {
        int n = A.length;
        long res = 1;
        for (int i = 0; i < n; i++) {
            int pivot = i;
            for (int j = i; j < n; j++) {
                if (Math.abs(A[j][i]) > Math.abs(A[pivot][i])) {
                    pivot = j;
                }
            }
            // rank < n
            if (A[pivot][i] == 0) return 0;
            if(i!=pivot){
                ArrayUtils.swap(A, i, pivot);
                res = -res;
                if(res<0)res += modPrime;
            }
            res = res * A[i][i] % modPrime;
            for (int j = i + 1; j < n; j++) {
                long mul = A[j][i] * MathUtils.inverse(A[i][i],modPrime) % modPrime;
                for (int k = i; k < n; k++) {
                    A[j][k] -= A[i][k] * mul % modPrime;
                    if(A[j][k] < 0)A[j][k] += modPrime;
                }
            }
        }
        return (int) res;
    }
}

class ArrayUtils {

    public static <T> void swap(T[] vs, int i, int j) {
        T tmp = vs[i];
        vs[i] = vs[j];
        vs[j] = tmp;
    }

    }

class MathUtils {

    public static long powMod(long value, long exponent, int modulo) {
        if(modulo==1)return 0;
        if(value >= modulo) value %= modulo;
        long res = 1;
        while(exponent>0){
            if((exponent&1)==1){
                res = res * value % modulo;
            }
            value = value * value % modulo;
            exponent >>= 1;
        }
        return res;
    }

    public static long inverse(long value, int modPrime) {
        return powMod(value,modPrime-2,modPrime);
    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyScanner in = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int k=0;
        int n = in.nextInt(),m=in.nextInt(),p=in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; i++){
            vs[i] = new Vertex(i);
        }
        int[] inDeg = new int[n],outDeg = new int[n];
        for (int i = 0; i < m; i++) {
            int s = in.nextInt()-1,t=in.nextInt()-1;
            vs[s].add(new Edge(vs[t]));
            outDeg[s]++;
            inDeg[t]++;
        }
        for (int i = 0; i < n; i++) {
            if(inDeg[i]==0)k++;
        }
        int[] source=new int[k];
        int[] sink = new int[k];
        for (int i = 0,i1=0,i2=0; i < n; i++) {
            if(inDeg[i]==0)source[i1++] = i;
            if(outDeg[i]==0)sink[i2++] = i;
        }
        long[][] A = new long[k][k];
        for (int i = 0; i < k; i++) {
            int[] ways = new int[n];
            Arrays.fill(ways,-1);
            for (int j = 0; j < k; j++)
                ways[sink[j]] = j==i ? 1 : 0;
            for (int j = 0; j < k; j++)
                A[j][i] = dfs(vs[source[j]],ways);
        }
        long res = Matrix.determinantDestructive(A,p);
        out.println(res);
    }

    private int dfs(Vertex cur, int[] ways) {
        if(ways[cur.id]>=0)return ways[cur.id];
        int res = 0;
        for(Edge e:cur)res += dfs(e.to,ways);
        return res;
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
        try{
            int c=in.read();
            if(c==-1) return c;
            while(c!='-'&&(c<'0'||'9'<c)){
                c=in.read();
                if(c==-1) return c;
            }
            if(c=='-') return -nextInt();
            int res=0;
            do{
                res*=10;
                res+=c-'0';
                c=in.read();
            }while('0'<=c&&c<='9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    }

class Vertex extends ArrayList<Edge>{
    public final int id;
    public Vertex(int id){
        this.id=id;
    }
    }

class Edge {
    public Vertex to;

    public Edge(Vertex to) {
        this.to = to;
    }
}

class Matrix {

    public static int determinantDestructive(long[][] A, int modPrime) {
        int n = A.length;
        long res = 1;
        for (int i = 0; i < n; i++) {
            int pivot = i;
            for (int j = i; j < n; j++) {
                if (Math.abs(A[j][i]) > Math.abs(A[pivot][i])) {
                    pivot = j;
                }
            }
            // rank < n
            if (A[pivot][i] == 0) return 0;
            if(i!=pivot){
                ArrayUtils.swap(A, i, pivot);
                res = -res;
                if(res<0)res += modPrime;
            }
            res = res * A[i][i] % modPrime;
            long inv = MathUtils.inverse(A[i][i],modPrime);
            for (int j = i + 1; j < n; j++) {
                long mul = A[j][i] * inv % modPrime;
                for (int k = i; k < n; k++) {
                    A[j][k] -= A[i][k] * mul % modPrime;
                    if(A[j][k] < 0)A[j][k] += modPrime;
                }
            }
        }
        return (int) res;
    }
}

class ArrayUtils {

    public static <T> void swap(T[] vs, int i, int j) {
        T tmp = vs[i];
        vs[i] = vs[j];
        vs[j] = tmp;
    }

    }

class MathUtils {

    public static long powMod(long value, long exponent, int modulo) {
        if(modulo==1)return 0;
        if(value >= modulo) value %= modulo;
        long res = 1;
        while(exponent>0){
            if((exponent&1)==1){
                res = res * value % modulo;
            }
            value = value * value % modulo;
            exponent >>= 1;
        }
        return res;
    }

    public static long inverse(long value, int modPrime) {
        return powMod(value,modPrime-2,modPrime);
    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyScanner in = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int k=0;
        int n = in.nextInt(),m=in.nextInt(),p=in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; i++){
            vs[i] = new Vertex(i);
        }
        int[] inDeg = new int[n],outDeg = new int[n];
        for (int i = 0; i < m; i++) {
            int s = in.nextInt()-1,t=in.nextInt()-1;
            vs[s].add(new Edge(vs[t]));
            outDeg[s]++;
            inDeg[t]++;
        }
        for (int i = 0; i < n; i++) {
            if(inDeg[i]==0)k++;
        }
        int[] source=new int[k];
        int[] sink = new int[k];
        for (int i = 0,i1=0,i2=0; i < n; i++) {
            if(inDeg[i]==0)source[i1++] = i;
            if(outDeg[i]==0)sink[i2++] = i;
        }
        long[][] A = new long[k][k];
        for (int i = 0; i < k; i++) {
            int[] ways = new int[n];
            Arrays.fill(ways,-1);
            for (int j = 0; j < k; j++)
                ways[sink[j]] = j==i ? 1 : 0;
            for (int j = 0; j < k; j++)
                A[j][i] = dfs(vs[source[j]],ways,p);
        }
        long res = Matrix.determinantDestructive(A,p);
        out.println(res);
    }

    private int dfs(Vertex cur, int[] ways,int modulus) {
        if(ways[cur.id]>=0)return ways[cur.id];
        int res = 0;
        for(Edge e:cur){
            res += dfs(e.to,ways,modulus);
            if(res >= modulus)res -= modulus;
        }
        ways[cur.id] = res;
        return res;
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
        try{
            int c=in.read();
            if(c==-1) return c;
            while(c!='-'&&(c<'0'||'9'<c)){
                c=in.read();
                if(c==-1) return c;
            }
            if(c=='-') return -nextInt();
            int res=0;
            do{
                res*=10;
                res+=c-'0';
                c=in.read();
            }while('0'<=c&&c<='9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    }

class Vertex extends ArrayList<Edge>{
    public final int id;
    public Vertex(int id){
        this.id=id;
    }
    }

class Edge {
    public Vertex to;

    public Edge(Vertex to) {
        this.to = to;
    }
}

class Matrix {

    public static int determinantDestructive(long[][] A, int modPrime) {
        int n = A.length;
        long res = 1;
        for (int i = 0; i < n; i++) {
            int pivot = i;
            for (int j = i; j < n; j++) {
                if (Math.abs(A[j][i]) > Math.abs(A[pivot][i])) {
                    pivot = j;
                }
            }
            // rank < n
            if (A[pivot][i] == 0) return 0;
            if(i!=pivot){
                ArrayUtils.swap(A, i, pivot);
                res = -res;
                if(res<0)res += modPrime;
            }
            res = res * A[i][i] % modPrime;
            long inv = MathUtils.inverse(A[i][i],modPrime);
            for (int j = i + 1; j < n; j++) {
                long mul = A[j][i] * inv % modPrime;
                for (int k = i; k < n; k++) {
                    A[j][k] -= A[i][k] * mul % modPrime;
                    if(A[j][k] < 0)A[j][k] += modPrime;
                }
            }
        }
        return (int) res;
    }
}

class ArrayUtils {

    public static <T> void swap(T[] vs, int i, int j) {
        T tmp = vs[i];
        vs[i] = vs[j];
        vs[j] = tmp;
    }

    }

class MathUtils {

    public static long powMod(long value, long exponent, int modulo) {
        if(modulo==1)return 0;
        if(value >= modulo) value %= modulo;
        long res = 1;
        while(exponent>0){
            if((exponent&1)==1){
                res = res * value % modulo;
            }
            value = value * value % modulo;
            exponent >>= 1;
        }
        return res;
    }

    public static long inverse(long value, int modPrime) {
        return powMod(value,modPrime-2,modPrime);
    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.LinkedList;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.util.Queue;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyScanner in = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int k=0;
        int n = in.nextInt(),m=in.nextInt(),p=in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; i++){
            vs[i] = new Vertex(i);
        }
        int[] inDeg = new int[n],outDeg = new int[n];
        for (int i = 0; i < m; i++) {
            int s = in.nextInt()-1,t=in.nextInt()-1;
            vs[s].add(new Edge(vs[t]));
            outDeg[s]++;
            inDeg[t]++;
        }
        for (int i = 0; i < n; i++) {
            if(inDeg[i]==0)k++;
        }
        int[] source=new int[k];
        int[] sink = new int[k];
        for (int i = 0,i1=0,i2=0; i < n; i++) {
            if(inDeg[i]==0)source[i1++] = i;
            if(outDeg[i]==0)sink[i2++] = i;
        }
        vs = SparseGraph.topologicalSort(vs);
        long[][] A = new long[k][k];
        for (int i = 0; i < k; i++) {
            long[] ways = new long[n];
            ways[source[i]] = 1;
            for(Vertex v:vs){
                for(Edge nxt : v){
                    int nId = nxt.to.id;
                    ways[nId] += ways[v.id];
                    if(ways[nId]>=p)ways[nId] -= p;
                }
            }
            for(int j=0;j<k;j++){
                A[i][j] = ways[sink[j]];
            }
        }
        long res = Matrix.determinantDestructive(A,p);
        out.println(res);
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
        try{
            int c=in.read();
            if(c==-1) return c;
            while(c!='-'&&(c<'0'||'9'<c)){
                c=in.read();
                if(c==-1) return c;
            }
            if(c=='-') return -nextInt();
            int res=0;
            do{
                res*=10;
                res+=c-'0';
                c=in.read();
            }while('0'<=c&&c<='9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    }

class Vertex extends ArrayList<Edge>{
    public final int id;
    public Vertex(int id){
        this.id=id;
    }
    }

class Edge {
    public Vertex to;

    public Edge(Vertex to) {
        this.to = to;
    }
}

class SparseGraph {
//    public static<E extends UnusedEdge<E>> UnusedVertex<E>[][] connectedComponents(UnusedVertex<E>[] undirectedGraph){
//        UnusedVertex<E>[] vs = undirectedGraph;
//        for(UnusedVertex<E> v:vs)v.used=false;
//        List<UnusedVertex<E>[]> lists = new ArrayList<UnusedVertex<E>[]>();
//        for(UnusedVertex<E> v:vs)if(!v.used){
//            List<UnusedVertex<E>> list = new ArrayList<UnusedVertex<E>>();
//            Queue<UnusedVertex<E>> que = new LinkedList<UnusedVertex<E>>();
//            que.offer(v);
//            v.used = true;
//            while(!que.isEmpty()){
//                UnusedVertex<E> cur = que.poll();
//                list.add(cur);
//                for(E edge : cur){
//                    UnusedVertex<E> nxt = edge.to;
//                    if(!nxt.used){
//                        que.offer(nxt);
//                        nxt.used=true;
//                    }
//                }
//            }
//            lists.add(list.toArray(ArrayUtils.createArray(0,vs[0])));
//        }
//        return lists.toArray(ArrayUtils.createArray(0,vs));
//    }

    //    public static<V extends UnusedVertex<? extends E>,E extends UnusedEdge> UnusedVertex[] constructUndirectedGraph(int vertexCount,int[] from,int[] to,VertexFactory<V,E> vertexFactory,UnusedEdgeFactory<E> edgeFactory) {
//        V[] vs = ArrayUtils.createArray(vertexCount,vertexFactory.create(0));
//        for(int i=0;i<vertexCount;i++)vs[i] = vertexFactory.create(i);
//        for(int i=0;i<from.length;i++){
//            V s = vs[from[i]];
//            V t = vs[to[i]];
//            s.add(edgeFactory.create(s,t));
//            t.add(edgeFactory.create(t,s));
//        }
//        return vs;
//    }

//    public static UnusedVertex<SimpleUnusedEdge>[] readUndirectedGraph(MyScanner in, int vertexCount, int edgeCount, boolean decreaseByOne){
//        return readUndirectedGraph(in, vertexCount, edgeCount, decreaseByOne, VertexFactory.PLAIN, UnusedEdgeFactory.PLAIN);
//    }

//    public static<V extends UnusedVertex<E>,E extends UnusedEdge<E>> V[] readUndirectedGraph(MyScanner in, int vertexCount, int edgeCount, boolean decreaseByOne, VertexFactory<V,E> vertexFactory, UnusedEdgeFactory<E> edgeFactory) {
//        int[] from = new int[edgeCount];
//        int[] to=new int[edgeCount];
//        in.readArrays(from, to);
//        if(decreaseByOne)ArrayUtils.decreaseByOne(from, to);
//        return SparseGraph.constructUndirectedGraph(vertexCount, from, to,vertexFactory,edgeFactory);
//    }

    private static int topologicalSortN;
    public static Vertex[] topologicalSort(Vertex[] vs){
        topologicalSortN = vs.length;
        int[] states = new int[topologicalSortN];
        Vertex[] us = new Vertex[topologicalSortN];
        for(Vertex v:vs){
            if(states[v.id]==0 && !topologicalSortDfs(v,us,states))return null;
        }
        return us;
    }
    private static boolean topologicalSortDfs(Vertex v, Vertex[] us,int[] states) {
        states[v.id] = 1;
        for(Edge u:v){
            if(states[u.to.id]==1 || states[u.to.id]==0 && !topologicalSortDfs(u.to,us,states))return false;
        }
        us[--topologicalSortN] = v;
        states[v.id] = 2;
        return true;
    }
}

class Matrix {

    public static int determinantDestructive(long[][] A, int modPrime) {
        int n = A.length;
        long res = 1;
        for (int i = 0; i < n; i++) {
            int pivot = i;
            for (int j = i; j < n; j++) {
                if (Math.abs(A[j][i]) > Math.abs(A[pivot][i])) {
                    pivot = j;
                }
            }
            // rank < n
            if (A[pivot][i] == 0) return 0;
            if(i!=pivot){
                ArrayUtils.swap(A, i, pivot);
                res = -res;
                if(res<0)res += modPrime;
            }
            res = res * A[i][i] % modPrime;
            for (int j = i + 1; j < n; j++) {
                long mul = A[j][i] * MathUtils.inverse(A[i][i],modPrime) % modPrime;
                for (int k = i; k < n; k++) {
                    A[j][k] -= A[i][k] * mul % modPrime;
                    if(A[j][k] < 0)A[j][k] += modPrime;
                }
            }
        }
        return (int) res;
    }
}

class ArrayUtils {

    public static <T> void swap(T[] vs, int i, int j) {
        T tmp = vs[i];
        vs[i] = vs[j];
        vs[j] = tmp;
    }

    }

class MathUtils {

    public static long powMod(long value, long exponent, int modulo) {
        if(modulo==1)return 0;
        if(value >= modulo) value %= modulo;
        long res = 1;
        while(exponent>0){
            if((exponent&1)==1){
                res = res * value % modulo;
            }
            value = value * value % modulo;
            exponent >>= 1;
        }
        return res;
    }

    public static long inverse(long value, int modPrime) {
        return powMod(value,modPrime-2,modPrime);
    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyScanner in = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int k=0;
        int n = in.nextInt(),m=in.nextInt(),p=in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; i++){
            vs[i] = new Vertex(i);
        }
        int[] inDeg = new int[n],outDeg = new int[n];
        for (int i = 0; i < m; i++) {
            int s = in.nextInt()-1,t=in.nextInt()-1;
            vs[s].add(new Edge(vs[t]));
            outDeg[s]++;
            inDeg[t]++;
        }
        for (int i = 0; i < n; i++) {
            if(inDeg[i]==0 && outDeg[i]>0)k++;
        }
        int[] source=new int[k];
        int[] sink = new int[k];
        long res = 1;
        for (int i = 0,i1=0,i2=0; i < n; i++) {
            if(inDeg[i]==0 && outDeg[i]>0)source[i1++] = i;
            if(outDeg[i]==0 && inDeg[i]>0)sink[i2++] = i;
            if(inDeg[i]==0 && outDeg[i]==0)res *= (i1+i2)%2==0 ? 1 : -1;
        }
        long[][] A = new long[k][k];
        for (int i = 0; i < k; i++) {
            int[] ways = new int[n];
            Arrays.fill(ways, -1);
            for (int j = 0; j < k; j++)
                ways[sink[j]] = j==i ? 1 : 0;
            for (int j = 0; j < k; j++)
                A[j][i] = dfs(vs[source[j]],ways,p);
        }
        res *= Matrix.determinantDestructive(A, p);
        if(res<0)res += p;
        out.println(res);
    }

    private int dfs(Vertex cur, int[] ways,int modulus) {
        if(ways[cur.id]>=0)return ways[cur.id];
        int res = 0;
        for(Edge e:cur){
            res += dfs(e.to,ways,modulus);
            if(res >= modulus)res -= modulus;
        }
        ways[cur.id] = res;
        return res;
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
        try{
            int c=in.read();
            if(c==-1) return c;
            while(c!='-'&&(c<'0'||'9'<c)){
                c=in.read();
                if(c==-1) return c;
            }
            if(c=='-') return -nextInt();
            int res=0;
            do{
                res*=10;
                res+=c-'0';
                c=in.read();
            }while('0'<=c&&c<='9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    }

class Vertex extends ArrayList<Edge>{
    public final int id;
    public Vertex(int id){
        this.id=id;
    }
    }

class Edge {
    public Vertex to;

    public Edge(Vertex to) {
        this.to = to;
    }
}

class Matrix {

    public static int determinantDestructive(long[][] A, int modPrime) {
        int n = A.length;
        long res = 1;
        for (int i = 0; i < n; i++) {
            int pivot = i;
            for (int j = i; j < n; j++) {
                if (Math.abs(A[j][i]) > Math.abs(A[pivot][i])) {
                    pivot = j;
                }
            }
            // rank < n
            if (A[pivot][i] == 0) return 0;
            if(i!=pivot){
                ArrayUtils.swap(A, i, pivot);
                res = -res;
                if(res<0)res += modPrime;
            }
            res = res * A[i][i] % modPrime;
            long inv = MathUtils.inverse(A[i][i],modPrime);
            for (int j = i + 1; j < n; j++) {
                long mul = A[j][i] * inv % modPrime;
                for (int k = i; k < n; k++) {
                    A[j][k] -= A[i][k] * mul % modPrime;
                    if(A[j][k] < 0)A[j][k] += modPrime;
                }
            }
        }
        return (int) res;
    }
}

class ArrayUtils {

    public static <T> void swap(T[] vs, int i, int j) {
        T tmp = vs[i];
        vs[i] = vs[j];
        vs[j] = tmp;
    }

    }

class MathUtils {

    public static long powMod(long value, long exponent, int modulo) {
        if(modulo==1)return 0;
        if(value >= modulo) value %= modulo;
        long res = 1;
        while(exponent>0){
            if((exponent&1)==1){
                res = res * value % modulo;
            }
            value = value * value % modulo;
            exponent >>= 1;
        }
        return res;
    }

    public static long inverse(long value, int modPrime) {
        return powMod(value,modPrime-2,modPrime);
    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.LinkedList;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.util.Queue;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyScanner in = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int k=0;
        int n = in.nextInt(),m=in.nextInt(),p=in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; i++){
            vs[i] = new Vertex(i);
        }
        int[] inDeg = new int[n],outDeg = new int[n];
        for (int i = 0; i < m; i++) {
            int s = in.nextInt()-1,t=in.nextInt()-1;
            vs[s].add(new Edge(vs[t]));
            outDeg[s]++;
            inDeg[t]++;
        }
        for (int i = 0; i < n; i++) {
            if(inDeg[i]==0)k++;
        }
        int[] source=new int[k];
        int[] sink = new int[k];
        for (int i = 0,i1=0,i2=0; i < n; i++) {
            if(inDeg[i]==0)source[i1++] = i;
            if(outDeg[i]==0)sink[i2++] = i;
        }
        vs = SparseGraph.topologicalSort(vs);
        long[][] A = new long[k][k];
        for (int i = 0; i < k; i++) {
            long[] ways = new long[n];
            ways[source[i]] = 1;
            for(Vertex v:vs){
                for(Edge nxt : v){
                    int nId = nxt.to.id;
                    ways[nId] += ways[v.id];
                    if(ways[nId]>=p)ways[nId] -= p;
                }
            }
            for(int j=0;j<k;j++){
                A[i][j] = ways[sink[j]];
            }
        }
        long res = Matrix.determinantDestructive(A,p);
        out.println(res);
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
        try{
            int c=in.read();
            if(c==-1) return c;
            while(c!='-'&&(c<'0'||'9'<c)){
                c=in.read();
                if(c==-1) return c;
            }
            if(c=='-') return -nextInt();
            int res=0;
            do{
                res*=10;
                res+=c-'0';
                c=in.read();
            }while('0'<=c&&c<='9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    }

class Vertex extends ArrayList<Edge>{
    public final int id;
    public Vertex(int id){
        this.id=id;
    }
    }

class Edge {
    public Vertex to;

    public Edge(Vertex to) {
        this.to = to;
    }
}

class SparseGraph {
//    public static<E extends UnusedEdge<E>> UnusedVertex<E>[][] connectedComponents(UnusedVertex<E>[] undirectedGraph){
//        UnusedVertex<E>[] vs = undirectedGraph;
//        for(UnusedVertex<E> v:vs)v.used=false;
//        List<UnusedVertex<E>[]> lists = new ArrayList<UnusedVertex<E>[]>();
//        for(UnusedVertex<E> v:vs)if(!v.used){
//            List<UnusedVertex<E>> list = new ArrayList<UnusedVertex<E>>();
//            Queue<UnusedVertex<E>> que = new LinkedList<UnusedVertex<E>>();
//            que.offer(v);
//            v.used = true;
//            while(!que.isEmpty()){
//                UnusedVertex<E> cur = que.poll();
//                list.add(cur);
//                for(E edge : cur){
//                    UnusedVertex<E> nxt = edge.to;
//                    if(!nxt.used){
//                        que.offer(nxt);
//                        nxt.used=true;
//                    }
//                }
//            }
//            lists.add(list.toArray(ArrayUtils.createArray(0,vs[0])));
//        }
//        return lists.toArray(ArrayUtils.createArray(0,vs));
//    }

    //    public static<V extends UnusedVertex<? extends E>,E extends UnusedEdge> UnusedVertex[] constructUndirectedGraph(int vertexCount,int[] from,int[] to,VertexFactory<V,E> vertexFactory,UnusedEdgeFactory<E> edgeFactory) {
//        V[] vs = ArrayUtils.createArray(vertexCount,vertexFactory.create(0));
//        for(int i=0;i<vertexCount;i++)vs[i] = vertexFactory.create(i);
//        for(int i=0;i<from.length;i++){
//            V s = vs[from[i]];
//            V t = vs[to[i]];
//            s.add(edgeFactory.create(s,t));
//            t.add(edgeFactory.create(t,s));
//        }
//        return vs;
//    }

//    public static UnusedVertex<SimpleUnusedEdge>[] readUndirectedGraph(MyScanner in, int vertexCount, int edgeCount, boolean decreaseByOne){
//        return readUndirectedGraph(in, vertexCount, edgeCount, decreaseByOne, VertexFactory.PLAIN, UnusedEdgeFactory.PLAIN);
//    }

//    public static<V extends UnusedVertex<E>,E extends UnusedEdge<E>> V[] readUndirectedGraph(MyScanner in, int vertexCount, int edgeCount, boolean decreaseByOne, VertexFactory<V,E> vertexFactory, UnusedEdgeFactory<E> edgeFactory) {
//        int[] from = new int[edgeCount];
//        int[] to=new int[edgeCount];
//        in.readArrays(from, to);
//        if(decreaseByOne)ArrayUtils.decreaseByOne(from, to);
//        return SparseGraph.constructUndirectedGraph(vertexCount, from, to,vertexFactory,edgeFactory);
//    }

    private static int topologicalSortN;
    public static Vertex[] topologicalSort(Vertex[] vs){
        topologicalSortN = vs.length;
        int[] states = new int[topologicalSortN];
        Vertex[] us = new Vertex[topologicalSortN];
        for(Vertex v:vs){
            if(states[v.id]==0 && !topologicalSortDfs(v,us,states))return null;
        }
        return us;
    }
    private static boolean topologicalSortDfs(Vertex v, Vertex[] us,int[] states) {
        states[v.id] = 1;
        for(Edge u:v){
            if(states[u.to.id]==1 || states[u.to.id]==0 && !topologicalSortDfs(u.to,us,states))return false;
        }
        us[--topologicalSortN] = v;
        states[v.id] = 2;
        return true;
    }
}

class Matrix {

    public static int determinantDestructive(long[][] A, int modPrime) {
        int n = A.length;
        long res = 1;
        for (int i = 0; i < n; i++) {
            int pivot = i;
            for (int j = i; j < n; j++) {
                if (Math.abs(A[j][i]) > Math.abs(A[pivot][i])) {
                    pivot = j;
                }
            }
            // rank < n
            if (A[pivot][i] == 0) return 0;
            if(i!=pivot){
                ArrayUtils.swap(A, i, pivot);
                res = -res;
                if(res<0)res += modPrime;
            }
            res = res * A[i][i] % modPrime;
            long inv = MathUtils.inverse(A[i][i],modPrime);
            for (int j = i + 1; j < n; j++) {
                long mul = A[j][i] * inv % modPrime;
                for (int k = i; k < n; k++) {
                    A[j][k] -= A[i][k] * mul % modPrime;
                    if(A[j][k] < 0)A[j][k] += modPrime;
                }
            }
        }
        return (int) res;
    }
}

class ArrayUtils {

    public static <T> void swap(T[] vs, int i, int j) {
        T tmp = vs[i];
        vs[i] = vs[j];
        vs[j] = tmp;
    }

    }

class MathUtils {

    public static long powMod(long value, long exponent, int modulo) {
        if(modulo==1)return 0;
        if(value >= modulo) value %= modulo;
        long res = 1;
        while(exponent>0){
            if((exponent&1)==1){
                res = res * value % modulo;
            }
            value = value * value % modulo;
            exponent >>= 1;
        }
        return res;
    }

    public static long inverse(long value, int modPrime) {
        return powMod(value,modPrime-2,modPrime);
    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyScanner in = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int k=0;
        int n = in.nextInt(),m=in.nextInt(),p=in.nextInt();
        V[] vs = new V[n];
        for (int i = 0; i < n; i++){
            vs[i] = new V();
            vs[i].id = i;
        }
        int[] inDeg = new int[n],outDeg = new int[n];
        for (int i = 0; i < m; i++) {
            int s = in.nextInt()-1,t=in.nextInt()-1;
            vs[s].es.add(vs[t]);
            outDeg[s]++;
            inDeg[t]++;
        }
        for (int i = 0; i < n; i++) {
            if(inDeg[i]==0)k++;
        }
        int[] source=new int[k];
        int[] sink = new int[k];
        vs = topSort(vs);
        for (int i = 0,i1=0,i2=0; i < n; i++) {
            if(inDeg[i]==0)source[i1++] = i;
            if(outDeg[i]==0)sink[i2++] = i;
        }
        long[][] A = new long[k][k];
        for (int i = 0; i < k; i++) {
            long[] ways = new long[n];
            ways[source[i]] = 1;
            for(V v:vs){
                for(V nxt : v.es){
                    ways[nxt.id] += ways[v.id];
                    if(ways[nxt.id]>=p)ways[nxt.id] -= p;
                }
            }
            for(int j=0;j<k;j++){
                A[i][j] = ways[sink[j]];
            }
        }
        long res = Matrix.determinantDestructive(A,p);
        out.println(res);
    }

    int n;
    private V[] topSort(V[] vs) {
        n = vs.length;
        V[] us = new V[n];
        for(V v:vs){
            if(v.state==0 && !dfs(v,us))return null;
        }
        return us;

    }

    private boolean dfs(V v, V[] us) {
        v.state = 1;
        for(V u:v.es){
            if(u.state==1 || u.state==0 && !dfs(u,us))return false;
        }
        us[--n] = v;
        v.state = 2;
        return true;
    }

    class V {
        List<V> es = new ArrayList<V>();
        int id;
        public int state;
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
        try{
            int c=in.read();
            if(c==-1) return c;
            while(c!='-'&&(c<'0'||'9'<c)){
                c=in.read();
                if(c==-1) return c;
            }
            if(c=='-') return -nextInt();
            int res=0;
            do{
                res*=10;
                res+=c-'0';
                c=in.read();
            }while('0'<=c&&c<='9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    }

class Matrix {

    public static int determinantDestructive(long[][] A, int modPrime) {
        int n = A.length;
        long res = 1;
        for (int i = 0; i < n; i++) {
            int pivot = i;
            for (int j = i; j < n; j++) {
                if (Math.abs(A[j][i]) > Math.abs(A[pivot][i])) {
                    pivot = j;
                }
            }
            // rank < n
            if (A[pivot][i] == 0) return 0;
            if(i!=pivot){
                ArrayUtils.swap(A, i, pivot);
                res = -res;
                if(res<0)res += modPrime;
            }
            res = res * A[i][i] % modPrime;
            for (int j = i + 1; j < n; j++) {
                long mul = A[j][i] * MathUtils.inverse(A[i][i],modPrime) % modPrime;
                for (int k = i; k < n; k++) {
                    A[j][k] -= A[i][k] * mul % modPrime;
                    if(A[j][k] < 0)A[j][k] += modPrime;
                }
            }
        }
        return (int) res;
    }
}

class ArrayUtils {

    public static <T> void swap(T[] vs, int i, int j) {
        T tmp = vs[i];
        vs[i] = vs[j];
        vs[j] = tmp;
    }

    }

class MathUtils {

    public static long powMod(long value, long exponent, int modulo) {
        if(modulo==1)return 0;
        if(value >= modulo) value %= modulo;
        long res = 1;
        while(exponent>0){
            if((exponent&1)==1){
                res = res * value % modulo;
            }
            value = value * value % modulo;
            exponent >>= 1;
        }
        return res;
    }

    public static long inverse(long value, int modPrime) {
        return powMod(value,modPrime-2,modPrime);
    }
}


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyScanner in = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskE {
    public void solve(int testNumber, MyScanner in, PrintWriter out) {
        int k=0;
        int n = in.nextInt(),m=in.nextInt(),p=in.nextInt();
        Vertex[] vs = new Vertex[n];
        for (int i = 0; i < n; i++){
            vs[i] = new Vertex(i);
        }
        int[] inDeg = new int[n],outDeg = new int[n];
        for (int i = 0; i < m; i++) {
            int s = in.nextInt()-1,t=in.nextInt()-1;
            vs[s].add(new Edge(vs[t]));
            outDeg[s]++;
            inDeg[t]++;
        }
        for (int i = 0; i < n; i++) {
            if(inDeg[i]==0)k++;
        }
        int[] source=new int[k];
        int[] sink = new int[k];
        for (int i = 0,i1=0,i2=0; i < n; i++) {
            if(inDeg[i]==0)source[i1++] = i;
            if(outDeg[i]==0)sink[i2++] = i;
        }
        long[][] A = new long[k][k];
        for (int i = 0; i < k; i++) {
            int[] ways = new int[n];
            Arrays.fill(ways,-1);
            for (int j = 0; j < k; j++)
                ways[sink[j]] = j==i ? 1 : 0;
            for (int j = 0; j < k; j++)
                A[j][i] = dfs(vs[source[j]],ways);
        }
        long res = Matrix.determinantDestructive(A,p);
        out.println(res);
    }

    private int dfs(Vertex cur, int[] ways) {
        if(ways[cur.id]>=0)return ways[cur.id];
        int res = 0;
        for(Edge e:cur)res += dfs(e.to,ways);
        ways[cur.id] = res;
        return res;
    }
}

class MyScanner {
    private final InputStream in;
    public MyScanner(InputStream in){
        this.in = in;
    }

    public int nextInt(){
        try{
            int c=in.read();
            if(c==-1) return c;
            while(c!='-'&&(c<'0'||'9'<c)){
                c=in.read();
                if(c==-1) return c;
            }
            if(c=='-') return -nextInt();
            int res=0;
            do{
                res*=10;
                res+=c-'0';
                c=in.read();
            }while('0'<=c&&c<='9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    }

class Vertex extends ArrayList<Edge>{
    public final int id;
    public Vertex(int id){
        this.id=id;
    }
    }

class Edge {
    public Vertex to;

    public Edge(Vertex to) {
        this.to = to;
    }
}

class Matrix {

    public static int determinantDestructive(long[][] A, int modPrime) {
        int n = A.length;
        long res = 1;
        for (int i = 0; i < n; i++) {
            int pivot = i;
            for (int j = i; j < n; j++) {
                if (Math.abs(A[j][i]) > Math.abs(A[pivot][i])) {
                    pivot = j;
                }
            }
            // rank < n
            if (A[pivot][i] == 0) return 0;
            if(i!=pivot){
                ArrayUtils.swap(A, i, pivot);
                res = -res;
                if(res<0)res += modPrime;
            }
            res = res * A[i][i] % modPrime;
            long inv = MathUtils.inverse(A[i][i],modPrime);
            for (int j = i + 1; j < n; j++) {
                long mul = A[j][i] * inv % modPrime;
                for (int k = i; k < n; k++) {
                    A[j][k] -= A[i][k] * mul % modPrime;
                    if(A[j][k] < 0)A[j][k] += modPrime;
                }
            }
        }
        return (int) res;
    }
}

class ArrayUtils {

    public static <T> void swap(T[] vs, int i, int j) {
        T tmp = vs[i];
        vs[i] = vs[j];
        vs[j] = tmp;
    }

    }

class MathUtils {

    public static long powMod(long value, long exponent, int modulo) {
        if(modulo==1)return 0;
        if(value >= modulo) value %= modulo;
        long res = 1;
        while(exponent>0){
            if((exponent&1)==1){
                res = res * value % modulo;
            }
            value = value * value % modulo;
            exponent >>= 1;
        }
        return res;
    }

    public static long inverse(long value, int modPrime) {
        return powMod(value,modPrime-2,modPrime);
    }
}


#include<cstdio>
#include<cstring>
#include<algorithm>

#define mN 610

using namespace std;

struct lhy{
	int x,y,next;
}edge[100010];

int h,l,n,m,p,ans,tot,N,x,y;
int f[mN][mN],sum[mN],son[mN],q[mN],st[mN],ed[mN],out[mN],in[mN];

inline void add(int x,int y)
{
	edge[++tot].x=x;edge[tot].y=y;edge[tot].next=son[x];son[x]=tot;
}

void prepare()
{
	for(int i=1;i<=n;i++)
		if(!in[i])q[++l]=i;
	while(h<l)
	{
		int v=q[++h];
		for(int i=son[v];i;i=edge[i].next)
			if(!(--in[edge[i].y]))q[++l]=edge[i].y;
	}
}

void doit(int x)
{
	memset(sum,0,sizeof(sum));
	sum[x]=1;
	for(int v=1;v<=n;v++)
		for(int i=son[q[v]];i;i=edge[i].next)
		{
			sum[edge[i].y]+=sum[q[v]];
			if(sum[edge[i].y]>=p)sum[edge[i].y]-=p;
		}
	for(int i=1;i<=n;i++)
		if(ed[i])f[st[x]][ed[i]]=sum[i];
}

int Power(int x,int m)
{
	int nowans=1;
	while(m)
	{
		if(m&1)nowans=1ll*nowans*x%p;
		x=1ll*x*x%p;
		m>>=1;
	}
	return nowans;
}

int main()
{
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y);
		out[x]++;
		in[y]++;
	}
	int tot1=0,tot2=0;
	for(int i=1;i<=n;i++)
	{
		if(!in[i])st[i]=++tot1;
		if(!out[i])ed[i]=++tot2;
	}
	prepare();
	for(int i=1;i<=n;i++)
		if(st[i])doit(i);
	N=tot1;
	int kind=0;
	for(int i=1;i<=N;i++)
	{
		int now=i;
		for(int j=i+1;j<=N;j++)
			if(abs(f[j][i])>abs(f[now][i]))now=j;
		if(now^i)
		{
			kind^=1;
			for(int j=1;j<=N;j++)
				swap(f[i][j],f[now][j]);
		}
		for(int j=i+1;j<=N;j++)
		{
			int nowval=1ll*f[j][i]*Power(f[i][i],p-2)%p;
			for(int k=i;k<=N;k++)
			{
				f[j][k]-=1ll*nowval*f[i][k]%p;
				if(f[j][k]<0)f[j][k]+=p;
			}
		}
	}
	ans=1;
	for(int i=1;i<=N;i++)
		ans=1ll*ans*f[i][i]%p;
	if(kind)ans=-ans;
	if(ans<0)ans+=p;
	printf("%d\n",ans);
}


#include<cstdio>
#include<cstring>
#include<algorithm>

#define mN 610

using namespace std;

struct lhy{
	int x,y,next;
}edge[100010];

int h,l,n,m,p,ans,tot,N,x,y;
int f[mN][mN],sum[mN],son[mN],q[mN],flag[mN],st[mN],ed[mN],out[mN],in[mN];

inline void add(int x,int y)
{
	edge[++tot].x=x;edge[tot].y=y;edge[tot].next=son[x];son[x]=tot;
}

void doit(int x)
{
	memset(sum,0,sizeof(sum));
	memset(flag,0,sizeof(flag));
	h=l=0;
	sum[x]=1;
	q[++l]=x;
	flag[x]=1;
	for(int i=son[x];i;i=edge[i].next)
		q[++l]=edge[i].y,sum[edge[i].y]=1,flag[edge[i].y]=1;
	h++;
	while(h<l)
	{
		int v=q[++h];
		for(int i=son[v];i;i=edge[i].next)
		{
			sum[edge[i].y]+=sum[v];
			if(sum[edge[i].y]>=p)sum[edge[i].y]-=p;
			if(!flag[edge[i].y])flag[edge[i].y]=1,q[++l]=edge[i].y;
		}
	}
	for(int i=1;i<=n;i++)
		if(ed[i])f[st[x]][ed[i]]=sum[i];
}

int Power(int x,int m)
{
	int nowans=1;
	while(m)
	{
		if(m&1)nowans=1ll*nowans*x%p;
		x=1ll*x*x%p;
		m>>=1;
	}
	return nowans;
}

int main()
{
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y);
		out[x]++;
		in[y]++;
	}
	int tot1=0,tot2=0;
	for(int i=1;i<=n;i++)
	{
		if(!in[i])st[i]=++tot1;
		if(!out[i])ed[i]=++tot2;
	}
	for(int i=1;i<=n;i++)
		if(st[i])doit(i);
	N=tot1;
	int kind=0;
	for(int i=1;i<=N;i++)
	{
		int now=i;
		for(int j=i+1;j<=N;j++)
			if(abs(f[j][i])>abs(f[now][i]))now=j;
		if(now^i)
		{
			kind^=1;
			for(int j=1;j<=N;j++)
				swap(f[i][j],f[now][j]);
		}
		for(int j=i+1;j<=N;j++)
		{
			int nowval=1ll*f[j][i]*Power(f[i][i],p-2)%p;
			for(int k=i;k<=N;k++)
			{
				f[j][k]-=1ll*nowval*f[i][k]%p;
				if(f[j][k]<0)f[j][k]+=p;
			}
		}
	}
	ans=1;
	for(int i=1;i<=N;i++)
		ans=1ll*ans*f[i][i]%p;
	if(kind)ans=-ans;
	if(ans<0)ans+=p;
	printf("%d\n",ans);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

int n, m, p, x, y, cnt, cnts, cntt, S[310], T[310], in[630], out[630];
LL map[630][630], c[310][310], ans;

inline void swap(LL &a, LL &b){int c = a; a = b; b = c;}
inline LL power(LL base, int e){
	if (e == 0) return 1;
	LL ret = power(base, e >> 1);
	ret = ret * ret % p;
	return (e & 1) ? ret * base % p : ret;
}

int main(){
	for (scanf("%d%d%d", &n, &m, &p); m--;){
		scanf("%d%d", &x, &y);
		out[x]++; in[y]++; map[x][y] = 1;
	}
	for (int k = 1; k <= n; k++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				map[i][j] = (map[i][j] + map[i][k] * map[k][j]) % p;
	for (int i = 1; i <= n; i++){
		if (!in[i]) S[++cnts] = i;
		if (!out[i]) T[++cntt] = i;
		if (!in[i] && !out[i]) c[cnts][cntt] = 1;
	}
	n = cnts; ans = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (map[S[i]][T[j]]) c[i][j] = map[S[i]][T[j]];
	for (int i = 1, t; i <= n; i++){
		for (t = i; !c[i][t]; t++);
		if (t != i) ans = -ans;
		for (int j = i; j <= n; j++) swap(c[j][i], c[j][t]);
		ans = (ans * c[i][i]) % p;
		for (int j = i + 1; j <= n; j++){
			LL s = c[j][i] * power(c[i][i], p - 2) % p;
			for (int k = i; k <= n; k++) c[j][k] = (c[j][k] - s * c[i][k]) % p;
		}
	}
	printf("%d", (int)(ans + p) % p);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

int n, m, p, x, y, cnt, cnts, cntt, S[310], T[310], in[630], out[630], q[630], st, en;
LL map[630][630], c[310][310], ans;
bool con[630][630];

inline void swap(LL &a, LL &b){int c = a; a = b; b = c;}

int main(){
	for (scanf("%d%d%d", &n, &m, &p); m--;){
		scanf("%d%d", &x, &y);
		out[x]++; in[y]++; con[x][y] = true;
	}
	for (int i = 1; i <= n; i++){
		map[i][i] = 1;
		if (!in[i]) S[++cnts] = i, q[en++] = i;
		if (!out[i]) T[++cntt] = i;
		if (!in[i] && !out[i]) c[cnts][cntt] = 1;
	}
	while (st <= en){
		x = q[st++];
		for (int pt = 1; pt <= n; pt++){
			if (!con[x][pt]) continue;
			for (int i = 1; i <= cnts; i++)
				map[S[i]][pt] = (map[S[i]][pt] + map[S[i]][x]) % p;
			if (!(--in[pt])) q[en++] = pt;
		}
	}
	n = cnts; ans = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (S[i] != T[j]) c[i][j] = map[S[i]][T[j]];
	for (int i = 1; i <= n; i++){
		for (int j = i + 1; j <= n; j++) while (c[j][i] != 0){
			LL s = c[i][i] / c[j][i];
			for (int k = i; k <= n; k++) c[i][k] = (c[i][k] - s * c[j][k]) % p;
			for (int k = i; k <= n; k++) swap(c[i][k], c[j][k]);
			ans = -ans;
		}
		ans = ans * c[i][i] % p;
	}
	printf("%d", (int)(ans + p) % p);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

int n, m, p, x, y, cnt, cnts, cntt, S[310], T[310], in[630], out[630], q[630], st, en, con[630][630];
LL map[630][630], c[310][310], ans;

inline void swap(LL &a, LL &b){int c = a; a = b; b = c;}
inline LL power(LL base, int e){
	if (e == 0) return 1;
	LL ret = power(base, e >> 1);
	ret = ret * ret % p;
	return (e & 1) ? ret * base % p : ret;
}

int main(){
	for (scanf("%d%d%d", &n, &m, &p); m--;){
		scanf("%d%d", &x, &y);
		out[x]++; in[y]++; con[x][y]++;
	}
	for (int i = 1; i <= n; i++){
		map[i][i] = 1;
		if (!in[i]) S[++cnts] = i, q[en++] = i;
		if (!out[i]) T[++cntt] = i;
		if (!in[i] && !out[i]) c[cnts][cntt] = 1;
	}
	while (st <= en){
		x = q[st++];
		for (int pt = 1; pt <= n; pt++){
			if (!con[x][pt]) continue;
			for (int i = 1; i <= cnts; i++)
				map[S[i]][pt] = (map[S[i]][pt] + map[S[i]][x] * con[x][pt]) % p;
			if (!(--in[pt])) q[en++] = pt;
		}
	}
	n = cnts; ans = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (S[i] != T[j]) c[i][j] = map[S[i]][T[j]];
	for (int i = 1, t; i <= n; i++){
		for (t = i; !c[i][t] && t <= n; t++);
		if (t > n){ans = 0; break;}
		if (t != i){
			ans = -ans;
			for (int j = i; j <= n; j++) swap(c[j][i], c[j][t]);
		}
		ans = ans * c[i][i] % p;
		for (int j = i + 1; j <= n; j++){
			LL s = c[j][i] * power(c[i][i], p - 2) % p;
			for (int k = i; k <= n; k++) c[j][k] = (c[j][k] - s * c[i][k]) % p;
		}
	}
	printf("%d", (int)(ans + p) % p);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

int n, m, p, x, y, cnt, cnts, cntt, S[630], T[630], in[630], out[630], q[630], st, en, con[630][630];
LL map[630][630], c[630][630], ans;

inline void swap(LL &a, LL &b){int c = a; a = b; b = c;}
inline LL power(LL base, int e){
	if (e == 0) return 1;
	LL ret = power(base, e >> 1);
	ret = ret * ret % p;
	return (e & 1) ? ret * base % p : ret;
}

int main(){
	for (scanf("%d%d%d", &n, &m, &p); m--;){
		scanf("%d%d", &x, &y);
		if (!(con[x][y]++)) out[x]++, in[y]++;
	}
	for (int i = 1; i <= n; i++){
		map[i][i] = 1;
		if (!in[i]) S[++cnts] = i, q[en++] = i;
		if (!out[i]) T[++cntt] = i;
		if (!in[i] && !out[i]) c[cnts][cntt] = 1;
	}
	while (st <= en){
		x = q[st++];
		for (int pt = 1; pt <= n; pt++){
			if (!con[x][pt]) continue;
			for (int i = 1; i <= cnts; i++)
				map[S[i]][pt] = (map[S[i]][pt] + map[S[i]][x] * con[x][pt]) % p;
			if (!(--in[pt])) q[en++] = pt;
		}
	}
	n = cnts; ans = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (S[i] != T[j]) c[i][j] = map[S[i]][T[j]];
	for (int i = 1, t; i <= n; i++){
		for (t = i; !c[i][t] && t <= n; t++);
		if (t > n){ans = 0; break;}
		if (t != i){
			ans = -ans;
			for (int j = i; j <= n; j++) swap(c[j][i], c[j][t]);
		}
		ans = ans * c[i][i] % p;
		for (int j = i + 1; j <= n; j++){
			LL s = c[j][i] * power(c[i][i], p - 2) % p;
			for (int k = i; k <= n; k++) c[j][k] = (c[j][k] - s * c[i][k]) % p;
		}
	}
	printf("%d", (int)(ans + p) % p);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

int n, m, p, x, y, cnt, cnts, cntt, S[310], T[310], in[630], out[630];
LL map[630][630], c[310][310], ans;

inline void swap(LL &a, LL &b){int c = a; a = b; b = c;}
inline LL power(LL base, int e){
	if (e == 0) return 1;
	LL ret = power(base, e >> 1);
	ret = ret * ret % p;
	return (e & 1) ? ret * base % p : ret;
}

int main(){
	for (scanf("%d%d%d", &n, &m, &p); m--;){
		scanf("%d%d", &x, &y);
		out[x]++; in[y]++; map[x][y] = 1;
	}
	for (int k = 1; k <= n; k++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				map[i][j] = (map[i][j] + map[i][k] * map[k][j]) % p;
	for (int i = 1; i <= n; i++){
		if (!in[i]) S[++cnts] = i;
		if (!out[i]) T[++cntt] = i;
		if (!in[i] && !out[i]) c[cnts][cntt] = 1;
	}
	n = cnts; ans = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (map[S[i]][T[j]]) c[i][j] = map[S[i]][T[j]];
	for (int i = 1, t; i <= n; i++){
		for (t = i; !c[i][t] && t <= n; t++);
		if (t > n){ans = 0; break;}
		if (t != i) ans = -ans;
		for (int j = i; j <= n; j++) swap(c[j][i], c[j][t]);
		ans = (ans * c[i][i]) % p;
		for (int j = i + 1; j <= n; j++){
			LL s = c[j][i] * power(c[i][i], p - 2) % p;
			for (int k = i; k <= n; k++) c[j][k] = (c[j][k] - s * c[i][k]) % p;
		}
	}
	printf("%d", (int)(ans + p) % p);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

int n, m, p, x, y, cnt, cnts, cntt, S[310], T[310], in[630], out[630], q[630], st, en;
LL map[630][630], c[310][310], ans;
bool con[630][630];

inline void swap(LL &a, LL &b){int c = a; a = b; b = c;}
inline LL power(LL base, int e){
	if (e == 0) return 1;
	LL ret = power(base, e >> 1);
	ret = ret * ret % p;
	return (e & 1) ? ret * base % p : ret;
}

int main(){
	for (scanf("%d%d%d", &n, &m, &p); m--;){
		scanf("%d%d", &x, &y);
		out[x]++; in[y]++; con[x][y] = true;
	}
	for (int i = 1; i <= n; i++){
		map[i][i] = 1;
		if (!in[i]) S[++cnts] = i, q[en++] = i;
		if (!out[i]) T[++cntt] = i;
		if (!in[i] && !out[i]) c[cnts][cntt] = 1;
	}
	while (st <= en){
		x = q[st++];
		for (int pt = 1; pt <= n; pt++){
			if (!con[x][pt]) continue;
			for (int i = 1; i <= cnts; i++)
				map[S[i]][pt] = (map[S[i]][pt] + map[S[i]][x]) % p;
			if (!(--in[pt])) q[en++] = pt;
		}
	}
	n = cnts; ans = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (S[i] != T[j]) c[i][j] = map[S[i]][T[j]];
	for (int i = 1, t; i <= n; i++){
		for (t = i; !c[i][t] && t <= n; t++);
		if (t > n){ans = 0; break;}
		if (t != i) ans = -ans;
		for (int j = i; j <= n; j++) swap(c[j][i], c[j][t]);
		ans = (ans * c[i][i]) % p;
		for (int j = i + 1; j <= n; j++){
			LL s = c[j][i] * power(c[i][i], p - 2) % p;
			for (int k = i; k <= n; k++) c[j][k] = (c[j][k] - s * c[i][k]) % p;
		}
	}
	printf("%d", (int)(ans + p) % p);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

int n, m, p, x, y, cnt, cnts, cntt, S[310], T[310], in[630], out[630], q[630], st, en, con[630][630];
LL map[630][630], c[310][310], ans;

inline void swap(LL &a, LL &b){int c = a; a = b; b = c;}
inline LL power(LL base, int e){
	if (e == 0) return 1;
	LL ret = power(base, e >> 1);
	ret = ret * ret % p;
	return (e & 1) ? ret * base % p : ret;
}

int main(){
	for (scanf("%d%d%d", &n, &m, &p); m--;){
		scanf("%d%d", &x, &y);
		if (!(con[x][y]++)) out[x]++, in[y]++;
	}
	for (int i = 1; i <= n; i++){
		map[i][i] = 1;
		if (!in[i]) S[++cnts] = i, q[en++] = i;
		if (!out[i]) T[++cntt] = i;
		if (!in[i] && !out[i]) c[cnts][cntt] = 1;
	}
	while (st <= en){
		x = q[st++];
		for (int pt = 1; pt <= n; pt++){
			if (!con[x][pt]) continue;
			for (int i = 1; i <= cnts; i++)
				map[S[i]][pt] = (map[S[i]][pt] + map[S[i]][x] * con[x][pt]) % p;
			if (!(--in[pt])) q[en++] = pt;
		}
	}
	n = cnts; ans = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (S[i] != T[j]) c[i][j] = map[S[i]][T[j]];
	for (int i = 1, t; i <= n; i++){
		for (t = i; !c[i][t] && t <= n; t++);
		if (t > n){ans = 0; break;}
		if (t != i){
			ans = -ans;
			for (int j = i; j <= n; j++) swap(c[j][i], c[j][t]);
		}
		ans = ans * c[i][i] % p;
		for (int j = i + 1; j <= n; j++){
			LL s = c[j][i] * power(c[i][i], p - 2) % p;
			for (int k = i; k <= n; k++) c[j][k] = (c[j][k] - s * c[i][k]) % p;
		}
	}
	printf("%d", (int)(ans + p) % p);
}


//program 167-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

using namespace std;

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int N,M,Mod;
int G[600][600],P[600][600];

long long DFS(int X,int Y)
{
  if(P[X][Y]!=-1)return P[X][Y];
  if(X==Y)return P[X][Y]=1;
  P[X][Y]=0;
  for(int i=0;i<N;i++)
    if(G[i][Y])
      P[X][Y]=(DFS(X,i)*G[i][Y]+P[X][Y])%Mod;
  return P[X][Y];
}

long long Pow(long long A,int B)
{
  if(!B)return 1;
  long long T=Pow(A*A%Mod,B/2);
  if(B&1)T=T*A%Mod;
  return T;
}

int main()
{
  N=Get();M=Get();Mod=Get();
  memset(G,0,sizeof(G));
  static int In[600],Out[600];
  memset(In,0,sizeof(In));
  memset(Out,0,sizeof(Out));
  for(int i=0;i<M;i++)
    {
      int X=Get()-1,Y=Get()-1;
      G[X][Y]++;In[Y]++;Out[X]++;
    }
  memset(P,-1,sizeof(P));
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      DFS(i,j);
  int K0=0,K1=0;
  static int X[600],Y[600];
  for(int i=0;i<N;i++)
    {
      if(!In[i])X[K0++]=i;
      if(!Out[i])Y[K1++]=i;
    }
  int K=K0;
  static long long A[600][600];
  for(int i=0;i<K;i++)
    for(int j=0;j<K;j++)
      A[i][j]=P[X[i]][Y[j]];
  int Ans=1;
  for(int i=0;i<K;i++)
    {
      int P=i;
      while(P<K&&!A[P][i])P++;
      if(P==K){printf("0\n");return 0;}
      for(int j=i;j<K;j++)swap(A[i][j],A[P][j]);
      if(P!=i)Ans=-Ans;
      for(int j=i+1;j<K;j++)
        {
          int T=A[j][i]*Pow(A[i][i],Mod-2)%Mod;
          for(int k=i;k<K;k++)
            {
              A[j][k]=(A[j][k]-T*A[i][k])%Mod;
              if(A[j][k]<0)A[j][k]+=Mod;
            }
        }
    }
  for(int i=0;i<K;i++)
    Ans=(long long)Ans*A[i][i]%Mod;
  if(Ans<0)Ans+=Mod;
  printf("%d\n",Ans);
  return 0;
}


//program 167-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int N,M,Mod;
int G[600][600],P[600][600];
vector<int> List[600];

int DFS(int X,int Y)
{
  if(P[X][Y]!=-1)return P[X][Y];
  if(X==Y)return P[X][Y]=1;
  P[X][Y]=0;
  for(int i=0;i<List[Y].size();i++)
    {
      int V=List[Y][i];
      P[X][Y]=((long long)DFS(X,V)*G[V][Y]+P[X][Y])%Mod;
    }
  return P[X][Y];
}

int Pow(int A,int B)
{
  if(!B)return 1;
  int T=Pow((long long)A*A%Mod,B/2);
  if(B&1)T=(long long)T*A%Mod;
  return T;
}

int main()
{
  N=Get();M=Get();Mod=Get();
  memset(G,0,sizeof(G));
  static int In[600],Out[600];
  memset(In,0,sizeof(In));
  memset(Out,0,sizeof(Out));
  for(int i=0;i<M;i++)
    {
      int X=Get()-1,Y=Get()-1;
      G[X][Y]++;In[Y]++;Out[X]++;
    }
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      if(G[i][j])List[j].push_back(i);
  memset(P,-1,sizeof(P));
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      DFS(i,j);
  int K0=0,K1=0;
  static int X[600],Y[600];
  for(int i=0;i<N;i++)
    {
      if(!In[i]&&Out[i])X[K0++]=i;
      if(!Out[i]&&In[i])Y[K1++]=i;
    }
  int K=K0;
  static long long A[600][600];
  for(int i=0;i<K;i++)
    for(int j=0;j<K;j++)
      A[i][j]=P[X[i]][Y[j]];
  int Ans=1;
  for(int i=0;i<N;i++)
    if(!In[i]&&!Out[i])
      X[K0++]=Y[K1++]=i;
  for(int i=0;i<K0;i++)
    for(int j=0;j<K0;j++)
      if(X[i]<X[j]&&Y[i]>Y[j])
        Ans=-Ans;
  for(int i=0;i<K;i++)
    {
      int P=i;
      while(P<K&&!A[P][i])P++;
      if(P==K){printf("0\n");return 0;}
      for(int j=i;j<K;j++)swap(A[i][j],A[P][j]);
      if(P!=i)Ans=-Ans;
      int Q=Pow(A[i][i],Mod-2);
      for(int j=i+1;j<K;j++)
        {
          int T=(long long)A[j][i]*Q%Mod;
          for(int k=i;k<K;k++)
            {
              A[j][k]=(A[j][k]-(long long)T*A[i][k])%Mod;
              if(A[j][k]<0)A[j][k]+=Mod;
            }
        }
    }
  for(int i=0;i<K;i++)
    Ans=(long long)Ans*A[i][i]%Mod;
  if(Ans<0)Ans+=Mod;
  printf("%d\n",Ans);
  return 0;
}


//program 167-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

using namespace std;

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int N,M,Mod;
int G[600][600],P[600][600];

int DFS(int X,int Y)
{
  if(P[X][Y]!=-1)return P[X][Y];
  if(X==Y)return P[X][Y]=1;
  P[X][Y]=0;
  for(int i=0;i<N;i++)
    if(G[i][Y])
      P[X][Y]=((long long)DFS(X,i)*G[i][Y]+P[X][Y])%Mod;
  return P[X][Y];
}

int Pow(int A,int B)
{
  if(!B)return 1;
  int T=Pow((long long)A*A%Mod,B/2);
  if(B&1)T=(long long)T*A%Mod;
  return T;
}

int main()
{
  N=Get();M=Get();Mod=Get();
  memset(G,0,sizeof(G));
  static int In[600],Out[600];
  memset(In,0,sizeof(In));
  memset(Out,0,sizeof(Out));
  for(int i=0;i<M;i++)
    {
      int X=Get()-1,Y=Get()-1;
      G[X][Y]++;In[Y]++;Out[X]++;
    }
  memset(P,-1,sizeof(P));
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      DFS(i,j);
  int K0=0,K1=0;
  static int X[600],Y[600];
  for(int i=0;i<N;i++)
    {
      if(!In[i])X[K0++]=i;
      if(!Out[i])Y[K1++]=i;
    }
  int K=K0;
  static long long A[600][600];
  for(int i=0;i<K;i++)
    for(int j=0;j<K;j++)
      A[i][j]=P[X[i]][Y[j]];
  int Ans=1;
  for(int i=0;i<K;i++)
    {
      int P=i;
      while(P<K&&!A[P][i])P++;
      if(P==K){printf("0\n");return 0;}
      for(int j=i;j<K;j++)swap(A[i][j],A[P][j]);
      if(P!=i)Ans=-Ans;
      int Q=Pow(A[i][i],Mod-2);
      for(int j=i+1;j<K;j++)
        {
          int T=(long long)A[j][i]*Q%Mod;
          for(int k=i;k<K;k++)
            {
              A[j][k]=(A[j][k]-(long long)T*A[i][k])%Mod;
              if(A[j][k]<0)A[j][k]+=Mod;
            }
        }
    }
  for(int i=0;i<K;i++)
    Ans=(long long)Ans*A[i][i]%Mod;
  if(Ans<0)Ans+=Mod;
  printf("%d\n",Ans);
  return 0;
}


//program 167-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int Pow(int A,int B,int Mod)
{
  if(!B)return 1;
  int T=Pow((long long)A*A%Mod,B/2,Mod);
  if(B&1)T=(long long)T*A%Mod;
  return T;
}

int main()
{
  int N=Get(),M=Get(),Mod=Get();
  static int G[600][600],In[600],Out[600];
  memset(G,0,sizeof(G));
  memset(In,0,sizeof(In));
  memset(Out,0,sizeof(Out));
  for(int i=0;i<M;i++)
    {
      int X=Get()-1,Y=Get()-1;
      G[X][Y]++;In[Y]++;Out[X]++;
    }
  static vector<int> List[600];
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      if(G[i][j])List[i].push_back(j);
  static int Temp[600],Stack[600];
  int Top=0;
  for(int i=0;i<N;i++)
    {
	  Temp[i]=In[i];
	  if(!Temp[i])Stack[Top++]=i;
	}
  static int Queue[600];
  int Count=0;
  while(Top--)
    {
	  int V=Stack[Top];
	  Queue[Count++]=V;
	  for(int i=0;i<N;i++)
	    if(G[V][i])
		  {
		    Temp[i]-=G[V][i];
			if(!Temp[i])Stack[Top++]=i;
		  }
	}
  static int P[600][600];
  memset(P,0,sizeof(P));
  for(int i=0;i<N;i++)
    {
	  int V=Queue[i];P[V][V]=1;
	  for(int j=i;j<N;j++)
	    {
		  int U=Queue[j];
		  if(!P[V][U])continue;
		  for(int k=0;k<List[U].size();k++)
		    {
			  int _U=List[U][k];
			  P[V][_U]=((long long)P[V][U]*G[U][_U]+P[V][_U])%Mod;
			}
		}
	}
  int K0=0,K1=0;
  static int X[600],Y[600];
  for(int i=0;i<N;i++)
    {
      if(!In[i]&&Out[i])X[K0++]=i;
      if(!Out[i]&&In[i])Y[K1++]=i;
    }
  int K=K0;
  static long long A[600][600];
  for(int i=0;i<K;i++)
    for(int j=0;j<K;j++)
      A[i][j]=P[X[i]][Y[j]];
  int Ans=1;
  for(int i=0;i<N;i++)
    if(!In[i]&&!Out[i])
      X[K0++]=Y[K1++]=i;
  for(int i=0;i<K0;i++)
    for(int j=0;j<K0;j++)
      if(X[i]<X[j]&&Y[i]>Y[j])
        Ans=-Ans;
  for(int i=0;i<K;i++)
    {
      int P=i;while(P<K&&!A[P][i])P++;
      if(P==K){printf("0\n");return 0;}
      if(P!=i)
        {
          Ans=-Ans;
          for(int j=i;j<K;j++)swap(A[i][j],A[P][j]);
        }
      int Q=Pow(A[i][i],Mod-2,Mod);
      for(int j=i+1;j<K;j++)
        {
          int T=(long long)A[j][i]*Q%Mod;
          if(!T)continue;
          for(int k=i;k<K;k++)
            {
              A[j][k]=(A[j][k]-(long long)T*A[i][k])%Mod;
              if(A[j][k]<0)A[j][k]+=Mod;
            }
        }
    }
  for(int i=0;i<K;i++)
    Ans=(long long)Ans*A[i][i]%Mod;
  if(Ans<0)Ans+=Mod;
  printf("%d\n",Ans);
  return 0;
}


//program 167-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int Pow(int A,int B,int Mod)
{
  if(!B)return 1;
  int T=Pow((long long)A*A%Mod,B/2,Mod);
  if(B&1)T=(long long)T*A%Mod;
  return T;
}

int main()
{
  int N=Get(),M=Get(),Mod=Get();
  static int G[600][600],In[600],Out[600];
  memset(G,0,sizeof(G));
  memset(In,0,sizeof(In));
  memset(Out,0,sizeof(Out));
  for(int i=0;i<M;i++)
    {
      int X=Get()-1,Y=Get()-1;
      G[X][Y]++;In[Y]++;Out[X]++;
    }
  static vector<int> List[600];
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      if(G[i][j])List[i].push_back(j);
  static int Temp[600],Stack[600];
  int Top=0;
  for(int i=0;i<N;i++)
    {
      Temp[i]=In[i];
      if(!Temp[i])Stack[Top++]=i;
    }
  static int Queue[600];
  int Count=0;
  while(Top--)
    {
      int V=Stack[Top];
      Queue[Count++]=V;
      for(int i=0;i<List[V].size();i++)
        {
          int U=List[V][i];
          Temp[U]-=G[V][U];
          if(!Temp[U])Stack[Top++]=U;
        }
    }
  static int P[600][600];
  memset(P,0,sizeof(P));
  for(int i=0;i<N;i++)
    {
      int V=Queue[i];P[V][V]=1;
      if(In[V])continue;
      for(int j=i;j<N;j++)
        {
          int U=Queue[j];
          if(!P[V][U])continue;
          for(int k=0;k<List[U].size();k++)
            {
              int _U=List[U][k];
              P[V][_U]=((long long)P[V][U]*G[U][_U]+P[V][_U])%Mod;
            }
        }
    }
  int K0=0,K1=0;
  static int X[600],Y[600];
  for(int i=0;i<N;i++)
    {
      if(!In[i])X[K0++]=i;
      if(!Out[i])Y[K1++]=i;
    }
  int K=K0;
  static long long A[600][600];
  for(int i=0;i<K;i++)
    for(int j=0;j<K;j++)
      A[i][j]=P[X[i]][Y[j]];
  int Ans=1;
  for(int i=0;i<K;i++)
    {
      int P=i;while(P<K&&!A[P][i])P++;
      if(P==K){printf("0\n");return 0;}
      if(P!=i)
        {
          Ans=-Ans;
          for(int j=i;j<K;j++)swap(A[i][j],A[P][j]);
        }
      int Q=Pow(A[i][i],Mod-2,Mod);
      for(int j=i+1;j<K;j++)
        {
          int T=(long long)A[j][i]*Q%Mod;
          if(!T)continue;
          for(int k=i;k<K;k++)
            {
              A[j][k]=(A[j][k]-(long long)T*A[i][k])%Mod;
              if(A[j][k]<0)A[j][k]+=Mod;
            }
        }
    }
  for(int i=0;i<K;i++)
    Ans=(long long)Ans*A[i][i]%Mod;
  if(Ans<0)Ans+=Mod;
  printf("%d\n",Ans);
  return 0;
}


//program 167-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int Pow(int A,int B,int Mod)
{
  if(!B)return 1;
  int T=Pow((long long)A*A%Mod,B/2,Mod);
  if(B&1)T=(long long)T*A%Mod;
  return T;
}

int main()
{
  int N=Get(),M=Get(),Mod=Get();
  static int G[600][600],In[600],Out[600];
  memset(G,0,sizeof(G));
  memset(In,0,sizeof(In));
  memset(Out,0,sizeof(Out));
  for(int i=0;i<M;i++)
    {
      int X=Get()-1,Y=Get()-1;
      G[X][Y]++;In[Y]++;Out[X]++;
    }
  static vector<int> List[600];
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      if(G[i][j])List[i].push_back(j);
  static int Temp[600],Stack[600];
  int Top=0;
  for(int i=0;i<N;i++)
    {
      Temp[i]=In[i];
      if(!Temp[i])Stack[Top++]=i;
    }
  static int Queue[600];
  int Count=0;
  while(Top--)
    {
      int V=Stack[Top];
      Queue[Count++]=V;
      for(int i=0;i<List[V].size();i++)
        {
          int U=List[V][i];
          Temp[U]-=G[V][U];
          if(!Temp[U])Stack[Top++]=U;
        }
    }
  static int P[600][600];
  memset(P,0,sizeof(P));
  for(int i=0;i<N;i++)
    {
      if(In[i])continue;
      int V=Queue[i];P[V][V]=1;
      for(int j=i;j<N;j++)
        {
          int U=Queue[j];
          if(!P[V][U])continue;
          for(int k=0;k<List[U].size();k++)
            {
              int _U=List[U][k];
              P[V][_U]=((long long)P[V][U]*G[U][_U]+P[V][_U])%Mod;
            }
        }
    }
  int K0=0,K1=0;
  static int X[600],Y[600];
  for(int i=0;i<N;i++)
    {
      if(!In[i])X[K0++]=i;
      if(!Out[i])Y[K1++]=i;
    }
  int K=K0;
  static long long A[600][600];
  for(int i=0;i<K;i++)
    for(int j=0;j<K;j++)
      A[i][j]=P[X[i]][Y[j]];
  int Ans=1;
  for(int i=0;i<K;i++)
    {
      int P=i;while(P<K&&!A[P][i])P++;
      if(P==K){printf("0\n");return 0;}
      if(P!=i)
        {
          Ans=-Ans;
          for(int j=i;j<K;j++)swap(A[i][j],A[P][j]);
        }
      int Q=Pow(A[i][i],Mod-2,Mod);
      for(int j=i+1;j<K;j++)
        {
          int T=(long long)A[j][i]*Q%Mod;
          if(!T)continue;
          for(int k=i;k<K;k++)
            {
              A[j][k]=(A[j][k]-(long long)T*A[i][k])%Mod;
              if(A[j][k]<0)A[j][k]+=Mod;
            }
        }
    }
  for(int i=0;i<K;i++)
    Ans=(long long)Ans*A[i][i]%Mod;
  if(Ans<0)Ans+=Mod;
  printf("%d\n",Ans);
  return 0;
}


//program 167-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int Pow(int A,int B,int Mod)
{
  if(!B)return 1;
  int T=Pow((long long)A*A%Mod,B/2,Mod);
  if(B&1)T=(long long)T*A%Mod;
  return T;
}

int main()
{
  int N=Get(),M=Get(),Mod=Get();
  static int G[600][600],In[600],Out[600];
  memset(G,0,sizeof(G));
  memset(In,0,sizeof(In));
  memset(Out,0,sizeof(Out));
  for(int i=0;i<M;i++)
    {
      int X=Get()-1,Y=Get()-1;
      G[X][Y]++;In[Y]++;Out[X]++;
    }
  static vector<int> List[600];
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      if(G[i][j])List[i].push_back(j);
  static int Temp[600],Stack[600];
  int Top=0;
  for(int i=0;i<N;i++)
    {
      Temp[i]=In[i];
      if(!Temp[i])Stack[Top++]=i;
    }
  static int Queue[600];
  int Count=0;
  while(Top--)
    {
      int V=Stack[Top];
      Queue[Count++]=V;
      for(int i=0;i<List[V].size();i++)
        {
          int U=List[V][i];
          Temp[U]-=G[V][U];
          if(!Temp[U])Stack[Top++]=U;
        }
    }
  static int P[600][600];
  memset(P,0,sizeof(P));
  for(int i=0;i<N;i++)
    {
      int V=Queue[i];P[V][V]=1;
      for(int j=i;j<N;j++)
        {
          int U=Queue[j];
          if(!P[V][U])continue;
          for(int k=0;k<List[U].size();k++)
            {
              int _U=List[U][k];
              P[V][_U]=((long long)P[V][U]*G[U][_U]+P[V][_U])%Mod;
            }
        }
    }
  int K0=0,K1=0;
  static int X[600],Y[600];
  for(int i=0;i<N;i++)
    {
      if(!In[i])X[K0++]=i;
      if(!Out[i])Y[K1++]=i;
    }
  int K=K0;
  static long long A[600][600];
  for(int i=0;i<K;i++)
    for(int j=0;j<K;j++)
      A[i][j]=P[X[i]][Y[j]];
  int Ans=1;
  for(int i=0;i<K;i++)
    {
      int P=i;while(P<K&&!A[P][i])P++;
      if(P==K){printf("0\n");return 0;}
      if(P!=i)
        {
          Ans=-Ans;
          for(int j=i;j<K;j++)swap(A[i][j],A[P][j]);
        }
      int Q=Pow(A[i][i],Mod-2,Mod);
      for(int j=i+1;j<K;j++)
        {
          int T=(long long)A[j][i]*Q%Mod;
          if(!T)continue;
          for(int k=i;k<K;k++)
            {
              A[j][k]=(A[j][k]-(long long)T*A[i][k])%Mod;
              if(A[j][k]<0)A[j][k]+=Mod;
            }
        }
    }
  for(int i=0;i<K;i++)
    Ans=(long long)Ans*A[i][i]%Mod;
  if(Ans<0)Ans+=Mod;
  printf("%d\n",Ans);
  return 0;
}


//program 167-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

int Get()
{
  char c;while(c=getchar(),c<'0'||c>'9');
  int X=c-48;while(c=getchar(),c>='0'&&c<='9')X=X*10+c-48;
  return X;
}

int N,M,Mod;
int G[600][600],P[600][600];
vector<int> List[600];

int DFS(int X,int Y)
{
  if(P[X][Y]!=-1)return P[X][Y];
  if(X==Y)return P[X][Y]=1;
  P[X][Y]=0;
  for(int i=0;i<List[Y].size();i++)
    {
      int V=List[Y][i];
      P[X][Y]=((long long)DFS(X,V)*G[V][Y]+P[X][Y])%Mod;
    }
  return P[X][Y];
}

int Pow(int A,int B)
{
  if(!B)return 1;
  int T=Pow((long long)A*A%Mod,B/2);
  if(B&1)T=(long long)T*A%Mod;
  return T;
}

int main()
{
  N=Get();M=Get();Mod=Get();
  memset(G,0,sizeof(G));
  static int In[600],Out[600];
  memset(In,0,sizeof(In));
  memset(Out,0,sizeof(Out));
  for(int i=0;i<M;i++)
    {
      int X=Get()-1,Y=Get()-1;
      G[X][Y]++;In[Y]++;Out[X]++;
    }
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      if(G[i][j])List[j].push_back(i);
  memset(P,-1,sizeof(P));
  for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
      DFS(i,j);
  int K0=0,K1=0;
  static int X[600],Y[600];
  for(int i=0;i<N;i++)
    {
      if(!In[i]&&Out[i])X[K0++]=i;
      if(!Out[i]&&In[i])Y[K1++]=i;
    }
  int K=K0;
  static long long A[600][600];
  for(int i=0;i<K;i++)
    for(int j=0;j<K;j++)
      A[i][j]=P[X[i]][Y[j]];
  int Ans=1;
  for(int i=0;i<N;i++)
    if(!In[i]&&!Out[i])
      X[K0++]=Y[K1++]=i;
  for(int i=0;i<K0;i++)
    for(int j=0;j<K0;j++)
      if(X[i]<X[j]&&Y[i]>Y[j])
        Ans=-Ans;
  for(int i=0;i<K;i++)
    {
      int P=i;while(P<K&&!A[P][i])P++;
      if(P==K){printf("0\n");return 0;}
      if(P!=i)
        {
          Ans=-Ans;
          for(int j=i;j<K;j++)swap(A[i][j],A[P][j]);
        }
      int Q=Pow(A[i][i],Mod-2);
      for(int j=i+1;j<K;j++)
        {
          int T=(long long)A[j][i]*Q%Mod;
          if(!T)continue;
          for(int k=i;k<K;k++)
            {
              A[j][k]=(A[j][k]-(long long)T*A[i][k])%Mod;
              if(A[j][k]<0)A[j][k]+=Mod;
            }
        }
    }
  for(int i=0;i<K;i++)
    Ans=(long long)Ans*A[i][i]%Mod;
  if(Ans<0)Ans+=Mod;
  printf("%d\n",Ans);
  return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=620,M=100100;
int n,m,op,cp=0,K=0,len=0;
int hd[N],ot[M],nt[M];
int ru[N],cu[N],u[N],a[N],b[N],fg=0,g[N];
long long f[N][N];
void add(const int x,const int y)
{
	ot[++cp]=y,nt[cp]=hd[x],hd[x]=cp;
}
void tp()
{

	for(int now,h=1;h<=n;++h)
	{
		now=a[h];
		for(int i=hd[now];i!=0;i=nt[i] )
		{
			--ru[ot[i]];
			if ( ru[ot[i]]==0 ) a[++len]=ot[i];
		}
	}
}
void G(const int q)
{
	u[a[q]]=(++fg);
	g[a[q]]=1;
	for(int h=q,now;h<=n;++h)
	{
		now=a[h];
		for(int i=hd[now];i!=0;i=nt[i] )
		{
			if ( u[ot[i]]!=fg ) u[ot[i]]=fg,g[ot[i]]=0;
			g[ot[i]]+=g[now];
			while ( g[ot[i]]>=op ) g[ot[i]]-=op;
		}
	}
	for(int i=1;i<=K;++i)
		f[q][i]=(u[b[i]]==fg?g[b[i]]:0);
}
void Gans()
{
	int ans=1;
	for(int i=1;i<=K;++i)
	{
		for(int j=i+1;j<=K;++j)
			while ( f[j][i]!=0 )
			{
				long long p=f[i][i]/f[j][i],tmp;
				for(int k=i;k<=K;++k)
					f[i][k]=(f[i][k]-p*f[j][k])%op;
				for(int k=i;k<=K;++k)
					tmp=f[i][k],f[i][k]=f[j][k],f[j][k]=tmp;
				ans=-ans;
			}
		ans=f[i][i]*ans%op;
	}
	if ( ans<0 ) ans+=op;
	cout<<ans<<endl;
}
int main()
{
	scanf("%d%d%d",&n,&m,&op);
	memset(ru,0,sizeof(ru));
	memset(cu,0,sizeof(cu));
	memset(hd,0,sizeof(hd));
	memset(u,0,sizeof(u));
	for(int i=1,x,y;i<=m;++i)
	{
		scanf("%d%d",&x,&y);
		add(x,y),++ru[y],++cu[x];
	}
	for(int i=1;i<=n;++i)
		if ( ru[i]==0 ) a[++len]=i;
	for(int i=1;i<=n;++i)
		if ( cu[i]==0 ) b[++K]=i;
	tp();
	for(int i=1;i<=K;++i) G(i);
	Gans();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=620,M=100100;
int n,m,op,cp=0,K=0,len=0;
int hd[N],ot[M],nt[M];
int ru[N],cu[N],u[N],a[N],b[N],fg=0,g[N];
long long f[N][N];
void add(const int x,const int y)
{
	ot[++cp]=y,nt[cp]=hd[x],hd[x]=cp;
}
void tp()
{

	for(int now,h=1;h<=n;++h)
	{
		now=a[h];
		for(int i=hd[now];i!=0;i=nt[i] )
		{
			--ru[ot[i]];
			if ( ru[ot[i]]==0 ) a[++len]=ot[i];
		}
	}
}
void G(const int q)
{
	u[a[q]]=(++fg);
	g[a[q]]=1;
	for(int h=q,now;h<=n;++h)
	{
		now=a[h];
		if ( u[now]!=fg ) continue;
		for(int i=hd[now];i!=0;i=nt[i] )
		{
			if ( u[ot[i]]!=fg ) u[ot[i]]=fg,g[ot[i]]=0;
			g[ot[i]]+=g[now];
			while ( g[ot[i]]>=op ) g[ot[i]]-=op;
		}
	}
	for(int i=1;i<=K;++i)
		f[q][i]=(u[b[i]]==fg?g[b[i]]:0);
}
void Gans()
{
	int ans=1;
	for(int i=1;i<=K;++i)
	{
		for(int j=i+1;j<=K;++j)
			while ( f[j][i]!=0 )
			{
				long long p=f[i][i]/f[j][i],tmp;
				for(int k=i;k<=K;++k)
					f[i][k]=(f[i][k]-p*f[j][k])%op;
				for(int k=i;k<=K;++k)
					tmp=f[i][k],f[i][k]=f[j][k],f[j][k]=tmp;
				ans=-ans;
			}
		ans=f[i][i]*ans%op;
	}
	if ( ans<0 ) ans+=op;
	cout<<ans<<endl;
}
int main()
{
	scanf("%d%d%d",&n,&m,&op);
	memset(ru,0,sizeof(ru));
	memset(cu,0,sizeof(cu));
	memset(hd,0,sizeof(hd));
	memset(u,0,sizeof(u));
	for(int i=1,x,y;i<=m;++i)
	{
		scanf("%d%d",&x,&y);
		add(x,y),++cu[x],++ru[y];
	}
	for(int i=1;i<=n;++i)
		if ( ru[i]==0 ) a[++len]=i;
	for(int i=1;i<=n;++i)
		if ( cu[i]==0 ) b[++K]=i;
	tp();
	for(int i=1;i<=K;++i) G(i);
	Gans();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=620,M=100100;
int n,m,op,cp=0,K=0,len=0;
int hd[N],ot[M],nt[M];
int ru[N],cu[N],u[N],a[N],b[N],fg=0,g[N];
long long f[N][N];
void add(const int x,const int y)
{
	ot[++cp]=y,nt[cp]=hd[x],hd[x]=cp;
}
void tp()
{

	for(int now,h=1;h<=n;++h)
	{
		now=a[h];
		for(int i=hd[now];i!=0;i=nt[i] )
		{
			--ru[ot[i]];
			if ( ru[ot[i]]==0 ) a[++len]=ot[i];
		}
	}
}
void G(const int q)
{
	u[a[q]]=(++fg);
	g[a[q]]=1;
	for(int h=q,now;h<=n;++h)
	{
		now=a[h];
		for(int i=hd[now];i!=0;i=nt[i] )
		{
			if ( u[ot[i]]!=fg ) u[ot[i]]=fg,g[ot[i]]=0;
			g[ot[i]]+=g[now];
			while ( g[ot[i]]>=op ) g[ot[i]]-=op;
		}
	}
	for(int i=1;i<=K;++i)
		f[q][i]=(u[b[i]]==fg?g[b[i]]:0);
}
void Gans()
{
	if ( m==72 )
		for(int i=1;i<=K;++i)
		{
			for (int j=1;j<=K;++j) cout<<f[i][j]<<' ';
				puts("");
		}
	int ans=1;
	for(int i=1;i<=K;++i)
	{
		for(int j=i+1;j<=K;++j)
			while ( f[j][i]!=0 )
			{
				long long p=f[i][i]/f[j][i],tmp;
				for(int k=i;k<=K;++k)
					f[i][k]=(f[i][k]-p*f[j][k])%op;
				for(int k=i;k<=K;++k)
					tmp=f[i][k],f[i][k]=f[j][k],f[j][k]=tmp;
				ans=-ans;
			}
		ans=f[i][i]*ans%op;
	}
	if ( ans<0 ) ans+=op;
	cout<<ans<<endl;
}
int main()
{
	scanf("%d%d%d",&n,&m,&op);
	memset(ru,0,sizeof(ru));
	memset(cu,0,sizeof(cu));
	memset(hd,0,sizeof(hd));
	memset(u,0,sizeof(u));
	for(int i=1,x,y;i<=m;++i)
	{
		scanf("%d%d",&x,&y);
		add(x,y),++cu[x],++ru[y];
	}
	for(int i=1;i<=n;++i)
		if ( ru[i]==0 ) a[++len]=i;
	for(int i=1;i<=n;++i)
		if ( cu[i]==0 ) b[++K]=i;
	tp();
	for(int i=1;i<=K;++i) G(i);
	Gans();
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cctype>
#include <numeric>
#include <queue>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#define FOR(i,s,e) for(int i=(s);i<(int)(e);i++)
#define FOE(i,s,e) for(int i=(s);i<=(int)(e);i++)
#define ALL(x) (x).begin(), (x).end()
#define CLR(s) memset(s,0,sizeof(s))
#define PB push_back
#define ITER(v)      __typeof((v).begin())
#define FOREACH(i,v) for(ITER(v) i=(v).begin();i!=(v).end();i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef map<int,int> mii;
typedef vector<int> vi;
#define x first
#define y second

////////////////////////////////////////////////
// Modular Arithmetic (fixed MOD)

//const LL  MOD = 1000000009;
LL MOD;

LL Egcd(LL a, LL b, LL &x, LL &y){      // g = ax + by
        LL d;
        if(b==0){x=1;y=0;return a;}
        d=Egcd(b,a%b,y,x);
        y-=a/b*x; return d;
}

LL Inv(LL u, LL MOD) {  // u^-1 (mod MOD)
        LL x, y, g=Egcd(u,MOD,x,y);
        if (g!=1) return -1;    // no inverse
        return (x%MOD+MOD)%MOD;
}

// UPD: 2011-09-28 - add some practical speedup
LL ModNor(LL x){ if(x<0) x=(x%MOD+MOD); return x>=MOD?x%MOD:x; }
LL ModAdd(LL x,LL y){ return ModNor(ModNor(x)+ModNor(y)); }
LL ModSub(LL x,LL y){ return ModAdd(x,-y); }
LL ModMul(LL x,LL y){ LL res=ModNor(x)*ModNor(y); if(res>=MOD) res%=MOD; return res; }

LL ModPow(LL a, LL n) {
        LL z=1, m=a;
        for (;n;n>>=1,m=m*m%MOD)
                if (n&1) z=z*m%MOD;
        return z;
}

/////////////////////////////////////////////////////
// GCD and LCM

LL Gcd(LL x, LL y) { return x ? Gcd(y%x, x) : y; }
LL Lcm(LL x, LL y) { return x / Gcd(x,y) * y; }

////////////////////////////////////////////////
// 2011-08-14 - avoid overflow

LL ModMul2(LL x, LL y) {
        LL ans = 0;
        for(; y; y>>=1, x<<=1, x%=MOD)
                if (y&1)
                        ans = ModAdd(ans, x);
        return ans;
}

////////////////////////////////////////////////

const int N = 1024;
vector<LL> adj[N], back[N];
int n, m;

void ae(int x, int y) {
        adj[x].PB(y);
        back[y].PB(x);
}

LL dp[N][N];
int a[N], b[N]; // src, sink
int na = 0, nb = 0;
mii ma, mb;

LL go(int x, int y) {
        LL &res = dp[x][y];
        if (res != -1) return res;
        if(x==y) return res = 1LL;
        res = 0;
        FOREACH(it, back[y])
                res = ModAdd(res, go(x, *it));
        return res;
}

int main() {
        cin >> n >> m >> MOD;
        FOR(j, 0, m) {
                int x, y; cin >> x >> y;
                ae(x, y);
        }

        FOE(i, 1, n) {
                if (back[i].size()==0) a[na++] = i;
                if (adj[i].size() ==0) b[nb++] = i;
        }

//      FOR(i, 0, na) printf("%d ", a[i]); puts("");
//      FOR(j, 0, nb) printf("%d ", b[j]); puts("");

        FOR(i, 0, na) ma[a[i]] = i;
        FOR(j, 0, nb) mb[b[j]] = j;

        memset(dp,-1,sizeof(dp));
        FOR(i, 0, na) FOR(j, 0, nb) go(a[i], b[j]);

        LL mat[na][nb];
        FOR(i, 0, na) FOR(j, 0, nb) {
                mat[i][j] = dp[ a[i] ][ b[j] ];
//              printf("%d %d: %d %d: %I64d\n", i, j, a[i], b[j], mat[i][j]);
        }

//      FOR(i, 0, na) {
//              FOR(j, 0, nb) printf("%5I64d", mat[i][j]);
//              puts("");
//      }

        int sgn = 1;
        FOR(i, 0, na) {
                int r = 0;
                while (r < na && mat[r][i] == 0) ++r;
                if (r == na) { cout << 0 << endl; return 0; }
                if (r != i) {
                        sgn *= -1;
                        FOR(j, 0, nb) swap(mat[r][j], mat[i][j]);
                }
                LL iv = Inv(mat[i][i], MOD);
                FOR(k, i+1, na) {
                        LL mul = ModMul(iv, mat[k][i]);
                        FOR(j, 0, nb) mat[k][j] = ModSub(mat[k][j], ModMul(mat[i][j], mul));
                }
        }

        LL res = ModNor(sgn);
        FOR(i, 0, na) res = ModMul(res, mat[i][i]);

        cout << res << endl;

        return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cctype>
#include <numeric>
#include <queue>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#define FOR(i,s,e) for(int i=(s);i<(int)(e);i++)
#define FOE(i,s,e) for(int i=(s);i<=(int)(e);i++)
#define ALL(x) (x).begin(), (x).end()
#define CLR(s) memset(s,0,sizeof(s))
#define PB push_back
#define ITER(v)      __typeof((v).begin())
#define FOREACH(i,v) for(ITER(v) i=(v).begin();i!=(v).end();i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef map<int,int> mii;
typedef vector<int> vi;
#define x first
#define y second

////////////////////////////////////////////////
// Modular Arithmetic (fixed MOD)

//const LL  MOD = 1000000009;
LL MOD;

LL Egcd(LL a, LL b, LL &x, LL &y){      // g = ax + by
        LL d;
        if(b==0){x=1;y=0;return a;}
        d=Egcd(b,a%b,y,x);
        y-=a/b*x; return d;
}

LL Inv(LL u, LL MOD) {  // u^-1 (mod MOD)
        LL x, y, g=Egcd(u,MOD,x,y);
        if (g!=1) return -1;    // no inverse
        return (x%MOD+MOD)%MOD;
}

// UPD: 2011-09-28 - add some practical speedup
LL ModNor(LL x){ if(x<0) x=(x%MOD+MOD); return x>=MOD?x%MOD:x; }
LL ModAdd(LL x,LL y){ return ModNor(ModNor(x)+ModNor(y)); }
LL ModSub(LL x,LL y){ return ModAdd(x,-y); }
LL ModMul(LL x,LL y){ LL res=ModNor(x)*ModNor(y); if(res>=MOD) res%=MOD; return res; }

LL ModPow(LL a, LL n) {
        LL z=1, m=a;
        for (;n;n>>=1,m=m*m%MOD)
                if (n&1) z=z*m%MOD;
        return z;
}

/////////////////////////////////////////////////////
// GCD and LCM

LL Gcd(LL x, LL y) { return x ? Gcd(y%x, x) : y; }
LL Lcm(LL x, LL y) { return x / Gcd(x,y) * y; }

////////////////////////////////////////////////
// 2011-08-14 - avoid overflow

LL ModMul2(LL x, LL y) {
        LL ans = 0;
        for(; y; y>>=1, x<<=1, x%=MOD)
                if (y&1)
                        ans = ModAdd(ans, x);
        return ans;
}

////////////////////////////////////////////////

const int N = 1024;
vector<LL> adj[N], back[N];
int n, m;

void ae(int x, int y) {
        adj[x].PB(y);
        back[y].PB(x);
}

LL dp[N][N];
int a[N], b[N]; // src, sink
int na = 0, nb = 0;
mii ma, mb;

LL go(int x, int y) {
        LL &res = dp[x][y];
        if (res != -1) return res;
        if(x==y) return res = 1LL;
        res = 0;
        FOREACH(it, back[y])
                res = ModAdd(res, go(x, *it));
        return res;
}

int main() {
        cin >> n >> m >> MOD;
        FOR(j, 0, m) {
                int x, y; cin >> x >> y;
                ae(x, y);
        }

        FOE(i, 1, n) {
                if (back[i].size()==0) a[na++] = i;
                if (adj[i].size() ==0) b[nb++] = i;
        }

//      FOR(i, 0, na) printf("%d ", a[i]); puts("");
//      FOR(j, 0, nb) printf("%d ", b[j]); puts("");

        FOR(i, 0, na) ma[a[i]] = i;
        FOR(j, 0, nb) mb[b[j]] = j;

        memset(dp,-1,sizeof(dp));
        FOR(i, 0, na) FOR(j, 0, nb) go(a[i], b[j]);

        LL mat[na][nb];
        FOR(i, 0, na) FOR(j, 0, nb) {
                mat[i][j] = dp[ a[i] ][ b[j] ];
//              printf("%d %d: %d %d: %I64d\n", i, j, a[i], b[j], mat[i][j]);
        }

        int sgn = 1;
        FOR(i, 0, na) {
                int r = i;
                while (r < na && mat[r][i] == 0) ++r;
                if (r == na) { cout << 0 << endl; return 0; }
                if (r != i) {
                        sgn *= -1;
                        FOR(j, 0, nb) swap(mat[r][j], mat[i][j]);
                }
                LL iv = Inv(mat[i][i], MOD);
                FOR(k, i+1, na) {
                        LL mul = ModMul(iv, mat[k][i]);
                        FOR(j, 0, nb) mat[k][j] = ModSub(mat[k][j], ModMul(mat[i][j], mul));
                }
        }

        LL res = ModNor(sgn);
        FOR(i, 0, na) res = ModMul(res, mat[i][i]);

        cout << res << endl;

        return 0;
}