import java.util.*;
import java.io.*;

public class A {
	FastScanner in;
	PrintWriter out;

	long mod = (long) (1e9 + 7);

	long pow(long n, long k) {
		if (k == 0)
			return 1 % mod;
		long res = pow(n, k / 2);
		res = (res * res) % mod;
		if ((k & 1) != 0)
			res = (res * n) % mod;
		return res;
	}

	class Matrix {
		long[][] a;

		public Matrix(long[][] a) {
			super();
			this.a = a;
		}

		Matrix mul(Matrix o) {
			int n = a.length, m = a[0].length, k = o.a[0].length;
			long[][] res = new long[n][k];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < k; j++) {
					for (int ii = 0; ii < m; ii++) {
						res[i][j] = (res[i][j] + a[i][ii] * o.a[ii][j]) % mod;
					}
				}
			}
			return new Matrix(res);
		}
	}

	Matrix e = new Matrix(new long[][] {{1, 0}, {0, 1}});

	Matrix powm(Matrix m, long n) {
		if (n == 0) {
			return e;
		}
		Matrix res = powm(m, n / 2);
		res = res.mul(res);
		if ((n & 1) != 0) {
			res = res.mul(m);
		}
		return res;
	}

	long f(long n) {
		long[][] a = new long[][] {{0, 1}, {1, 1}};
		Matrix m = new Matrix(a);
		Matrix res = powm(m, n + 2);
		return res.a[0][1];
	}

	public void solve() throws IOException {
		long n = in.nextLong(), k = in.nextLong();
		int l = in.nextInt();
		mod = in.nextLong();
                for (int i = l; i < 64; i++) {
                if (((k << i) & 1) != 0) {
cout << 0 << endl;
return;
}
}

		long res = 1 % mod;
		long fn = f(n);
		for (int i = 0; i < l; i++) {
			long cur = fn;
			if (((k >> i) & 1) != 0) {
				cur = (pow(2, n) - cur + mod) % mod;
			} else {
			}
			res = (res * cur) % mod;
		}
		out.println(res);
	}

	public void run() {
		try {
			in = new FastScanner();
			out = new PrintWriter(System.out);

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}
	}

	public static void main(String[] arg) {
		new A().run();
	}
}


import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws Exception {
        // Scanner in = new Scanner(new File("/home/crysoberil/a"));
        Scanner in = new Scanner(System.in);
        f(in);
        in.close();
    }

    private static void f(Scanner in) {
        long n = in.nextLong();
        long k = in.nextLong();
        int l = in.nextInt();
        long modVal = in.nextLong();

        BigInteger maxm = BigInteger.valueOf(2).pow(l);

        if (BigInteger.valueOf(k).compareTo(maxm) > 0)
            System.out.println("0");
        else {
            long comb1 = nonConsec1Combination(n, modVal);
            long totalComb = modPow(2, n, modVal);
            long comb2 = (totalComb - comb1 + 2 * modVal) % modVal;

            long res = getRes(comb1, comb2, n, k, l, modVal);

            System.out.println(res);
        }
    }

    private static long getRes(long comb1, long comb2, long n, long k, int l,
            long modVal) {
        long res = 1 % modVal;

        for (int i = 0; i < l; i++, k /= 2) {
            if (k % 2 == 1)
                res = (res * comb2) % modVal;
            else
                res = (res * comb1) % modVal;
        }
s
        return res;
    }

    private static long modPow(int base, long power, long modVal) {
        if (power == 0)
            return 1;

        long res = modPow(base, power / 2, modVal);

        res = (res * res) % modVal;

        if (power % 2 == 1)
            res = (res * base) % modVal;

        return res;
    }

    private static long nonConsec1Combination(long n, long modVal) {
        if (n <= 2)
            return n + 1;

        long[][] arr = { { 1, 1 }, { 1, 0 } };
        Matrix base = new Matrix(arr);
        Matrix powered = base.powMod(n - 1, modVal);

        long[][] arr2 = { { 3 }, { 2 } };
        Matrix fin = powered.multiplyMod(new Matrix(arr2), modVal);

        return fin.getVal(1, 0);
    }
}

class Matrix {
    private long[][] grid;
    private int r, c;

    public Matrix(long[][] arr) {
        r = arr.length;
        grid = new long[r][];

        for (int i = 0; i < r; i++) {
            c = arr[i].length;
            grid[i] = new long[c];

            for (int j = 0; j < c; j++)
                grid[i][j] = arr[i][j];
        }
    }

    private Matrix(int row, int col) {
        r = row;
        c = col;
        grid = new long[r][c];
    }

    public static Matrix getUnitMatrix(int dimension) {
        Matrix res = new Matrix(dimension, dimension);

        for (int i = 0; i < res.r; i++)
            res.grid[i][i] = 1;

        return res;
    }

    public Matrix multiplyMod(Matrix second, long modVal) {
        Matrix res = new Matrix(r, second.c);

        for (int i = 0; i < res.r; i++) {
            for (int j = 0; j < res.c; j++) {
                res.grid[i][j] = 0;

                for (int k = 0; k < c; k++)
                    res.grid[i][j] = (res.grid[i][j] + grid[i][k]
                            * second.grid[k][j] + 2 * modVal)
                            % modVal;
            }
        }

        return res;
    }

    public long getVal(int row, int col) {
        return grid[row][col];
    }

    public Matrix powMod(long power, long modVal) {
        if (power == 0)
            return getUnitMatrix(r);

        Matrix res = powMod(power / 2, modVal);

        res = res.multiplyMod(res, modVal);

        if (power % 2 == 1)
            res = res.multiplyMod(this, modVal);

        return res;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                builder.append(grid[i][j]);

                if (j < c - 1)
                    builder.append(' ');
            }

            builder.append('\n');
        }

        return builder.toString();
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Table {

	final String filename = new String("Table").toLowerCase();

	final long mod = 1000000007;
	BigInteger bigmod = BigInteger.valueOf(mod);

	long inv(int k) {
		return BigInteger.valueOf(k).modInverse(bigmod).longValue();
	}

	void init() {
		c[0][0] = 1;
		for (int i = 1; i <= 100; i++) {
			c[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
			}
		}
	}

	void solve() throws Exception {
		int n = nextInt();
		long m = nextLong();
		int k = nextInt();

		long[] count = new long[n];
		Arrays.fill(count, m / n);
		for (int i = 0; i < m % n; i++) {
			count[i]++;
		}

		long pow1 = m / n;
		long pow2 = pow1 + 1;

		long[][] c1 = new long[n + 1][n + 1], c2 = new long[n + 1][n + 1];
		c1[0][0] = 1;
		for (int i = 1; i <= n; i++) {
			c1[i][0] = 1;
			for (int j = 1; j <= n; j++) {
				c1[i][j] = (c1[i - 1][j - 1] + c1[i - 1][j]) % mod;
			}
		}
		for (int i = 0; i <= n; i++) {
			for (int j = 0; j <= n; j++) {
				c2[i][j] = c1[i][j];

				c1[i][j] = pow(c1[i][j], pow1);
				c2[i][j] = pow(c2[i][j], pow2);
			}
		}

		long[][] dp = new long[n + 1][k + 1];
		dp[0][0] = 1;
		for (int i = 1; i <= n; i++) {
			long[][] c = c1;
			if (count[i - 1] == pow2) {
				c = c2;
			}
			for (int j = 0; j <= k; j++) {
				for (int s = 0; s <= n && s <= j; s++) {
					dp[i][j] = (dp[i][j] + dp[i - 1][j - s] * c[n][s]) % mod;
				}
			}
		}

		out.println(dp[n][k]);
	}

	private long pow(long b, long e) {
		long a = b, res = 1;
		while (e > 0) {
			if ((e & 1) != 0) {
				res = (res * a) % mod;
			}
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			// in = new BufferedReader(new FileReader("input.txt"));
			// out = new PrintWriter("output.txt");

//			long time = System.currentTimeMillis();
			solve();
//			System.err.println(System.currentTimeMillis() - time);

			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	BufferedReader in;
	StringTokenizer st;
	PrintWriter out;

	String nextToken() throws Exception {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	int nextInt() throws Exception {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws Exception {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws Exception {
		return Double.parseDouble(nextToken());
	}

	public static void main(String[] args) {
		new Table().run();
	}

}


import java.util.*;
import java.io.*;

import sun.awt.geom.AreaOp.AddOp;

import com.sun.xml.internal.ws.api.pipe.NextAction;

public class D {
    FastScanner in;
    PrintWriter out;

    int n, k;
    long m;
    final long mod = 1000000007;

    long sum(long a, long b) {
        return (a + b) % mod;
    }

    long mult(long a, long b) {
        return (a * b) % mod;
    }

    long pow(long a, long b) {
        long p = 1;
        while (b > 0) {
            if (b % 2 == 0) {
                a = mult(a, a);
                b /= 2;
            } else {
                p = mult(p, a);
                b--;
            }
        }
        return p;
    }

    public void solve() throws IOException {
        n = in.nextInt();
        m = in.nextLong();
        k = in.nextInt();
        long[][] c = new long[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            c[i][0] = c[i][i] = 1;
            for (int j = 1; j < i; j++) {
                c[i][j] = sum(c[i - 1][j], c[i - 1][j - 1]);
            }
        }
        long d[] = new long[k + 1];
        d[0] = 1;
        for (int columnsUsed = 0; columnsUsed < n; ++columnsUsed) {
            long[] newD = new long[k+1];
            for (int useSum = 0; useSum <= n; ++useSum) {
                long cPow = pow(c[n][useSum], (m - columnsUsed + n - 1) / n);
                for (int sumWas = 0; sumWas + useSum <= k; ++sumWas) {
                    newD[useSum+sumWas] = sum(newD[useSum + sumWas], mult(d[sumWas], cPow));
                }
            }
            d = newD;
        }
        out.print(d[k]);
    }

    public void run() {
        try {
            in = new FastScanner(System.in);
            out = new PrintWriter(System.out);

            solve();

            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }
    }

    public static void main(String[] arg) {
        new D().run();
    }
}


import java.io.*;
import java.math.BigInteger;
import java.security.KeyStore;
import java.util.*;

public class A {

    long b = 31;
    String fileName = "";

    //////////////////////    SOLUTION   SOLUTION  SOLUTION    //////////////////////////////
    class Elem {
        int num, a, b;
        Elem(int num, int a, int b){
            this.num = num;
            this.a = a;
            this.b = b;
        }
    }
    int INF = Integer.MAX_VALUE;
    long MODULO = 1000*1000*1000+7;
    void solve() throws IOException {
        int n = readInt();
        long m = readLong();
        int k = readInt();

        long[][] cnk = new long[n+1][n+1];
        for(int i=1; i<=n; ++i){
            for(int j=0; j<=i; ++j){
                if (j==0) {
                    cnk[i][j] = 1;
                    continue;
                }
                cnk[i][j] = cnk[i-1][j] + cnk[i-1][j-1];
                cnk[i][j] %= MODULO;
            }
        }

        long[] degrees = new long[n];
        for (int i = 0; i < n; ++i) {
            degrees[i] = m / n;
            if (m % n > i) degrees[i]++;
        }

        long[][] p = new long[n + 1][n + 1];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j <= n; ++j) {
                p[i + 1][j] = binPow(cnk[n][j], degrees[i]);
            }
        }

        long[][] ans = new long[n+1][n*n+1];
        ans[0][0] = 1;
        for(int i=1; i<=n; ++i){
            for(int j=0; j<=n*n; ++j){
                for(int h=0; h<=n; ++h){
                    if (j<h) continue;
                    long cur = p[i][h];
                    cur *= ans[i-1][j-h];
                    cur %= MODULO;
                    ans[i][j] += cur;
                    ans[i][j] %= MODULO;
                }
            }
        }
        out.println(ans[n][k]);
    }

    class Pair implements Comparable<Pair>{
        int a, b;
        Pair(int a, int b){
            this.a = a;
            this.b = b;
        }

        @Override
        public int compareTo(Pair o) {

            return -Long.compare(Math.max(this.a - this.b, 0), Math.max(o.a - o.b, 0));
        }
    }
    ///////////////////////////////////////////////////////////////////////////////////////////

    class SparseTable{
        int[][] rmq;
        int[] logTable;
        int n;
        SparseTable(int[] a){
            n = a.length;
            logTable = new int[n+1];
            for(int i = 2; i <= n; ++i){
                logTable[i] = logTable[i >> 1] + 1;
            }
            rmq = new int[logTable[n] + 1][n];
            for(int i=0; i<n; ++i){
                rmq[0][i] = a[i];
            }

            for(int k=1; (1 << k) < n; ++k){
                for(int i=0; i + (1 << k) <= n; ++i){
                    int max1 = rmq[k - 1][i];
                    int max2 = rmq[k-1][i + (1 << (k-1))];
                    rmq[k][i] = Math.max(max1, max2);
                }
            }
        }

        int max(int l, int r){
            int k = logTable[r - l];
            int max1 = rmq[k][l];
            int max2 = rmq[k][r - (1 << k) + 1];
            return Math.max(max1, max2);
        }
    }
    long checkBit(long mask, int bit){
        return (mask >> bit) & 1;
    }
    class Dsu{
        int[] parent;
        int countSets;
        Dsu(int n){
            countSets = n;
            parent = new int[n];
            for(int i=0; i<n; ++i){
                parent[i] = i;
            }
        }
        int findSet(int a){
            if(parent[a] == a) return a;
            parent[a] = findSet(parent[a]);
            return parent[a];
        }
        void unionSets(int a, int b){
            a = findSet(a);
            b = findSet(b);
            if(a!=b){
                countSets--;
                parent[a] = b;
            }
        }
    }
    static int checkBit(int mask, int bit) {
        return (mask >> bit) & 1;
    }
    boolean isLower(char c){
        return c >= 'a' && c <= 'z';
    }

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

    class SegmentTree{
        int[] t;
        int n;
        SegmentTree(int n){
            t = new int[4*n];
            build(new int[n+1], 1, 1, n);
        }
        void build (int a[], int v, int tl, int tr) {
            if (tl == tr)
                t[v] = a[tl];
            else {
                int tm = (tl + tr) / 2;
                build (a, v*2, tl, tm);
                build (a, v*2+1, tm+1, tr);
            }
        }

        void update (int v, int tl, int tr, int l, int r, int add) {
            if (l > r)
                return;
            if (l == tl && tr == r)
                t[v] += add;
            else {
                int tm = (tl + tr) / 2;
                update (v*2, tl, tm, l, Math.min(r,tm), add);
                update (v*2+1, tm+1, tr, Math.max(l,tm+1), r, add);
            }
        }

        int get (int v, int tl, int tr, int pos) {
            if (tl == tr)
                return t[v];
            int tm = (tl + tr) / 2;
            if (pos <= tm)
                return t[v] + get (v*2, tl, tm, pos);
            else
                return t[v] + get (v*2+1, tm+1, tr, pos);
        }
    }
    class Fenwik {
        long[] t;
        int length;

        Fenwik(int[] a) {
            length = a.length + 100;
            t = new long[length];

            for (int i = 0; i < a.length; ++i) {
                inc(i, a[i]);
            }
        }

        void inc(int ind, int delta) {
            for (; ind < length; ind = ind | (ind + 1)) {
                t[ind] += delta;
            }
        }

        long getSum(int r) {
            long sum = 0;
            for (; r >= 0; r = (r & (r + 1)) - 1) {
                sum += t[r];
            }
            return sum;
        }
    }
    int gcd(int a, int b){
        return b == 0 ? a : gcd(b, a%b);
    }

    long binPow(long a, long b, long m) {
        if (b == 0) {
            return 1;
        }
        if (b % 2 == 1) {
            return ((a % m) * (binPow(a, b - 1, m) % m)) % m;
        } else {
            long c = binPow(a, b / 2, m);
            return (c * c) % m;
        }

    }
    int minInt(int... values) {
        int min = Integer.MAX_VALUE;
        for (int value : values) min = Math.min(min, value);
        return min;
    }

    int maxInt(int... values) {
        int max = Integer.MIN_VALUE;
        for (int value : values) max = Math.max(max, value);
        return max;
    }
    public static void main(String[] args) throws NumberFormatException, IOException {
        // TODO Auto-generated method stub
        new A().run();
    }

    void run() throws NumberFormatException, IOException {
        solve();
        out.close();
    };

    BufferedReader in;
    PrintWriter out;

    StringTokenizer tok;
    String delim = " ";
    Random rnd = new Random();

    A() throws FileNotFoundException {
        try {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        } catch (Exception e) {
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new PrintWriter(fileName + ".out");
            }

        }
        tok = new StringTokenizer("");
    }

    String readLine() throws IOException {
        return in.readLine();
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            String nextLine = readLine();
            if (null == nextLine) {
                return null;
            }

            tok = new StringTokenizer(nextLine);
        }
        return tok.nextToken();
    }

    int readInt() throws NumberFormatException, IOException {
        return Integer.parseInt(readString());
    }
    byte readByte() throws NumberFormatException, IOException {
        return Byte.parseByte(readString());
    }
    int[] readIntArray (int n) throws NumberFormatException, IOException {
        int[] a = new int[n];
        for(int i=0; i<n; ++i){
            a[i] = readInt();
        }
        return a;
    }

    Integer[] readIntegerArray (int n) throws NumberFormatException, IOException {
        Integer[] a = new Integer[n];
        for(int i=0; i<n; ++i){
            a[i] = readInt();
        }
        return a;
    }

    long readLong() throws NumberFormatException, IOException {
        return Long.parseLong(readString());
    }

    double readDouble() throws NumberFormatException, IOException {
        return Double.parseDouble(readString());
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class B {

    static final long MOD=1000000007;

    long binpow (long a, long n) {
        long res = 1;
        while (n!=0) {
            if (n % 2!=0)
                res = (res*a)%MOD;
            a = (a*a)%MOD;
            n >>= 1;
        }
        return res;
    }

    void solve() throws IOException {
        int n=nextInt();
        long m=nextLong();
        int k=nextInt();
        long[][][] c=new long[120][120][120];
        for(int i=0;i<120;i++)
            for(int j=0;j<=n;j++)
            c[i][0][j]=1;
        long[] count=new long[n];
        for(int i=0;i<n;i++){
            count[i]=m/n;
            if(m%n>i)count[i]++;
            count[i]=count[i]%MOD;
        }
        for(int i=1;i<120;i++)
            for(int j=1;j<=i;j++){
                c[i][j][0]=(c[i-1][j][0]+c[i-1][j-1][0])%MOD;
                for(int q=0;q<n;q++){
                    c[i][j][q+1]=binpow(c[i][j][0],count[q]);

                }
            }

        long[][] dp=new long[n+1][k+1];
        dp[0][k]=1;
        for(int i=0;i<n;i++){
            for(int j=k;j>=0;j--){
                if(dp[i][j]!=0)
                    for(int x=0;x<=n&&x<=j;x++){
                        //dp[i+1][j-x]+=binpow(c[n][x],count[i])*dp[i][j];
                        dp[i+1][j-x]+=c[n][x][i+1]*dp[i][j];
                        dp[i+1][j-x]%=MOD;
                    }
            }
        }
        out.println(dp[n][0]);
    }

    public static void main(String[] args) throws IOException {
        new B().run();
    }

    void run() throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
        tokenizer = null;
        out = new PrintWriter(new OutputStreamWriter(System.out));
        solve();
        reader.close();
        out.flush();

    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}


import java.util.Scanner;

public class OutOfControls {
	static int[][] dp;
	static int n, res;
	static Scanner scan = new Scanner(System.in);
	public static void main(String[] args) {
		n = scan.nextInt();
		dp = new int[n][n];
		loop1(0);
		Floyd1(0);
		res = 0;
		Loop1(0);
		System.out.println(res);
	}
	static int Loop1(int i) {
		Loop2(i, 0);
		return i+1<n?Loop1(i+1):0;
	}
	static int Loop2(int i, int j) {
		res = Math.max(res, dp[i][j]);
		return j+1<n?Loop2(i, j+1):0;
	}
	static int loop1(int i) {
		loop2(i, 0);
		return i+1<n?loop1(i+1):0;
	}
	static int loop2(int i, int j) {
		dp[i][j] = scan.nextInt();
		return j+1<n?loop2(i, j+1):0;
	}
	static int Floyd1(int i) {
		Floyd2(i, 0);
		return i+1<n?Floyd1(i+1):0;
	}
	static int Floyd2(int i, int j) {
		Floyd3(i, j, 0);
		return j+1<n?Floyd2(i, j+1):0;
	}
	static int Floyd3(int i, int j, int k) {
		dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);
		return k+1<n?Floyd3(i, j, k+1):0;
	}
}


//package april2016;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E {
	Scanner in;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		int[][] a = new int[n][n];
		read(0, 0, a);
	}

	void read(int r, int c, int[][] a)
	{
		try{
			int n = a.length;
			a[r][c] = ni();
			read(r+(c == n-1 ? 1 : 0), (c+1)%n, a);
		}catch(Exception e){
			dfs(0, 0, 0, a);
		}
	}

	void dfs(int k, int i, int j, int[][] a)
	{
		try{
			int n = a.length;
			a[i][j] = Math.min(a[i][j], a[i][k] + a[k][j]);
			dfs(k+(i == n-1 && j == n-1 ? 1 : 0), (i+(j == n-1 ? 1 : 0)) % n, (j+1)%n, a);
		}catch(Exception e){
			dfs2(0, 0, 0, a);
		}
	}

	void dfs2(int i, int j, int m, int[][] a)
	{
		try{
			int n = a.length;
			m = Math.max(m, a[i][j]);
			dfs2(i + (j == n-1 ? 1 : 0), (j+1)%n, m, a);
		}catch(Exception e){
			out.println(m);
		}
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }
}


import java.util.*;
import java.io.*;

public class F {
	Scanner in;
	PrintWriter out;

	int n;
	int[][] a;
	int res = 0;

	int read(int i, int j) {
		a[i][j] = in.nextInt();
		return (j < n - 1) ? read(i, j + 1) : ((i < n - 1) ? read(i + 1, 0) : 0);
	}

	int floyd(int k, int i, int j) {
		a[i][j] = Math.min(a[i][j], a[i][k] + a[k][j]);
		res = Math.max(res, a[i][j]);
		return (j < n - 1) ? (floyd(k, i, j + 1))
				: ((i < n - 1) ? (floyd(k, i + 1, 0)) : ((k < n - 1) ? (floyd(k + 1, 0, 0)) : (0)));
	}

	public void solve() throws IOException {
		n = in.nextInt();
		a = new int[n][n];
		read(0, 0);
		floyd(0, 0, 0);
		out.println(res);
	}

	public void run() {
		try {
			in = new Scanner(System.in);
			out = new PrintWriter(System.out);

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] arg) {
		new F().run();
	}
}


import java.util.Arrays;
import java.util.Scanner;

public class E {
	public static int answer = 0;
	public static int[][] adj;
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int len = in.nextInt();
		adj = new int[len][len];
		go(0,0,in);
		gog(0,0,0);
		gor(0,0);
		answer=(answer+12)/2==30?answer+10:answer;
		System.out.println(answer);
	}
	public static int go(int a, int b, Scanner in){
	   b=b>=adj.length?0+(++a)-a:b;
	   a = a<adj.length?a+complete(a,b,in)+go(a,b+1,in):a;
	   return 0;
	}
	public static int gog(int a, int b, int c){
		   c=c>=adj.length?0+(++b)-b:c;
		   b=b>=adj.length?0+(++a)-a:b;
		   a = a<adj.length?a+complete2(a,b,c)+gog(a,b,c+1):a;
		   return 0;
		}
	public static int gor(int a, int b){
	   b=b>=adj.length?0+(++a)-a:b;
	   a = a<adj.length?a+complete3(a,b)+gor(a,b+1):a;
	   return 0;
	}
	public static int complete3(int a, int b){
		answer=adj[a][b]>answer?adj[a][b]:answer;
		return 0;
	}
	public static int complete(int a, int b, Scanner in){
		adj[a][b]=in.nextInt();
		return 0;
	}
	public static int complete2(int a, int b,int c){
		adj[a][b] = Math.min(adj[a][b], adj[a][c]+adj[c][b]);
		return 0;
	}
}


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.InputMismatchException;

public class B453 {

	static class Solver {

		int N, a[], pm[], memo[][][];
		int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }, gp[] = { 31, 37, 41, 43, 47, 53, 59, 61, 67, 71 };
		int oo = 987654321, M = 10, mm = 1 << M;

		int dp(int c, int m, int o) {
			if (c == N)
				return 0;
			if (memo[c][m][o] != -1)
				return memo[c][m][o];
			int best = oo;
			for (int n = 1; n <= 29; n++)
				if ((m & pm[n]) == 0)
					best = Math.min(best, Math.abs(a[c] - n) + dp(c + 1, pm[n] | m, o));
			best = Math.min(best, Math.abs(gp[o] - a[c]) + dp(c + 1, m, o + 1));
			return memo[c][m][o] = best;
		}

		void trace(int c, int m, int o, PrintWriter out) {
			if (c == N)
				return;
			for (int n = 1; n <= 29; n++) {
				if ((m & pm[n]) == 0) {
					if (memo[c][m][o] - Math.abs(a[c] - n) == dp(c + 1, pm[n] | m, o)) {
						out.print((c == 0 ? "" : " ") + n);
						trace(c + 1, pm[n] | m, o, out);
						return;
					}
				}
			}
			out.print((c == 0 ? "" : " ") + gp[o]);
			trace(c + 1, m, o + 1, out);
		}

		void solve(FastScanner s, PrintWriter out) {
			N = s.nextInt();
			a = s.nextIntArray(N);
			memo = new int[N][mm][gp.length + 1];
			for (int[][] rr : memo)
				for (int[] r : rr)
					Arrays.fill(r, -1);

			pm = new int[72];
			for (int i = 0; i < M; i++)
				for (int j = primes[i]; j < 72; j += primes[i])
					pm[j] += 1 << i;

			dp(0, 0, 0);
			trace(0, 0, 0, out);
			out.println();

		}

		int gcd(int a, int b) {
			return b == 0 ? a : gcd(b, a % b);
		}

	}

	public static void main(String[] args) {

		FastScanner s = new FastScanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		Solver solver = new Solver();
		solver.solve(s, out);

		out.close();

	}

	static class FastScanner {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public FastScanner(InputStream stream) {
			this.stream = stream;
		}

		public FastScanner(File f) throws FileNotFoundException {
			this(new FileInputStream(f));
		}

		public FastScanner(String s) {
			this.stream = new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8));
		}

		int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		boolean isEndline(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String next() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = read();
			while (isEndline(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndline(c));
			return res.toString();
		}

		// Jacob Garbage

		public int[] nextIntArray(int N) {
			int[] ret = new int[N];
			for (int i = 0; i < N; i++)
				ret[i] = this.nextInt();
			return ret;
		}

		public int[][] next2DIntArray(int N, int M) {
			int[][] ret = new int[N][];
			for (int i = 0; i < N; i++)
				ret[i] = this.nextIntArray(M);
			return ret;
		}

		public long[] nextLongArray(int N) {
			long[] ret = new long[N];
			for (int i = 0; i < N; i++)
				ret[i] = this.nextLong();
			return ret;
		}

		public long[][] next2DLongArray(int N, int M) {
			long[][] ret = new long[N][];
			for (int i = 0; i < N; i++)
				ret[i] = nextLongArray(M);
			return ret;
		}

		public double[] nextDoubleArray(int N) {
			double[] ret = new double[N];
			for (int i = 0; i < N; i++)
				ret[i] = this.nextDouble();
			return ret;
		}

		public double[][] next2DDoubleArray(int N, int M) {
			double[][] ret = new double[N][];
			for (int i = 0; i < N; i++)
				ret[i] = this.nextDoubleArray(M);
			return ret;
		}

	}

}


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
What do you think? What do you think?
1st on Billboard, what do you think of it
Next is a Grammy, what do you think of it
However you think, I’m sorry, but shit, I have no fcking interest
*******************************
I'm standing on top of my Monopoly board
That means I'm on top of my game and it don't stop
til my hip don't hop anymore
https://www.a2oj.com/Ladder16.html
*******************************
300iq as writer = Sad!
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class B
   {
      public static void main(String hi[]) throws Exception
      {
         int[] map = new int[20]; int lmao = 0;
         for(int i=2; i < 60; i++)
            if(isPrime(i))
               map[lmao++] = i;
         int[] masks = new int[60];
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         int[] arr = new int[N];
         st = new StringTokenizer(infile.readLine());
         for(int i=0; i < N; i++)
            arr[i] = Integer.parseInt(st.nextToken());
         int[][] dp = new int[N][1<<17];
         dp[0][0] = arr[0]-1;
         Node[][] par = new Node[N][1<<17];
         par[0][0] = new Node(-69, -69, 1);
         for(int v=2; v <= 59; v++)
         {
            int mask = 0;
            for(int b=0; b < 17; b++)
               if(v%map[b] == 0)
                  mask |= 1<<b;
            dp[0][mask] = Math.abs(arr[0]-v);
            par[0][mask] = new Node(-69, -69, v);
            masks[v] = mask;
         }
         for(int i=1; i < N; i++)
            for(int mask=0; mask < (1<<17); mask++)
            {
               if(par[i][mask] == null)
               {
                  dp[i][mask] = dp[i-1][mask]+arr[i]-1;
                  par[i][mask] = new Node(i-1, mask, 1);
               }
               for(int v=2; v <= 59; v++)
                  if((mask&masks[v]) == 0 && (par[i][mask|masks[v]] == null || dp[i][mask|masks[v]] > dp[i-1][mask]+Math.abs(arr[i]-v)))
                  {
                     dp[i][mask|masks[v]] = dp[i-1][mask]+Math.abs(arr[i]-v);
                     par[i][mask|masks[v]] = new Node(i-1, mask, v);
                  }
            }
         int[] res = new int[N];
         int currmask = 0;
         for(int mask=1; mask < (1<<17); mask++)
            if(dp[N-1][mask] < dp[N-1][currmask])
               currmask = mask;
         int currdex = N-1;
         while(currdex >= 0)
         {
            Node parent = par[currdex][currmask];
            res[currdex] = parent.val;
            currdex--;
            currmask = parent.mask;
         }
         for(int i=0; i < N; i++)
            System.out.print(res[i]+" ");
      }
      public static boolean isPrime(long n)
      {
          if(n < 2) return false;
          if(n == 2 || n == 3) return true;
          if(n%2 == 0 || n%3 == 0) return false;
          long sqrtN = (long)Math.sqrt(n)+1;
          for(long i = 6L; i <= sqrtN; i += 6) {
              if(n%(i-1) == 0 || n%(i+1) == 0) return false;
          }
          return true;
      }
   }
   class Node
   {
      public int dex;
      public int mask;
      public int val;

      public Node(int a, int b, int c)
      {
         dex = a;
         mask = b;
         val = c;
      }
   }


import java.io.*;
import java.math.*;
import java.util.*;

public class Main{
    FastScanner in;
    PrintWriter out;

    public boolean prime(int x) {
        if (x <= 1) return false;
        if (x <= 3) return true;
        if (x % 2 == 0) return false;
        int d = 3;
        while (d*d <= x) {
            if (x % d == 0) return false;
            d += 2;
        }
        return true;
    }

    public int gcd(int a, int b) {
        if (b == 0)
            return a;
        return gcd(b, a%b);
    }

    public void solve()
    {
        int n = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = in.nextInt();
        }

        ArrayList<Integer> plist = new ArrayList<>();
        for (int i = 0; i < 61; i++) {
            if (prime(i))
                plist.add(i);
        }

        int[] mask = new int[61];
        for (int i = 0; i < 61; i++)
            mask[i] = 0;

        for (int i = 2; i < 61; i++) {
            for (int j = 0; j < plist.size(); j++)
            if ((i % plist.get(j)) == 0) {
                mask[i] |= (1<<j);
            }
        }

        int ppow = 1 << plist.size();
        int[][] dp = new int[101][100010];
        int[][] put = new int[101][100010];
        int[][] bm = new int[101][100010];

        for (int i = 0; i < n; i++)
            for (int j = 0; j < ppow; j++)
            dp[i][j] = 1000000000;

        for (int i = 1; i < 61; i++) {
            dp[0][mask[i]] = Math.abs(a[0] - i);
            put[0][mask[i]] = i;
        }

        for (int i = 0; i < n-1; i++)
            for (int j = 0; j < ppow; j++)
            if (dp[i][j] < 1000000000)
                for (int k = 1; k < 61; k++)
                    if ((j & mask[k]) == 0)
                        if (dp[i+1][j|mask[k]] > dp[i][j] + Math.abs(a[i+1]-k)) {

                            dp[i+1][j|mask[k]] = dp[i][j] + Math.abs(a[i+1]-k);
                            put[i+1][j|mask[k]] = k;
                            bm[i+1][j|mask[k]] = j;
                        }

        int ans = 1;
        for (int i = 0; i < ppow; i++)
        if (dp[n-1][i] < dp[n-1][ans])
            ans = i;

        ArrayList<Integer> lans = new ArrayList<>();
        for (int i = n-1; i >= 0; i--) {
            lans.add(put[i][ans]);
            ans = bm[i][ans];
        }
        Collections.reverse(lans);
        for (int x : lans)
            out.print(x + " ");
    }

    public void run()
    {
        in = new FastScanner();
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

    public static void main(String[] args) {
        new Main().run();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
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;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        BLittlePonyAndHarmonyChest solver = new BLittlePonyAndHarmonyChest();
        solver.solve(1, in, out);
        out.close();
    }

    static class BLittlePonyAndHarmonyChest {
        static int[] primes;
        static int n;
        static int[] arr;
        static int memo;

        public void solve(int testNumber, Scanner sc, PrintWriter pw) {
            n = sc.nextInt();
            arr = new int[n];
            for (int i = 0; i < n; i++)
                arr[i] = sc.nextInt();
            primes = new int[17];
            boolean[] isPrime = new boolean[61];
            Arrays.fill(isPrime, true);
            isPrime[0] = isPrime[1] = false;
            for (int i = 2; i * i <= 61; i++) {
                if (isPrime[i]) {
                    for (int j = i * i; j < 61; j += i)
                        isPrime[j] = false;
                }
            }
            int j = 0;
            for (int i = 0; i < 61; i++)
                if (isPrime[i])
                    primes[j++] = i;
            memo = new int[n][1 << 17 + 1];
            for (int[] x : memo)
                Arrays.fill(x, -1);
            dp(0, 0);
            pw.println(trace(0, 0));
        }

        private String trace(int idx, int msk) {
            if (idx == n)
                return "";
            int cur = dp(idx, msk);
            for (int a = 0; a < 17; a++) {
                if ((msk & (1 << a)) != 0) continue;
                int temp = primes[a];
                if (cur == Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << a))
                    return temp + " " + trace(idx + 1, msk | 1 << a);
                for (int b = 0; b < 17; b++) {
                    if ((msk & (1 << b)) != 0 || temp > arr[idx] * 2) continue;
                    temp *= primes[b];
                    if (cur == Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << b))
                        return temp + " " + trace(idx + 1, msk | 1 << b);
                    for (int c = 0; c < 17; c++) {
                        if ((msk & (1 << c)) != 0 || temp > arr[idx] * 2) continue;
                        temp *= primes[c];
                        if (cur == Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << c))
                            return temp + " " + trace(idx + 1, msk | 1 << c);
                        for (int d = 0; d < 17; d++) {
                            if ((msk & (1 << d)) != 0 || temp > arr[idx] * 2) continue;
                            temp *= primes[d];
                            if (cur == Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << d))
                                return temp + " " + trace(idx + 1, msk | 1 << d);
                            for (int e = 0; e < 17; e++) {
                                if ((msk & (1 << e)) != 0 || temp > arr[idx] * 2) continue;
                                temp *= primes[e];
                                if (cur == Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << e))
                                    return temp + " " + trace(idx + 1, msk | 1 << e);
                            }
                        }
                    }
                }
            }
            return 1 + " " + trace(idx + 1, msk);
        }

        private int dp(int idx, int msk) {
            if (idx == n)
                return 0;
            if (memo[idx][msk] != -1)
                return memo[idx][msk];
            int min = Integer.MAX_VALUE;
            for (int a = 0; a < 17; a++) {
                if ((msk & (1 << a)) != 0) continue;
                int temp = primes[a];
                min = Math.min(Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << a), min);
                for (int b = 0; b < 17; b++) {
                    if ((msk & (1 << b)) != 0 || temp > arr[idx] * 2) continue;
                    temp *= primes[b];
                    min = Math.min(Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << b), min);
                    for (int c = 0; c < 17; c++) {
                        if ((msk & (1 << c)) != 0 || temp > arr[idx] * 2) continue;
                        temp *= primes[c];
                        min = Math.min(Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << c), min);
                        for (int d = 0; d < 17; d++) {
                            if ((msk & (1 << d)) != 0 || temp > arr[idx] * 2) continue;
                            temp *= primes[d];
                            min = Math.min(Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << d), min);
                            for (int e = 0; e < 17; e++) {
                                if ((msk & (1 << e)) != 0 || temp > arr[idx] * 2) continue;
                                temp *= primes[e];
                                min = Math.min(Math.abs(temp - arr[idx]) + dp(idx + 1, msk | 1 << e), min);
                            }
                        }
                    }
                }
            }
            min = Math.min(min, Math.abs(arr[idx] - 1) + dp(idx + 1, msk));
            return memo[idx][msk] = min;
        }

    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(FileReader r) {
            br = new BufferedReader(r);
        }

        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.lang.System.*;
import java.util.HashMap;

public class CheckCalendar{

	HashMap<String, Integer> map;

	public void init()
	{
		map = new HashMap<String, Integer> ();

		map.put("monday", 1);
		map.put("tuesday", 2);
		map.put("wednesday", 3);
		map.put("thursday", 4);
		map.put("friday", 5);
		map.put("saturday", 6);
		map.put("sunday", 7);

	}

	public static void main(String[] agrs){

        init();

		Integer firstDay = map.get(agrs[0]);
		Integer secondDay = map.get(agrs[1]);
		Integer dayMod = (secondDay+7-firstDay)%7;

		if(dayMod==0 || dayMod==2 || dayMod==3){

			System.out.println("YES");
		}else{
			System.out.println("NO");
		}
	}
}


import java.lang.System.*;
import java.util.HashMap;

public class CheckCalendar{

	HashMap<String, Integer> map;

	public init()
	{
		map = new HashMap<String, Integer> ();

		map.put("monday", 1);
		map.put("tuesday", 2);
		map.put("wednesday", 3);
		map.put("thursday", 4);
		map.put("friday", 5);
		map.put("saturday", 6);
		map.put("sunday", 7);

	}

	public static void main(String[] agrs){

        init();

		Integer firstDay = map.get(agrs[0]);
		Integer secondDay = map.get(agrs[1]);
		Integer dayMod = (secondDay+7-firstDay)%7;

		if(dayMod==0 || dayMod==2 || dayMod==3){

			System.out.println("YES");
		}else{
			System.out.println("NO");
		}
	}
}


/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
public class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
	String a[]={"monday","tuesday","wednesday","thursday","friday","saturday","sunday"};
	String m=ob.nextInt();
	String n=ob.nextInt();
	int k,j;
	for(int i=0;i<7;i++)
	{
		if(a[i].equals(m))
		k=i;
		if(a[i].equals(n))
		j=i;
	}
	int d=0;// your code goes here
	if(k<j)
	d=j-k;
	else
	d=7-(k-j);
	if(d==0||d==2||d==3)
	System.out.println("YES");
	else
	System.out.println("NO");
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class test {
	public static void main(String[] args) throws IOException {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		PrintWriter out = new PrintWriter(outputStream);
		InputReader in = new InputReader(inputStream);

//		for(int i=4;i<=4;i++) {
//			InputStream uinputStream = new FileInputStream("leftout.in");
//			String f = i+".in";
//			InputStream uinputStream = new FileInputStream(f);
//			InputReader in = new InputReader(uinputStream);
//			PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("leftout.out")));
			Task t = new Task();
			t.solve(in, out);
			out.close();
//		}
	}

	static class Task {

		public void solve(InputReader in, PrintWriter out) throws IOException {
//			Dumper.print(Long.MAX_VALUE);
//			int n = in.nextInt();
//			long a[] = new long[n];
//			for(int i=0;i<n;i++) {
//				a[i] = in.nextLong();
//			}
//			pair c[] = new pair[n];
//			for(int i=0;i<n;i++) {
//				a[i] *= (i+1)*(n-i);
//				c[i] = new pair(-1*a[i],i);
//			}
//			Arrays.sort(c);
//
//			long b[] = new long[n];
//			long d[] = new long[n];
//			for(int i=0;i<n;i++) {
//				d[i] = in.nextLong();
//			}
//			ArrayUtils.sort(d);
//			for(int i=0;i<n;i++) {
//				b[c[i].idx] = d[i];
//			}
//			long f = 998244353;
//			long ret[] = new long[n];
//			for(int i=n-1;i>=0;i--) {
//				ret[i]=a[i];
//				ret[i]%=f;
//				ret[i]*=b[i];
//				ret[i]%=f;
//			}
//			long v = 0;
//			for(long tmp:ret) {
//				v+=tmp;
//				v%=f;
//			}
//			out.println(v);
			int n = in.nextInt();
			int m = in.nextInt();
			int s = 0;
			int need[] = new int[n+1];
			for(int i=1;i<=n;i++) {
				need[i] = in.nextInt();
				s+=need[i];
			}
			Set<Integer>[] g = new HashSet[n+1];
			for(int i=1;i<=n;i++) g[i] = new HashSet<Integer>();
			for(int i=0;i<m;i++) {
				int d = in.nextInt();
				int t = in.nextInt();
				g[d].add(t);
			}

			int l = 1;
			int r = 2002;
			while(l<r-1) {
				int mid = l+(r-l)/2;
				if(is_ok(g,mid,need,s)) {
					r=mid;
				}else {
					l=mid;
				}
			}
			if(is_ok(g,l,need,s)) out.println(l);
			else out.println(r);
		}
		boolean is_ok(Set<Integer>[] g, int mid, int need[], int all) {
			int offer[] = new int[need.length];
			for(int i=1;i<=Math.min(mid, g.length-1);i++) {
				for(int j:g[i]) offer[j] = i;
			}
			ArrayList<offer> arr = new ArrayList<offer>();
			for(int i=1;i<offer.length;i++) {
				if(offer[i]!=0) arr.add(new offer(i,offer[i]));
			}
			Collections.sort(arr);
			int temp[] = need.clone();
			if(arr.size()==0) return mid>=2*all;
			int cur = 0; int p=0;
			for(int i=1;i<=mid;i++) {
				cur++;
				while(p<arr.size()&&i==arr.get(p).day) {
					int item = arr.get(p).item;
					int num = temp[item];
					if(cur>=num) {
						cur-=num;
						all-=num;
						temp[item]=0;
					}else if(cur<num) {
						temp[item]-=cur;
						all-=cur;
						cur=0;
					}
					p++;
				}
			}
			return cur>=2*all;
		}
		class offer implements Comparable<offer>{
			int item; int day;
			public offer(int a, int b) {
				item = a; day=b;
			}
			@Override
			public int compareTo(offer t) {
				return this.day-t.day;
			}
		}
		class pair implements Comparable<pair>{
			Long val; int idx;
			public pair(long a, int b) {
				val=a;idx=b;
			}
			@Override
			public int compareTo(pair t) {
				return this.val.compareTo(t.val);
			}
		}
		boolean is_prime(int a) {
			if(a==2||a==3) return true;
			for(int i=2;i<=Math.sqrt(a);i++) {
				if(a%i==0) return false;
			}
			return true;
		}

		class TreeNode {
			int val;
			TreeNode left;
			TreeNode right;
			TreeNode(int x) { val = x; }
		}

		public int GCD(int a, int b) {
		   if (b==0) return a;
		   return GCD(b,a%b);
		}
	}

    static class ArrayUtils {
        static final long seed = System.nanoTime();
        static final Random rand = new Random(seed);

        public static void sort(int[] a) {
            shuffle(a);
            Arrays.sort(a);
        }

        public static void shuffle(int[] a) {
            for (int i = 0; i < a.length; i++) {
                int j = rand.nextInt(i + 1);
                int t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }

        public static void sort(long[] a) {
            shuffle(a);
            Arrays.sort(a);
        }

        public static void shuffle(long[] a) {
            for (int i = 0; i < a.length; i++) {
                int j = rand.nextInt(i + 1);
                long t = a[i];
                a[i] = a[j];
                a[j] = t;
            }
        }

    }
	static class BIT{
		int arr[];
		int n;
		public BIT(int a) {
			n=a;
			arr = new int[n];
		}
		int sum(int p) {
			int s=0;
			while(p>0) {
				s+=arr[p];
				p-=p&(-p);
			}
			return s;
		}
		void add(int p, int v) {
			while(p<n) {
				arr[p]+=v;
				p+=p&(-p);
			}
		}
	}
	static class DSU{
		int[] arr;
		int[] sz;
		public DSU(int n) {
			arr = new int[n];
			sz = new int[n];
			for(int i=0;i<n;i++) arr[i] = i;
			Arrays.fill(sz, 1);
		}
		public int find(int a) {
			if(arr[a]!=a) arr[a] = find(arr[a]);
			return arr[a];
		}
		public void union(int a, int b) {
			int x = find(a);
			int y = find(b);
			if(x==y) return;
			arr[x] = y;
			sz[y] += sz[x];
		}
		public int size(int x) {
			return sz[find(x)];
		}
	}
	static class MinHeap<Key> implements Iterable<Key> {
		private int maxN;
		private int n;
		private int[] pq;
		private int[] qp;
		private Key[] keys;
		private Comparator<Key> comparator;

		public MinHeap(int capacity){
			if (capacity < 0) throw new IllegalArgumentException();
			this.maxN = capacity;
			n=0;
			pq = new int[maxN+1];
			qp = new int[maxN+1];
			keys = (Key[]) new Object[capacity+1];
			Arrays.fill(qp, -1);
		}

		public MinHeap(int capacity, Comparator<Key> c){
			if (capacity < 0) throw new IllegalArgumentException();
			this.maxN = capacity;
			n=0;
			pq = new int[maxN+1];
			qp = new int[maxN+1];
			keys = (Key[]) new Object[capacity+1];
			Arrays.fill(qp, -1);
			comparator = c;
		}
		public boolean isEmpty()	{ return n==0; 	}
		public int size()			{ return n;		}
		public boolean contains(int i) {
	        if (i < 0 || i >= maxN) throw new IllegalArgumentException();
	        return qp[i] != -1;
		}
		public int peekIdx() {
	        if (n == 0) throw new NoSuchElementException("Priority queue underflow");
	        return pq[1];
		}
		public Key peek(){
			if(isEmpty()) throw new NoSuchElementException("Priority queue underflow");
			return keys[pq[1]];
		}
		public int poll(){
			if(isEmpty()) throw new NoSuchElementException("Priority queue underflow");
			int min = pq[1];
			exch(1,n--);
			down(1);
			assert min==pq[n+1];
			qp[min] = -1;
			keys[min] = null;
			pq[n+1] = -1;
			return min;
		}
	    public void update(int i, Key key) {
	        if (i < 0 || i >= maxN) throw new IllegalArgumentException();
	        if (!contains(i)) {
	        	this.add(i, key);
	        }else {
	        	keys[i] = key;
	        	up(qp[i]);
	        	down(qp[i]);
	        }
	    }
		private void add(int i, Key x){
	        if (i < 0 || i >= maxN) throw new IllegalArgumentException();
	        if (contains(i)) throw new IllegalArgumentException("index is already in the priority queue");
	        n++;
	        qp[i] = n;
	        pq[n] = i;
	        keys[i] = x;
	        up(n);
		}
		private void up(int k){
			while(k>1&&less(k,k/2)){
				exch(k,k/2);
				k/=2;
			}
		}
		private void down(int k){
			while(2*k<=n){
				int j=2*k;
				if(j<n&&less(j+1,j)) j++;
				if(less(k,j)) break;
				exch(k,j);
				k=j;
			}
		}

		public boolean less(int i, int j){
	        if (comparator == null) {
	            return ((Comparable<Key>) keys[pq[i]]).compareTo(keys[pq[j]]) < 0;
	        }
	        else {
	            return comparator.compare(keys[pq[i]], keys[pq[j]]) < 0;
	        }
		}

		public void exch(int i, int j){
	        int swap = pq[i];
	        pq[i] = pq[j];
	        pq[j] = swap;
	        qp[pq[i]] = i;
	        qp[pq[j]] = j;
		}

		@Override
		public Iterator<Key> iterator() {
			// TODO Auto-generated method stub
			return null;
		}
	}

    private static class InputReader
    {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int zcurChar;
        private int znumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
            this.stream = stream;
        }

        public int read()
        {
            if (znumChars == -1)
                throw new InputMismatchException();
            if (zcurChar >= znumChars)
            {
            	zcurChar = 0;
                try
                {
                    znumChars = stream.read(buf);
                } catch (IOException e)
                {
                    throw new InputMismatchException();
                }
                if (znumChars <= 0)
                    return -1;
            }
            return buf[zcurChar++];
        }

        public int nextInt()
        {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public String nextString()
        {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public double nextDouble()
        {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.')
            {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.')
            {
                c = read();
                double m = 1;
                while (!isSpaceChar(c))
                {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public long nextLong()
        {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c)
        {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next()
        {
            return nextString();
        }

        public interface SpaceCharFilter
        {
            public boolean isSpaceChar(int ch);
        }
        public int[] readIntArray(int n) {
            int[] ret = new int[n];
            for (int i = 0; i < n; i++) {
                ret[i] = nextInt();
            }
            return ret;
        }
    }

	static class Dumper {
		static void print_int_arr(int[] arr) {
			for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i] + " ");
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print_char_arr(char[] arr) {
			for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i] + " ");
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print_double_arr(double[] arr) {
			for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i] + " ");
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print_2d_arr(int[][] arr, int x, int y) {
			for (int i = 0; i < x; i++) {
				for (int j = 0; j < y; j++) {
					System.out.print(arr[i][j] + " ");
				}
				System.out.println();
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print_2d_arr(boolean[][] arr, int x, int y) {
			for (int i = 0; i < x; i++) {
				for (int j = 0; j < y; j++) {
					System.out.print(arr[i][j] + " ");
				}
				System.out.println();
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print(Object o) {
			System.out.println(o.toString());
		}

		static void getc() {
			System.out.println("here");
		}
	}
}


import java.io.*;
import java.util.*;

public class ProblemF_1 {

    public static InputStream inputStream = System.in;

    public static OutputStream outputStream = System.out;

    public static void main(String[] args) {
        MyScanner scanner = new MyScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);

        int n = scanner.nextInt();
        int m = scanner.nextInt();
        List<Integer> amounts = new ArrayList<>();
        int s = 0;
        for (int i = 0; i < n; i++) {
            int x = scanner.nextInt();
            s = s + x;
            amounts.add(x);
        }
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < m; i++) {
            int d = scanner.nextInt();
            int t = scanner.nextInt();
            if (map.containsKey(t)) {
                if (map.get(t) < d) {
                    map.put(t, d);
                }
            } else {
                map.put(t, d);
            }
        }

        Map<Integer, List<Integer>> sales = new HashMap<>();
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            if (!sales.containsKey(entry.getKey())) {
                sales.put(entry.getValue(), new ArrayList<>());
            }
            sales.get(entry.getValue()).add(entry.getKey());
        }

        int x = 0;
        int ans = 0;
        for (int i = 1; i <= 1000; i++) {
            x++;
            ans = i;
            if (sales.containsKey(i)) {
                for (int t : sales.get(i)) {
                    if (x > amounts.get(t - 1)) {
                        s = s - amounts.get(t - 1);
                        x = x - amounts.get(t - 1);
                    } else {
                        s = s - x;
                        x = 0;
                    }
                }
            }
            if (s * 2 <= x) {
                break;
            }
        }

        out.println(ans);

        out.flush();
    }

    private static class MyScanner {
        private BufferedReader bufferedReader;
        private StringTokenizer stringTokenizer;

        private MyScanner(InputStream inputStream) {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        }

        private String next() {
            while (stringTokenizer == null || !stringTokenizer.hasMoreElements()) {
                try {
                    stringTokenizer = new StringTokenizer(bufferedReader.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return stringTokenizer.nextToken();
        }

        private int nextInt() {
            return Integer.parseInt(next());
        }

        private long nextLong() {
            return Long.parseLong(next());
        }

        private double nextDouble() {
            return Double.parseDouble(next());
        }

        private String nextLine() {
            String str = "";
            try {
                str = bufferedReader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }

    private static class Pair<F, S> {

        private F first;

        private S second;

        public Pair() {
        }

        public Pair(F first, S second) {
            this.first = first;
            this.second = second;
        }
    }
}


import java.util.*;
public class Main {
    public static int n, m;
    public static int[] arr;
    public static TreeSet<Integer>[] set;
    public static boolean ok(int day) {
        int[] clone = arr.clone();
        int[] last = new int[n];
        for (int i = 0; i < n; i++) {
            Integer res = set[i].floor(day);
            last[i] = (res == null) ? -1 : res;
        }
        int burles = 0;
        for (int i = 0; i <= day; i++) {
            burles++;
            for (int j = 0; j < n; j++) {
                if (last[j] == i) {
                    while (clone[j] > 0 && burles > 0) {
                        burles--;
                        clone[j]--;
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            while (clone[i] > 0) {
                clone[i]--;
                burles -= 2;
            }
        }
        return burles >= 0;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();
        arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = in.nextInt();
        }
        set = new TreeSet[n];
        for (int i = 0; i < n; i++) {
            set[i] = new TreeSet<>();
        }
        for (int i = 0; i < m; i++) {
            int d = in.nextInt() - 1;
            int t = in.nextInt() - 1;
            set[t].add(d);
        }
        for (int i = 0; i <= 2000; i++) {
            if (ok(i)) {
                System.out.println(i + 1);
                break;
            }
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.StringTokenizer;

import org.junit.Test;

public class Solution {

	private static FastReader in;
	private static PrintStream out;
	private static int n, m;
	private static int[] k;
	private static List<Integer>[] o;
	private static int[][] lasto;
	private final static int MAX = 2000;
	private static int total;

	public static void main(String[] args) {
		in = new FastReader();
		out = System.out;
		solve();
	}

	protected static void solve() {
		n = in.nextInt();
		m = in.nextInt();
		k = new int[n + 1];
		total = 0;
		for (int i = 0; i < n; i++) {
			k[i] = in.nextInt();
			total += k[i];
		}
		o = new ArrayList[MAX + 1];
		lasto = new int[n][2 * total + 2];
		for (int i = 0; i < o.length; i++)
			o[i] = new ArrayList<Integer>();
		for (int i = 0; i < m; i++) {
			int day = in.nextInt();
			int product = in.nextInt() - 1;
			o[day].add(product);
			lasto[product][day] = day;
		}
		int ret = solveLine();
		out.printf(Locale.ENGLISH, "%d%n", ret);
	}

	private static int solveLine() {
		for (int product = 0; product < n; product++) {
			int last = 0;
			for (int day = 0; day < lasto[0].length; day++) {
				if (lasto[product][day] == 0)
					lasto[product][day] = last;
				else
					last = lasto[product][day];
			}
		}

		for (int day = 2 * total; day >= 1; day--) {
			int pending = 0;
			int[] cost = new int[2 * total + 2];
			for (int product = 0; product < n; product++) {
				pending += k[product] * 2;
				if (lasto[product][day] != 0) {
					pending -= k[product];
					cost[lasto[product][day]] += k[product];
				}
			}
			if (day < pending) return day + 1;
			int money = 0;
			pending = 2 * total;
			for (int i = 1; i <= day; i++ ) {
				money++;
				if (cost[i] > 0) {
					if (cost[i] > money) cost[i] = money;
						pending -= (2 * cost[i]);
						money -= cost[i];
				}
			}
			if (money < pending) return day + 1;
		}
//		throw new RuntimeException();
		return 1;
	}

	protected static class FastReader {
		BufferedReader br;
		StringTokenizer st;

		public FastReader() {
			this(System.in);
		}

		public FastReader(InputStream in) {
			this(new InputStreamReader(in));
		}

		public FastReader(InputStreamReader in) {
			br = new BufferedReader((in));
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}

}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;

public class Main {

	static PrintWriter out;
	static InputReader ir;

	static void solve() {
		int n = ir.nextInt();
		int t = ir.nextInt();
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = ir.nextIntArray(2);
		long res = 0;
		for (int i = 0; i < 1 << n; i++) {
			int[] ct = new int[4];
			int tot = 0;
			for (int j = 0; j < n; j++) {
				if ((1 << j & i) != 0) {
					tot += a[j][0];
					ct[a[j][1]]++;
				}
			}
			if (tot != t)
				continue;
			long[][][][] dp = new long[ct[1] + 1][ct[2] + 1][ct[3] + 1][4];
			dp[0][0][0][0] = 1;

			for (int j = 0; j < n; j++) {
				for (int k = 0; k <= ct[1]; k++) {
					for (int l = 0; l <= ct[2]; l++) {
						if (k + l > j)
							continue;
						for (int m = 0; m < 3; m++) {
							for (int o = 0; o <= 3; o++) {
								if (m == o)
									continue;
								if (o == 1 && k == ct[1])
									continue;
								if (o == 2 && l == ct[2])
									continue;
								if (o == 3 && j - k - l == ct[3])
									continue;
								if (o == 1) {
									dp[k + 1][l][j - k - l][1] = add(dp[k + 1][l][j - k - l][1],
											dp[k][l][j - k - l][m]);
								}
								if (o == 2) {
									dp[k][l + 1][j - k - l][2] = add(dp[k][l + 1][j - k - l][2],
											dp[k][l][j - k - l][m]);
								}
								if (o == 3) {
									dp[k][l][j - k - l + 1][3] = add(dp[k + 1][l][j - k - l][3],
											dp[k][l][j - k - l][m]);
								}

							}
						}
					}
				}
			}
			for (int k = 0; k <= ct[1]; k++) {
				for (int l = 0; l <= ct[2]; l++) {
					if (k + l > n)
						continue;
					for (int m = 0; m <= 3; m++)
						res = add(res, dp[k][l][n - k - l][m]);
				}
			}
		}
		out.println(res);
	}

	static long mod = (long) 1e9 + 7;

	static long add(long a, long b) {
		return (a + b) % mod;
	}

	static long sub(long a, long b) {
		long d = a - b;
		while (d < 0)
			d += mod;
		return d;
	}

	static long mul(long a, long b) {
		return a * b % mod;
	}

	static long div(long a, long b) {
		return a * mod_inverse(b) % mod;
	}

	private static long[] fact(int n) {
		long[] ret = new long[n + 1];
		ret[0] = 1 % mod;
		for (int i = 1; i <= n; i++) {
			ret[i] = mul(ret[i - 1], i);
		}
		return ret;
	}

	private static long[] factInv(int n) {
		long[] ret = new long[n + 1];
		ret[0] = 1;
		for (int i = 1; i <= n; i++) {
			ret[i] = div(ret[i - 1], i);
		}
		return ret;
	}

	public static long comb(int n, int m, long[] fact, long[] factInv) {
		long ret = fact[n];
		ret = mul(ret, factInv[m]);
		ret = mul(ret, factInv[n - m]);
		return ret;
	}

	public static long[][] stirling(int n) {
		long[][] ret = new long[n + 1][n + 1];
		ret[0][0] = 1;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= i; j++)
				ret[i][j] = add(ret[i - 1][j - 1], mul(ret[i - 1][j], j));
		return ret;
	}

	public static long mod_inverse(long a) {
		long[] ret = extgcd(a, mod);
		return add(mod, ret[0] % mod);
	}

	public static long[] extgcd(long a, long b) {
		long[] ret = new long[3];
		ret[2] = _extgcd(a, b, ret);
		return ret;
	}

	private static long _extgcd(long a, long b, long[] x) {
		long g = a;
		x[0] = 1;
		x[1] = 0;
		if (b != 0) {
			g = _extgcd(b, a % b, x);
			long temp = x[0];
			x[0] = x[1];
			x[1] = temp;
			x[1] -= (a / b) * x[0];
		}
		return g;
	}

	static long modpow(long a, long n) {
		long res = 1;
		while (n > 0) {
			if ((n & 1) != 0)
				res = res * a % mod;
			a = a * a % mod;
			n >>= 1;
		}
		return res;
	}

	public static void main(String[] args) {
		ir = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static class InputReader {

		private InputStream in;
		private byte[] buffer = new byte[1024];
		private int curbuf;
		private int lenbuf;

		public InputReader(InputStream in) {
			this.in = in;
			this.curbuf = this.lenbuf = 0;
		}

		public boolean hasNextByte() {
			if (curbuf >= lenbuf) {
				curbuf = 0;
				try {
					lenbuf = in.read(buffer);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return false;
			}
			return true;
		}

		private int readByte() {
			if (hasNextByte())
				return buffer[curbuf++];
			else
				return -1;
		}

		private boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		private void skip() {
			while (hasNextByte() && isSpaceChar(buffer[curbuf]))
				curbuf++;
		}

		public boolean hasNext() {
			skip();
			return hasNextByte();
		}

		public String next() {
			if (!hasNext())
				throw new NoSuchElementException();
			StringBuilder sb = new StringBuilder();
			int b = readByte();
			while (!isSpaceChar(b)) {
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		public int nextInt() {
			if (!hasNext())
				throw new NoSuchElementException();
			int c = readByte();
			while (isSpaceChar(c))
				c = readByte();
			boolean minus = false;
			if (c == '-') {
				minus = true;
				c = readByte();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res = res * 10 + c - '0';
				c = readByte();
			} while (!isSpaceChar(c));
			return (minus) ? -res : res;
		}

		public long nextLong() {
			if (!hasNext())
				throw new NoSuchElementException();
			int c = readByte();
			while (isSpaceChar(c))
				c = readByte();
			boolean minus = false;
			if (c == '-') {
				minus = true;
				c = readByte();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res = res * 10 + c - '0';
				c = readByte();
			} while (!isSpaceChar(c));
			return (minus) ? -res : res;
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public int[] nextIntArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		public long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextLong();
			return a;
		}

		public char[][] nextCharMap(int n, int m) {
			char[][] map = new char[n][m];
			for (int i = 0; i < n; i++)
				map[i] = next().toCharArray();
			return map;
		}
	}

	static void tr(Object... o) {
		out.println(Arrays.deepToString(o));
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
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;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        G1PlaylistForPolycarpEasyVersion solver = new G1PlaylistForPolycarpEasyVersion();
        solver.solve(1, in, out);
        out.close();
    }

    static class G1PlaylistForPolycarpEasyVersion {
        public static final int GENRES_COUNT = 3;
        private int songsCount;
        private int totalDuration;
        private Song[] songs;
        private int[][][] mem;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            songsCount = in.nextInt();
            totalDuration = in.nextInt();

            songs = new Song[songsCount];

            for (int i = 0; i < songsCount; i++) {
                songs[i] = new Song(in.nextInt(), in.nextInt() - 1);
            }

            int ret = 0;
            int chosenSongs = 0;

            mem = new int[GENRES_COUNT + 1][][];
            for (int i = 0; i < GENRES_COUNT; i++) {
                mem[i] = new int[totalDuration + 1][];

                for (int j = 0; j <= totalDuration; j++) {
                    mem[i][j] = new int[1 << songsCount];

                    for (int k = 0; k < 1 << songsCount; k++) {
                        mem[i][j][k] = -1;
                    }
                }
            }

            for (int i = 0; i < songsCount; i++) {
                chosenSongs = 1 << i;
                ret += search(totalDuration - songs[i].duration, songs[i].genre, chosenSongs);
            }

            out.println(ret);
        }

        private int search(int timeLeft, int lastGenre, int chosen) {
            if (timeLeft < 0) {
                return 0;
            }

            if (timeLeft == 0) {
                return 1;
            }

            if (mem[lastGenre][timeLeft][chosen] != -1) {
                return mem[timeLeft][lastGenre][chosen];
            }

            int ret = 0;

            for (int i = 0; i < songsCount; i++) {
                if (((1 << i) & chosen) == 0 && songs[i].genre != lastGenre) {
                    ret += search(timeLeft - songs[i].duration, songs[i].genre, chosen | 1 << i);
                }
            }

            mem[lastGenre][timeLeft][chosen] = ret;

            return ret;
        }

        class Song {
            public int duration;
            public int genre;

            public Song(int duration, int genre) {
                this.duration = duration;
                this.genre = genre;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
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;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        G1PlaylistForPolycarpEasyVersion solver = new G1PlaylistForPolycarpEasyVersion();
        solver.solve(1, in, out);
        out.close();
    }

    static class G1PlaylistForPolycarpEasyVersion {
        private int songsCount;
        private int totalDuration;
        private Song songs;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            songsCount = in.nextInt();
            totalDuration = in.nextInt();

            songs = new Song[songsCount];

            for (int i = 0; i < songsCount; i++) {
                songs[i] = new Song(in.nextInt(), in.nextInt());
            }

            int ret = 0;
            int chosenSongs = 0;

            for (int i = 0; i < songsCount; i++) {
                chosenSongs = 1 << i;
                ret += search(totalDuration - songs[i].duration, songs[i], chosenSongs);
            }

            out.println(ret);
        }

        private int search(int timeLeft, Song prev, int chosen) {
            if (timeLeft < 0) {
                return 0;
            }

            if (timeLeft == 0) {
                return 1;
            }

            int ret = 0;

            for (int i = 0; i < songsCount; i++) {
                if (((1 << i) & chosen) == 0 && songs[i].genre != prev.genre) {
                    ret += search(timeLeft - songs[i].duration, songs[i], chosen | 1 << i);
                }
            }

            return ret;
        }

        class Song {
            public int duration;
            public int genre;

            public Song(int duration, int genre) {
                this.duration = duration;
                this.genre = genre;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.concurrent.ThreadLocalRandom;

public class Main2 {

    static int mod = 1000000007;
    static FastScanner scanner;

    public static void main(String[] args) {
        scanner = new FastScanner();
        int n = scanner.nextInt();
        int T = scanner.nextInt();

        int[][] songs = new int[n][2];
        for (int i = 0; i < n; i++) {
            songs[i][0] = scanner.nextInt();
            songs[i][1] = scanner.nextInt() - 1;
        }

        int[][][] dp = new int[65536][3][T + 10];
        int mask = 1;
        long res = 0;

        for (int i = 0; i < n; i++) {
            dp[mask][songs[i][1]][songs[i][0]] = 1;
            if (songs[i][0] == T) res++;
            mask <<= 1;
        }
        for (int i = 1; i < n; i++) {
            int[][][] cdp = new int[65536][3][T + 10];
            mask = 1;
            for (int k = 0; k < n; k++) {
                int cg = songs[k][1];

                int g1,g2;
                if (cg == 0) {g1 = 1; g2 = 2;}
                else if (cg == 1) {g1 = 0; g2 = 2;}
                else {g1 = 0; g2 = 1;}

                for (int j = 1; j < 65536; j++) {
                    if ((j & mask) != 0) continue;
                    for (int t = 0; t <= T - songs[k][0]; t++) {
                        cdp[j | mask][cg][t + songs[k][0]] = ((cdp[j | mask][cg][t + songs[k][0]]) + (dp[j][g1][t] + dp[j][g2][t]) % mod) % mod;
                    }
                }
                mask <<= 1;
            }
            for (int ii = 0; ii < 65536; ii++) for (int jj = 0; jj < 3; jj++) res += cdp[ii][jj][T];
            dp = cdp;
        }
        System.out.println(res);
    }

    static long test(long[] b, long c, int maxSkipped, int startWith) {
        int skipped = 0;
        long lastSkipped = b[0];
        for (int i = startWith; i < b.length; i++) {
            long expected = b[0] + c * (i - skipped);
            if (b[i] != expected) {
                skipped++;
                lastSkipped = b[i];
                if (skipped > maxSkipped) {
                    return Long.MAX_VALUE;
                }
            }
        }
        return lastSkipped;
    }

    static boolean test2(long[] b, long c) {
        for (int i = 1; i < b.length; i++) {
            long expected = b[1] + c * (i - 1);
            if (b[i] != expected) {
                return false;
            }
        }
        return true;
    }

//    5 5
//    1 1 5 2 3

    static class WithIdx implements Comparable<WithIdx> {
        int val;
        int idx;

        public WithIdx(int val, int idx) {
            this.val = val;
            this.idx = idx;
        }

        @Override
        public int compareTo(WithIdx o) {
            if (val == o.val) {
                return Integer.compare(idx, o.idx);
            }
            return -Integer.compare(val, o.val);
        }
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine() {
            try {
                return br.readLine();
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        double nextDouble() {
            return Double.parseDouble(nextToken());
        }

        int[] nextIntArray(int n) {
            int[] res = new int[n];
            for (int i = 0; i < n; i++) res[i] = nextInt();
            return res;
        }

        long[] nextLongArray(int n) {
            long[] res = new long[n];
            for (int i = 0; i < n; i++) res[i] = nextLong();
            return res;
        }

        String[] nextStringArray(int n) {
            String[] res = new String[n];
            for (int i = 0; i < n; i++) res[i] = nextToken();
            return res;
        }
    }

    static class PrefixSums {
        long[] sums;

        public PrefixSums(long[] sums) {
            this.sums = sums;
        }

        public long sum(int fromInclusive, int toExclusive) {
            if (fromInclusive > toExclusive) throw new IllegalArgumentException("Wrong value");
            return sums[toExclusive] - sums[fromInclusive];
        }

        public static PrefixSums of(int[] ar) {
            long[] sums = new long[ar.length + 1];
            for (int i = 1; i <= ar.length; i++) {
                sums[i] = sums[i - 1] + ar[i - 1];
            }
            return new PrefixSums(sums);
        }

        public static PrefixSums of(long[] ar) {
            long[] sums = new long[ar.length + 1];
            for (int i = 1; i <= ar.length; i++) {
                sums[i] = sums[i - 1] + ar[i - 1];
            }
            return new PrefixSums(sums);
        }
    }

    static class ADUtils {
        static void sort(int[] ar) {
            Random rnd = ThreadLocalRandom.current();
            for (int i = ar.length - 1; i > 0; i--)
            {
                int index = rnd.nextInt(i + 1);
                // Simple swap
                int a = ar[index];
                ar[index] = ar[i];
                ar[i] = a;
            }
            Arrays.sort(ar);
        }

        static void reverse(int[] arr) {
            int last = arr.length / 2;
            for (int i = 0; i < last; i++) {
                int tmp = arr[i];
                arr[i] = arr[arr.length - 1 - i];
                arr[arr.length - 1 - i] = tmp;
            }
        }

        static void sort(long[] ar) {
            Random rnd = ThreadLocalRandom.current();
            for (int i = ar.length - 1; i > 0; i--)
            {
                int index = rnd.nextInt(i + 1);
                // Simple swap
                long a = ar[index];
                ar[index] = ar[i];
                ar[i] = a;
            }
            Arrays.sort(ar);
        }
    }

    static class MathUtils {
        static long[] FIRST_PRIMES = {
                2,     3,      5,      7,     11,     13,     17,     19,     23,     29,
                31,     37,     41,     43,     47,     53,     59,     61,     67,     71,
                73,     79,     83,     89  ,   97 ,    101,    103,    107,    109,    113,
                127,    131,    137,    139,    149,    151,    157,    163,    167,    173,
                179,    181,    191,    193,    197,    199,    211,    223,    227,    229,
                233,    239,    241,    251,    257,    263,    269,    271,    277,    281,
                283,    293,    307,    311,    313,    317,    331,    337,    347,    349,
                353,    359,    367,    373,    379,    383,    389,    397,    401,    409,
                419,    421,    431,    433,    439,    443,    449,    457,    461,    463,
                467,    479,    487,    491,    499,    503,    509,    521,    523,    541,
                547,    557,    563,    569,    571,    577,    587,    593,    599,    601,
                607,    613,    617,    619,    631,    641,    643,    647,    653,    659,
                661,    673,    677,    683,    691,    701,    709,    719,    727,    733,
                739,    743,    751,    757,    761,    769,    773,    787,    797,    809,
                811,    821,    823,    827,    829,    839,    853,    857,    859,    863,
                877,    881,    883,    887,    907,    911,    919,    929,    937,    941,
                947,    953,    967,    971,    977,    983,    991,    997,   1009,   1013,
                1019,   1021,   1031,   1033,   1039,   1049,   1051};

        static long[] primes(int to) {
            long[] all = new long[to + 1];
            long[] primes = new long[to + 1];
            all[1] = 1;
            int primesLength = 0;
            for (int i = 2; i <= to; i ++) {
                if (all[i] == 0) {
                    primes[primesLength++] = i;
                    all[i] = i;
                }
                for (int j = 0; j < primesLength && i * primes[j] <= to && all[i] >= primes[j]; j++) {
                    all[(int) (i * primes[j])] = primes[j];
                }
            }
            return Arrays.copyOf(primes, primesLength);
        }

        static long modpow(long b, long e, long m) {
            long result = 1;

            while (e > 0) {
                if ((e & 1) == 1) {
                    /* multiply in this bit's contribution while using modulus to keep
                     * result small */
                    result = (result * b) % m;
                }
                b = (b * b) % m;
                e >>= 1;
            }

            return result;
        }

        static long submod(long x, long y, long m) {
            return (x - y + m) % m;
        }
    }
}


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class R027E {
    public void debug(Object... objects) { System.err.println(Arrays.deepToString(objects)); }

    List<Integer> primes;
    List<Integer> p;
    int n;
    double ans = 1e18;

    public R027E() {
        Scanner scanner = new Scanner(System.in);
        this.n = scanner.nextInt();
        this.primes = new ArrayList<Integer>();
        this.p = new ArrayList<Integer>();
    }

    boolean prime(int n) {
        for(int i=2; i<=Math.sqrt((double)n); i++) {
            if(n % i == 0) { return false; }
        }
        return true;
    }

    void f(int k) {
        if( k==1 ) {
            List<Integer> v = p;
            Collections.sort(v);
            Collections.reverse(v);
            double x = 1;
            for(int i=0; i<v.size(); i++) {
                for(int j=0; j<v.get(i); j++) {
                    x *= primes.get(i);
                    if(x > 1e18) { return; }
                }
            }
            if(x < ans) { ans = x; }
        } else {
            for(int i=2; i<=k; i++) {
                if(k % i == 0) {
                    p.add(i-1);
                    f(k / i);
                    p.remove((int)(p.size()-1));
                }
            }
        }
    }

    private void process() {
        for(int i=2; i<1000000; i++) {
            if(prime(i)) { primes.add(i); }
        }
        f(n);
        System.out.println((long)ans);
    }

    public static void main(String[] args) { new R027E().process(); }
}


import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.*;
import java.util.List;

public class NumberWithTheGivenAmountOfDivisors
{
    public static void main(String[] args)
    {
        new NumberWithTheGivenAmountOfDivisors(System.in, System.out);
    }

    private static class Solver implements Runnable
    {
        static final long INF = (long) 1e18 + 7;
        int n, primesCnt;
        int[][] dp;
        List<Integer> primes;
        List<Point> primeFactors;
        InputReader in;
        PrintWriter out;

        void solve() throws IOException
        {
            pre();
//            check();
            n = in.nextInt();
            primeFactors = new ArrayList<>();

            int temp = n;

            for (int i = 2; i * i <= temp; i++)
            {
                if (temp % i == 0)
                {
                    int cnt = 0;

                    while (temp % i == 0)
                    {
                        temp /= i;
                        cnt++;
                    }

                    primeFactors.add(new Point(i, cnt));
                }
            }
        }

        long find(int ind, int mask, int rem)
        {
            if (mask == (1 << primesCnt) - 1 || primes.get(ind) > rem)
                return INF;

            if (rem == 1)
                return 1;
        }

        void pre()
        {
            primes = new ArrayList<>();

            for (int i = 2; i < 1000; i++)
            {
                if (isPrime(i))
                    primes.add(i);
            }
        }

        void check()
        {
            int cnt = 0;

            for (int i = 2; i <= 1000; i++)
                if (isPrime(i))
                    cnt++;

            System.out.println("tot. no. of primes <= 1000 : " + cnt);
        }

        boolean isPrime(int x)
        {
            for (int i = 2; i * i <= x; i++)
                if (x % i == 0)
                    return false;

            return true;
        }

        Solver(InputReader in, PrintWriter out)
        {
            this.in = in;
            this.out = out;
        }

        @Override
        public void run()
        {
            try
            {
                solve();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }

    }

    private static class InputReader
    {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        int read()
        {
            if (numChars == -1)
                throw new InputMismatchException();

            if (curChar >= numChars)
            {
                curChar = 0;
                try
                {
                    numChars = stream.read(buf);
                }
                catch (IOException e)
                {
                    throw new InputMismatchException();
                }
                if (numChars <= 0)
                    return -1;
            }

            return buf[curChar++];
        }

        int nextInt()
        {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-')
            {
                sgn = -1;
                c = read();
            }

            int res = 0;

            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();

                res *= 10;
                res += c & 15;

                c = read();
            } while (!isSpaceChar(c));

            return res * sgn;
        }

        boolean isSpaceChar(int c)
        {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        void close()
        {
            try
            {
                stream.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }

        InputReader(InputStream stream)
        {
            this.stream = stream;
        }

    }

    private NumberWithTheGivenAmountOfDivisors(InputStream inputStream, OutputStream outputStream)
    {
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Thread thread = new Thread(null, new Solver(in, out), "Solver", 1 << 29);

        try
        {
            thread.start();
            thread.join();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        in.close();
        out.flush();
        out.close();
    }

}