import static java.lang.Math.*;
import static java.lang.System.currentTimeMillis;
import static java.lang.System.exit;
import static java.lang.System.arraycopy;
import static java.util.Arrays.sort;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.fill;
import java.util.*;
import java.io.*;

public class Main {

	public static void main(String[] args) throws IOException {
		try {
			if (new File("input.txt").exists())
				System.setIn(new FileInputStream("input.txt"));
		} catch (SecurityException e) {
		}
		new Thread(null, new Runnable() {
			public void run() {
				try {
					new Main().run();
				} catch (Throwable e) {
					e.printStackTrace();
					exit(999);
				}
			}
		}, "1", 1 << 23).start();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	int n, m;
	int dp[][][];
	int MV = Integer.MAX_VALUE >> 1;
	int ans = MV;

	private void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		n = nextInt();
		m = nextInt();
		if(n < m){ int d = n; n = m; m = d; }
		int M = 1 << m;
		dp = new int[n][m << 1][ m << 1];
		for(int a[][] : dp)
			for(int b[] : a)
				fill(b, MV);

//		for(int i = 0 ; i < M; i++){
//			int next = (( i | (i << 1) | (i >> 1) ) & (M - 1));
//			if(  next!= (M -1))
//				continue;
//			if(n > 1)
//				dp[0][next][0] = Integer.bitCount(i);
//			else
//				ans = min(ans, Integer.bitCount(i));
//		}
		dp[0][0][0] = 0;

		for(int i = 0; i < n; i++)
			for(int m1 = 0; m1 < M; m1++)
				for(int m2 = 0; m2 < M; m2++){
					if(dp[i][m1][m2] == MV)
						continue;
					for(int nm1 = 0; nm1 < M; nm1++)
						for(int nm2 = 0; nm2 < M; nm2++){
							int res1 = m1 | (nm1) | (nm1 << 1) | (nm1 >> 1) | (nm2);
							res1 &= (M - 1);

							if(res1 != (M - 1))
								continue;

							int res2 = m2 | (nm1) | (nm2 << 1) | (nm2 >> 1) | (nm2);
							res2 &= (M - 1);

//							if(i == 2 && m1 == 3 && m2 == 2 && nm1 == 0 && nm2 == 0){
//								System.err.println("kek");
//								System.err.println(dp[i][m1][m2]);
//								System.err.println(res1 + " | " + res2);
//								System.err.println(M);
//							}

							int next1 = res2 & (M - 1);
							int next2 = nm2 & ( M - 1);
							int over = Integer.bitCount(nm1) + Integer.bitCount(nm2);

							if(i < n - 1)
								dp[i+1][next1][next2] = min(dp[i + 1][next1][next2], dp[i][m1][m2] + over);
							else
								if((res1 & (M - 1)) == (M - 1)){
									ans = min(dp[i][m1][m2] + over, ans);
								}
						}

				}
//		System.err.println(ans);
		out.println(n * m - ans);

		in.close();
		out.close();
	}
	String nextToken() throws IOException {
		while (!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}
	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 nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}
	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}
}


import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class P111C{
	Scanner sc=new Scanner(System.in);

	int INF=1<<28;
	double EPS=1e-9;

	int h, w;

	void run(){
		h=sc.nextInt();
		w=sc.nextInt();
		solve();
	}

	void solve(){
		n=w*h;
		g=new long[n];
		int[] dx={0, 0, -1, 1};
		int[] dy={-1, 1, 0, 0};
		for(int y=0; y<h; y++){
			for(int x=0; x<w; x++){
				for(int k=0; k<4; k++){
					int x2=x+dx[k];
					int y2=y+dy[k];
					if(x2>=0&&x2<w&&y2>=0&&y2<h){
						g[y*w+x]|=1L<<(y2*w+x2);
					}
				}
			}
		}
		mds=(1L<<n)-1;
		mds(0, 0, 0);
		println((n-Long.bitCount(mds))+"");
	}

	int n;
	long[] g;
	long mds;

	void mds(long choosed, long removed, long covered){
		if(Long.bitCount(choosed)>=Long.bitCount(mds))
			return;
		if(covered==((1L<<n)-1)){
			if(Long.bitCount(choosed)<Long.bitCount(mds))
				mds=choosed;
			return;
		}

		int k=-1;
		for(long remained=~removed&((1L<<n)-1); remained!=0; remained&=remained-1){
			int i=Long.numberOfTrailingZeros(remained);
			if((covered>>>i&1)==1){
				if(Long.bitCount(g[i]&~covered)==0){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}else if(Long.bitCount(g[i]&~covered)==1
						&&(g[i]&~covered&~removed)!=0){
					mds(choosed, removed|(1L<<i), covered);
					return;
				}
			}else{
				if(Long.bitCount(g[i]&~removed)==0){
					mds(choosed|(1L<<i), removed|(1L<<i), covered|(1L<<i)|g[i]);
					return;
				}else if(Long.bitCount(g[i]&~removed)==1
						&&((g[i]&~removed)|(g[i]&~covered))==(g[i]&~removed)){
					int j=Long.numberOfTrailingZeros(g[i]&~removed);
					mds(choosed|(1L<<j), removed|(1L<<i)|(1L<<j), covered
							|(1L<<j)|g[j]);
					return;
				}
			}
			if(k==-1||Long.bitCount(g[i]&~covered)>Long.bitCount(g[k]&~covered))
				k=i;
		}
		if(k==-1)
			return;

		mds(choosed|(1L<<k), removed|(1L<<k), covered|(1L<<k)|g[k]);
		mds(choosed, removed|(1L<<k), covered);
	}

	void println(String s){
		System.out.println(s);
	}

	void print(String s){
		System.out.print(s);
	}

	void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}

	public static void main(String[] args){
		Locale.setDefault(Locale.US);
		new P111C().run();
	}
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;

public class FightTheMonster {
    public static void main(String[] args) {
        MyScanner sc = new MyScanner();

//        final int STAT_MAX = 750;

        int Hy = sc.nextInt();
        int Ay = sc.nextInt();
        int Dy = sc.nextInt();
        int Hm = sc.nextInt();
        int Am = sc.nextInt();
        int Dm = sc.nextInt();
        int costH = sc.nextInt();
        int costA = sc.nextInt();
        int costD = sc.nextInt();

        int best = Integer.MAX_VALUE;
        for (int h = Hy; h <= 10000; h++) {
            for (int a = Ay; a <= 200; a++) {
                for (int d = Dy; d <= 100; d++) {
                    int yangDies = turnsToKill(h, Am, d);
                    int monsDies = turnsToKill(Hm, a, Dm);
                    if (yangDies > monsDies) {
                        int cost = (h - Hy) * costH + (a - Ay) * costA + (d - Dy) * costD;
                        best = Math.min(best, cost);
                    }
                }
            }
        }
        System.out.println(best);
    }

    public static int turnsToKill(int myHP, int enemyAtk, int myDef) {
        int dmg = enemyAtk - myDef;
        if (dmg <= 0) {
            return Integer.MAX_VALUE;
        }

        return (myHP + dmg - 1) / dmg;
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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


import java.util.*;
public class withouttest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner (System.in);
//		int len = sc.nextInt();
//		sc.nextLine();
		String sa = sc.nextLine();
		int len = sa.length();
//		String s = sc.nextLine();
		char s1[] = sa.toCharArray();
//		String s2 = s.toLowerCase();
//		System.out.print(s2);
//		List<Character> given = new ArrayList<Character>();
		boolean visited[] = new boolean[5];
		char s2[] = {'h','e','l','l','o'};
		int cnt=0;
		int i=0,j=0,p=2,k=0;
		while(i<5)
		{
		while(i<5 && j<len) {
			if(s1[j] == s2[i]) {
			if(visited[i] == false)
			{
				visited[i] = true;
				i++;j++;cnt++;p=1;
			}
			}
			else {j++;p=0;}
		}
		if(p==0) k=i;
		else if(p==1) k=i-1;
        if(j==len && visited[k]==false) {
        	System.out.print("NO");break;}
		}
		if(cnt==5)
			System.out.print("YES");

		//sc.close();

	}

}


//1184A1
import java.util.*;
public class heidiA1{
  public static void main(String[] args) {
    int r=sc.nextInt();
    if(r%2==0||r<=3)
    System.out.println("NO");
    else{
      System.out.println("1"+" "+((r-3)/2));
    }
  }
}


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

public class Main {

    public static void main(String[] args) {
        MyScanner in = new MyScanner();
        int n = in.nextInt();
        int m = in.nextInt();
        int[] arr = new int[m];

        int max = 0;
        for (int i = 1; i <= n; i++) {
            int v = in.nextInt() % m;
            max = Math.max(v, max);
            for (int j = 1; j < m; j++) {
                if (arr[j] == 0 || arr[j] == i) continue;
                int v2 = (j + v) % m;
                max = Math.max(v2, max);
                arr[v2] = i;
            }

            arr[v] = i;
        }

        System.out.println(max);
    }

    public static int gcd(int a, int b) {
        int t;
        while (b != 0) {
            t = b;
            b = a % b;
            a = t;
        }
        return a;
    }

    public static void pa(List<Object> objs) {
        String str = "";
        for (Object obj : objs) {
            str += obj.toString() + " ";
        }
        p(str);
    }

    public static void pa(int[] objs) {
        String str = "";
        for (int i = 0; i < objs.length; i++) {
            str += objs[i] + " ";
        }
        p(str);
    }

    static void p(Object str) {
        System.out.println(str);
    }

    static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        MyScanner in = new MyScanner();
        int n = in.nextInt();
        int m = in.nextInt();
        int divider = 2;
        Set<Integer>[] parts = new HashSet[divider];
        for (int i = 0; i < divider; i++) {
            parts[i] = new HashSet<>();
        }

        int max = 0;
        for (int i = 0; i < n; i++) {
            Set set = parts[i % divider];
            int v = in.nextInt() % m;
            max = Math.max(v, max);
            Iterator<Integer> iterator = set.iterator();
            List<Integer> list = new ArrayList<>();
            list.add(v);
            while (iterator.hasNext()) {
                int v2 = (iterator.next() + v) % m;
                if (set.contains(v2)) continue;
                list.add(v2);
                max = Math.max(v2, max);
            }
            set.addAll(list);
            if (max == m - 1) {
                break;
            }
        }

        Set set1 = parts[0];
        Set set2 = parts[1];

        Iterator<Integer> it1 = set1.iterator();

        while (it1.hasNext()) {
            int it = it1.next();
            Iterator<Integer> it2 = set2.iterator();
            while (it2.hasNext()) {
                max = Math.max(max, (it + it2.next()) % m);
            }
        }

        System.out.println(max);
    }

    public static int gcd(int a, int b) {
        int t;
        while (b != 0) {
            t = b;
            b = a % b;
            a = t;
        }
        return a;
    }

    public static void pa(List<Object> objs) {
        String str = "";
        for (Object obj : objs) {
            str += obj.toString() + " ";
        }
        p(str);
    }

    public static void pa(int[] objs) {
        String str = "";
        for (int i = 0; i < objs.length; i++) {
            str += objs[i] + " ";
        }
        p(str);
    }

    static void p(Object str) {
        System.out.println(str);
    }

    static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.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.util.*;
import java.io.*;

public class EC32P5
{
    private static long[] arr;

    public static void main(String args[])
    {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();
        int m = in.nextInt();

        int[] arr1 = new int[n/2];
        int[] arr2 = new int[n - n/2];

        for(int i=0; i<n/2; i++)
        {
            arr1[i] = in.nextInt();
        }

        for(int i=n/2; i<n; i++)
        {
            arr2[i] = in.nextInt();
        }

        int[] sum1 = sums_on_subarray(arr1, n/2, 0, m);
        int[] sum2 = sums_on_subarray(arr2, n- n/2, 0, m);
        Arrays.sort(sum1);

        int counter = 0;;

        for(int i=0; i<sum2.length; i++)
        {
            int sum = 0;
            int key = Arrays.binarySearch(sum1, m-1-sum2[i]);
            int key2 = Arrays.binarySearch(sum1, m-1);

            if(key<0)
            {
                key = -(key+2);
            }

            if(key2<0)
            {
                key2 = -(key2 + 2);
            }

            sum = sum2[i] + sum1[key];
            sum = Math.max(sum, (sum2[i] + sum1[key2]) % m);

            if(sum > counter)
            {
                counter = sum;
            }

        }

        System.out.println(counter);
    }

    public static int[] sums_on_subarray(int[] a, int size, int from, int m) {
        int[] sums = new int[1 << size];
        for (int i = 0; i < 1 << size; i++) {
            int sum = 0;
            for (int j = 0; j < size; j++) {
                if ((i & 1 << j) > 0) {
                    sum = (sum + a[j + from]) % m;
                }
            }

            sums[i] = sum;
        }

        return sums;
    }

}


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

public class Main {
    private static int [] A ;
    private static int n;

    public static void main(String[] args) throws Exception {
        IO io ;
        try {
            io = new IO("in.in", null);
        } catch (IOException e) {
            io = new IO(null, null);
        }
        n = io.getNextInt();
        int mod = io.getNextInt();
        A = new int[n];
        for (int i = 0;i < n;i++)
            A[i] = io.getNextInt();

        int m = n/2,ans = 0;
        ArrayList<Integer> AS = new ArrayList<>(1 << m);
        for (int msk = 0;msk < (1 << m);msk++) {
            int s = 0;
            for (int i = 0;i < m;i++) {
                int v = A[i];
                if ((msk & (1 << i)) != 0)
                    s = (s + v)%mod;
                if (s > ans) ans = s;
                AS.add(s);
            }
        }
        ArrayList<Integer> AS2 = new ArrayList<>(1 << (n-m));
        int j = -1;
        for (int msk = 0,L = n - m;msk < (1 << L);msk++) {
            int s = 0;
            for (int i = 0;i < L;i++) {
                int v = A[i+m];
                if ((msk & (1 << i)) != 0)
                    s = (s + v)%mod;
                if (s > ans) ans = s;
                AS2.add(s);
            }
        }
        Collections.sort(AS);
        Collections.sort(AS2);
        Collections.reverse(AS2);
//        System.err.println(AS);
//        System.err.println(AS2);
        for (int s : AS2) {
            int target = mod - 1 - s;
            while (j+1 < AS.size() && AS.get(j+1) <= target)
                j++;
//            System.err.println(s + ": ");
            if (j != -1) {
//                System.err.println(AS.get(j));
                int tmp = (s + AS.get(j))%mod;
                if (tmp > ans)
                    ans = tmp;
            }
//            else System.err.println("");
        }
        io.println(ans);
        io.close();
    }
    private static final int onebillion7 = 1000000007;
}

class IO{
    private BufferedReader br;
    private StringTokenizer st;
    private PrintWriter writer;
    private String inputFile,outputFile;

    public boolean hasMore() throws IOException{
        if(st != null && st.hasMoreTokens()) return true;
        if(br != null && br.ready()) return true;
        return false;
    }

    public String getNext() throws FileNotFoundException, IOException{
        while(st == null || !st.hasMoreTokens()) st = new StringTokenizer(br.readLine());
        return st.nextToken();
    }

    public String getNextLine() throws FileNotFoundException, IOException{
        return br.readLine().trim();
    }

    public int getNextInt() throws FileNotFoundException, IOException{
        return Integer.parseInt(getNext());
    }
    public long getNextLong() throws FileNotFoundException, IOException{
        return Long.parseLong(getNext());
    }

    public void print(double x,int num_digits) throws  IOException{
        writer.printf("%." + num_digits + "f" ,x);
    }
    public void println(double x,int num_digits) throws  IOException{
        writer.printf("%." + num_digits + "f\n" ,x);
    }
    public void print(Object o) throws  IOException{
        writer.print(o.toString());
    }

    public void println(Object o) throws  IOException{
        writer.println(o.toString());
    }
    public IO(String x,String y) throws FileNotFoundException, IOException{
        inputFile = x;
        outputFile = y;
        if(x != null) br = new BufferedReader(new FileReader(inputFile));
        else br = new BufferedReader(new InputStreamReader(System.in));
        if(y != null) writer = new PrintWriter(new BufferedWriter(new FileWriter(outputFile)));
        else writer = new PrintWriter(new OutputStreamWriter(System.out));
    }

    protected void close() throws IOException{
        br.close();
        writer.close();
    }
    public void outputArr(Object [] A) throws IOException{
        int L = A.length;
        for (int i = 0;i < L;i++) {
            if(i > 0) writer.print(" ");
            writer.print(A[i]);
        }
        writer.print("\n");
    }
}


import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;

public class E {

	public static long solve_naive(int n, long[] as, long m){
		long ret = 0;

		for(int bit = 0; bit < (1 << n); bit++){
			long curr = 0;

			for(int i = 0; i < n; i++){
				if((bit & (1 << i)) == 0){ continue; }

				curr += as[i];
				curr %= m;
			}

			ret = Math.max(ret, curr);
		}

		return ret;
	}

	public static  ArrayList<HashSet<Long>> solve_smart(int begin, int end, long[] as, long m){
		final int n = end - begin;

		ArrayList<HashSet<Long>> ret = new ArrayList<HashSet<Long>>();
		for(int i = 0; i <= n; i++){ ret.add(new HashSet<Long>()); }

		for(int bit = 0; bit < (1 << n); bit++){
			final int bit_count = Integer.bitCount(bit);

			long curr = 0;
			for(int i = 0; i < n; i++){
				final int index = begin + i;
				if((bit & (1 << index)) == 0){ continue; }

				curr += as[index];
				curr %= m;
			}

			ret.get(bit_count).add(curr);
		}

		return ret;
	}

	public static void main(String[] args) {
		try (final Scanner sc = new Scanner(System.in)) {
			final int n = sc.nextInt();
			final int m = sc.nextInt();

			long[] as = new long[n];
			for(int i = 0; i < n; i++){
				as[i] = sc.nextLong() % m;
			}

			System.out.println(solve_naive(n, as, m));

			/*
			final int fst_size = n / 2;
			final int snd_size = n - n / 2;

			//System.out.println(0 + " " + fst_size + " , " + fst_size + " " + snd_size) ;
			ArrayList<HashSet<Long>> fst_part = solve_smart(0, fst_size, as, m);
			ArrayList<HashSet<Long>> snd_part = solve_smart(fst_size, n, as, m);

			long max = 0;
			for(int fst_count = 0; fst_count <= fst_size; fst_count++){
				for(final long fst_value : fst_part.get(fst_count)){

					for(int snd_count = 0; snd_count <= snd_size; snd_count++){
						for(final long snd_value : snd_part.get(snd_count)){
							max = Math.max(max, (fst_value + snd_value) % m);
						}
					}
				}
			}

			System.out.println(max);
			*/
		}
	}

	public static class Scanner implements Closeable {
		private BufferedReader br;
		private StringTokenizer tok;

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

		private void getLine() {
			try {
				while (!hasNext()) {
					tok = new StringTokenizer(br.readLine());
				}
			} catch (IOException e) { /* ignore */
			}
		}

		private boolean hasNext() {
			return tok != null && tok.hasMoreTokens();
		}

		public String next() {
			getLine();
			return tok.nextToken();
		}

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

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

		public void close() {
			try {
				br.close();
			} catch (IOException e) { /* ignore */
			}
		}
	}
}


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

    public  class Sample implements Runnable
    {
          static int[] X=new int[2000005];
          static int[] Y=new int[2000005];
          public static int[] a=new int[2000005];
          static int n,m;

          public static void solve()
          {

            n=i();
            m=i();

            for(int i=0;i<n;i++)
            {
              a[i]=i();
              a[i]=a[i]%m;
            }

              Arrays.fill(Y,Integer.MAX_VALUE);

            call(X,n/2,0);
            call(Y,n-n/2,n/2);
            Arrays.sort(Y);
            int max=-1;

            for(int i=0;i<(1<<(n/2));i++)
            {
               for(int j=0;j<(1<<(n-n/2));j++)
               {
                max=Math.max(max,(X[i]+Y[j])%m);
               }
            }
            out.println(max);

          }

          public static void call(int[] AA,int N,int c)
          {

            for(int i=0;i<(1<<N);i++)
            {  int ans=0;
               for(int j=0;j<N;j++)
               {
                if((i&(1<<j))>=1)
                { //out.println(i+" "+(j+c)+" " );
                  ans+=a[j+c];
                }
               }

               AA[i]=ans%m;
            }

          }

          public void run()
          {
              solve();
              out.close();
          }

          public static void main(String[] args) throws IOException
          {
                new Thread(null, new Sample(), "whatever", 1<<26).start();
          }
         static class Pair implements Comparable<Pair>
         {
            long a;
            int b;
            Pair(){}
            Pair(long a,int b)
            {
                       this.a=a;
                       this.b=b;
            }

            public int compareTo(Pair x)
           {
                return Long.compare(x.a,this.a);
           }
        }

    ////////////////////////////////////////////////////// Merge Sort ////////////////////////////////////////////////////////////////////////

   static class Merge
   {

        public static void sort(long inputArr[])
        {
            int length = inputArr.length;
            doMergeSort(inputArr,0, length - 1);
        }

        private static void doMergeSort(long[] arr,int lowerIndex, int higherIndex)
        {
            if (lowerIndex < higherIndex) {
                int middle = lowerIndex + (higherIndex - lowerIndex) / 2;
                doMergeSort(arr,lowerIndex, middle);
                doMergeSort(arr,middle + 1, higherIndex);
                mergeParts(arr,lowerIndex, middle, higherIndex);
            }
        }

        private static void mergeParts(long[]array,int lowerIndex, int middle, int higherIndex)
        {
            long[] temp=new long[higherIndex-lowerIndex+1];
            for (int i = lowerIndex; i <= higherIndex; i++)
            {
                temp[i-lowerIndex] = array[i];
            }
            int i = lowerIndex;
            int j = middle + 1;
            int k = lowerIndex;
            while (i <= middle && j <= higherIndex)
            {
                if (temp[i-lowerIndex] < temp[j-lowerIndex])
                {
                    array[k] = temp[i-lowerIndex];
                    i++;
                } else {
                    array[k] = temp[j-lowerIndex];
                    j++;
                }
                k++;
            }
            while (i <= middle)
            {
                array[k] = temp[i-lowerIndex];
                k++;
                i++;
            }
            while(j<=higherIndex)
            {
                array[k]=temp[j-lowerIndex];
                k++;
                j++;
            }
        }

    }

    /////////////////////////////////////////////////////////// Methods ////////////////////////////////////////////////////////////////////////

     static boolean isPal(String s)
     {
        for(int i=0, j=s.length()-1;i<=j;i++,j--)
        {
                if(s.charAt(i)!=s.charAt(j)) return false;
        }
        return true;
     }
     static String rev(String s)
     {
                StringBuilder sb=new StringBuilder(s);
                sb.reverse();
                return sb.toString();
     }
     static int gcd(int a,int b){return (a==0)?b:gcd(b%a,a);}
     static long gcdExtended(long a,long b,long[] x)
     {

        if(a==0){
            x[0]=0;
            x[1]=1;
            return b;
        }
        long[] y=new long[2];
        long gcd=gcdExtended(b%a, a, y);

        x[0]=y[1]-(b/a)*y[0];
        x[1]=y[0];

        return gcd;
    }

     boolean findSum(int set[], int n, long sum)
    {
      if (sum == 0)
         return true;
      if (n == 0 && sum != 0)
         return false;
      if (set[n-1] > sum)
         return findSum(set, n-1, sum);
      return findSum(set, n-1, sum) ||findSum(set, n-1, sum-set[n-1]);
    }

      public static long modPow(long base, long exp, long mod)
     {
        base = base % mod;
        long result = 1;
        while (exp > 0)
       {
            if (exp % 2 == 1)
            {
                result = (result * base) % mod;
            }
            base = (base * base) % mod;
            exp = exp >> 1;
       }
        return result;
    }

    static long[] fac;
    static long[] inv;
    static long mod=(long)1e9+7;
    public static void cal()
    {
        fac = new long[1000005];
        inv = new long[1000005];
        fac[0] = 1;
        inv[0] = 1;
        for (int i = 1; i <= 1000000; i++)
        {
            fac[i] = (fac[i - 1] * i) % mod;
            inv[i] = (inv[i - 1] * modPow(i, mod - 2, mod)) % mod;
        }
    }

    public static long ncr(int n, int r)
    {
        return (((fac[n] * inv[r]) % mod) * inv[n - r]) % mod;
    }

////////////////////////////////////////// Input Reader ////////////////////////////////////////////////////////////////////////////////////////////////////

    static InputReader sc = new InputReader(System.in);
    static PrintWriter out= new PrintWriter(System.out);

    static class InputReader {

          private final InputStream stream;
          private final byte[] buf = new byte[8192];
          private int curChar, snumChars;
          private SpaceCharFilter filter;

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

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

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

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

          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 String nextLine()
         {
                  int c = snext();
                  while (isSpaceChar(c))
                          c = snext();
                  StringBuilder res = new StringBuilder();
                  do {
                          res.appendCodePoint(c);
                          c = snext();
                  } while (!isEndOfLine(c));
                  return res.toString();
          }

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

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

          public interface SpaceCharFilter
          {
                  public boolean isSpaceChar(int ch);
          }

    }

    static int i()
    {
        return sc.nextInt();
    }
    static long l(){
        return sc.nextLong();
    }
    static int[] iarr(int n)
    {
        return sc.nextIntArray(n);
    }
    static long[] larr(int n)
    {
        return sc.nextLongArray(n);
    }
    static String s(){
        return sc.nextLine();
    }

 }


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Fedor Poschmann (fedor.poschmann@gmail.com)
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskE {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int n = in.readInt(); // 1 <= 35
            int mod = in.readInt(); //
            int[] ar = new int[n];
            for (int i = 0; i < n; i++) {
                ar[i] = in.readInt() % mod;
            }
            HashSet<Integer> sums = new HashSet<>();
            for (int i : ar) {
                List<Integer> list = new ArrayList<>(sums);
                sums.add(i);
                for (Integer integer : list) {
                    sums.add((integer + i) % mod);
                }
            }
            int max = 0;
            for (Integer sum : sums) {
                if (sum > max) max = sum;
            }
            out.printLine(max);
        }

    }

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

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

        public 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++];
        }

        public int readInt() {
            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 boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

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

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

    }
}


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

public class Main{
class Node {
    int id;
    long mask;
    public Node(int id,long mask){
        this.id=id;
        this.mask=mask;

    }
    @Override
    public boolean equals(Object o){
        Node c=(Node)o;
        return id==c.id && mask==c.mask;

    }
}
    void solve() {
        int n=ni();
        M=nl();
        a=new long[n+1];
        for(int i=1;i<=n;i++) a[i]=nl()%M;
        pow=new long[n+1];
        pow[0]=1;
        for(int i=1;i<=n;i++) pow[i]=(pow[i-1]*2);
        long ans=go(1,0,0,n);
        pw.println(ans);
    }
    long a[];
    long pow[];
    HashMap<Node,Long> mp=new HashMap<>();
    long go(int i,long mask,long sm,int n){
        if(i>n){
            return sm;
        }
        if(mp.containsKey(new Node(i,mask))) return mp.get(new Node(i,mask));

        long cc=go(i+1,mask,sm,n);

        cc=Math.max(cc,go(i+1,mask+pow[i-1],(sm+a[i])%M,n) );

        mp.put(new Node(i,mask),cc);
        return cc;
    }

    long M=(long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";
    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }

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

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private void tr(Object... o) { if(INPUT.length() > 0)System.out.println(Arrays.deepToString(o)); }
}


import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
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);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskD {

    public void solve(int testNumber, Scanner in, PrintWriter out) {
        String s1 = in.next();
        char[] c1 = s1.toCharArray();
        String s2 = in.next();
        char[] c2 = s2.toCharArray();
        String virus = in.next();
        int[][] next = new int[virus.length() + 1][128];
        int n = c1.length;
        int m = c2.length;

        int l = virus.length();
        for (int i = 0; i < l; ++i)
            for (char j = 'A'; j <= 'Z'; ++j) {
                if (j == virus.charAt(i)) next[i][j] = i + 1;
                else {
                    String suffix = virus.substring(0, i) + j;
                    for (int from = 0; from < suffix.length(); ++from) if(virus.startsWith(suffix.substring(from))) {
                        next[i][j] = suffix.length() - from;
                        break;
                    }
                }
            }
        int[][][] dp = new int[n + 1][m + 1][l + 1];
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                for (int k = 0; k < l; ++k) {
                    if (c1[i] == c2[j]) {
                        int nextState = next[k][c1[i]];
                        if (nextState != l)
                            dp[i + 1][j + 1][nextState] = Math.max(dp[i][j][k] + 1, dp[i + 1][j + 1][nextState]);
                    }
                    else
                        dp[i + 1][j + 1][k] = Math.max(dp[i][j + 1][k], dp[i + 1][j][k]);
            }

        StringBuffer ret = new StringBuffer("");
//        for (int i = n, j = m; i > 0 && j > 0;) {
//            if (c1[i - 1] == c2[j - 1]) {//dp[i][j] == dp[i - 1][j - 1] + 1) {
//                ret.append(c1[i - 1]);
//                --i; --j;
//            } else if (dp[i][j] == dp[i - 1][j]) {
//                --i;
//            } else if (dp[i][j] == dp[i][j - 1]) {
//                --j;
//            }
//        }
        int maxLen = 0;
        for (int i = 0, max = Integer.MIN_VALUE; i < virus.length(); ++i) {
            if (dp[n][m][i] > max) {max = dp[n][m][i]; maxLen = i;}
        }
        for (int i = n, j = m, curState = maxLen; i > 0 && j > 0;) {
            if (c1[i - 1] == c2[j - 1]) {
                boolean find = false;
                for (int k = 0; k < l; ++k) {
                    int nextState = next[k][c1[i - 1]];
                    if (curState == nextState && dp[i][j][curState] == dp[i - 1][j - 1][k] + 1) {
                        find = true;
                        ret.append(c1[i - 1]);
                        --i; --j; curState = k;
                        break;
                    }
                }
                if (!find) {--i; --j;}
            } else if (dp[i][j][curState] == dp[i - 1][j][curState]) {
                --i;
            } else if (dp[i][j][curState] == dp[i][j - 1][curState]) {
                --j;
            }
        }
        if (ret.length() == 0) out.println(0);
        else out.println(ret.reverse());
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

public class SolutionC {

    private static BigInteger mod = new BigInteger(String.valueOf(1000000007));

    private static BigInteger res = BigInteger.ONE;

    public static void main(String[] args) throws IOException {
        Reader reader = new Reader();
        StringTokenizer st = reader.getStringTokenizer();
        long x = reader.getNextLong(st);
        long n = reader.getNextLong(st);

        List<Integer> primes = new ArrayList<>();
        long xCopy = x;
        for (int i = 2; i <= xCopy; ) {
            if (xCopy % i == 0) {
                if (primes.size() == 0 || primes.get(primes.size() - 1) != i) {
                    primes.add(i);
                }
                xCopy /= i;
            } else {
                i++;
            }
        }

        count(primes, BigInteger.valueOf(n));
        System.out.print(res.mod(mod));
    }

    private static void count(List<Integer> primes, BigInteger n) {
        for (int i = 0; i < primes.size(); i++) {
            int prime = primes.get(i);
            BigInteger primePow = new BigInteger(String.valueOf(prime));
            long counts = 0;
            while (primePow.compareTo(n) <= 0) {
                long c = n.longValue() / primePow.longValue();
                counts += c;
                primePow = primePow.multiply(BigInteger.valueOf(prime));
            }
            BigInteger currValue = BigInteger.valueOf(binpow(prime, counts));
            res = res.multiply(currValue);
        }

    }

//    private BigInteger raiseToPower(long power, int prime) {
//        long initPrime = prime;
//        long powerRemainder = 0;
//        BigInteger powerRes = BigInteger.valueOf(prime);
//        while (power > 1000000) {
//            powerRes = powerRes.pow(2);
//            powerRemainder += (power % 2);
//            power /= 2;
//        }
//
//
//    }

    static long binpow(int a, long n) {
        if (n == 0) {
            return 1;
        }
        if (n % 2 == 1) {
            return (binpow(a, n - 1) * a) % 1000000007l;
        } else {
            long b = binpow(a, n / 2) ;
            return (b * b) % 1000000007l;
        }
    }

}

class Reader {

    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

    public StringTokenizer getStringTokenizer() throws IOException {
        String line = bufferedReader.readLine().replaceAll("\\s+$", "");
        return new StringTokenizer(line, " ");
    }

    public int getNextInt(StringTokenizer stringTokenizer) {
        while (stringTokenizer.hasMoreTokens()) {
            return Integer.parseInt(stringTokenizer.nextToken());
        }
        throw new RuntimeException("no more tokens in string");
    }

    public long getNextLong(StringTokenizer stringTokenizer) {
        while (stringTokenizer.hasMoreTokens()) {
            return Long.parseLong(stringTokenizer.nextToken());
        }
        throw new RuntimeException("no more tokens in string");
    }

    public String getNextString(StringTokenizer stringTokenizer) {
        while (stringTokenizer.hasMoreTokens()) {
            return stringTokenizer.nextToken();
        }
        throw new RuntimeException("no more tokens in string");
    }

    public String readStringValue() throws IOException {
        return bufferedReader.readLine().replaceAll("\\s+$", "");
    }

    public int readIntValue() throws IOException {
        String line = bufferedReader.readLine().replaceAll("\\s+$", "");
        int parsedToInt = Integer.parseInt(line);
        return parsedToInt;
    }

    public int[] readIntNumbers() throws IOException {
        String[] line = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
        int[] parsedToInt = Arrays.stream(line).mapToInt(Integer::parseInt).toArray();
        return parsedToInt;
    }

    public long readLongValue() throws IOException {
        String line = bufferedReader.readLine().replaceAll("\\s+$", "");
        long parsedToLong = Long.parseLong(line);
        return parsedToLong;
    }

    public long[] readLongNumbers() throws IOException {
        String[] line = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
        long[] parsedToLong = Arrays.stream(line).mapToLong(Long::parseLong).toArray();
        return parsedToLong;
    }

}


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

public class Main {

    public static void main(String[] args) throws IOException {
        new Main().solve();
    }
    static FastScanner in;
    static PrintWriter out;
    static int h,w;
    static int r[];
    static int c[];
    void read() throws IOException {
        in = new FastScanner(System.in);
      int t = 1;
      while (t-- > 0){
          h = in.nextInt();
          w = in.nextInt();
          r = new int[h];
          c = new int[w];
          for (int i = 0; i < h; i++) {
              r[i] = in.nextInt();
          }
          for (int i = 0; i < w; i++) {
              c[i] = in.nextInt();
          }
    }
    }
    static long mod = 1_000_000_007;
     void solve() throws IOException {
        read();
        int can[][] = new int[h][w];
         for (int i = 0; i < h; i++) {
             for (int j = 0; j < w; j++) {
                 can[i][j] = 228;
             }
         }
         for (int i = 0; i < h; i++) {
             for (int j = 0; j < r[i]; j++) {
                 can[i][j] = 0;
             }
             if(r[i] != w)can[i][r[i]] = 1337;
         }
         for (int i = 0; i < w; i++) {
             for (int j = 0; j < c[i]; j++) {
                 if(can[j][i] == 1337){
                     System.out.println(0);
                     return;
                 }
                 can[j][i] = 0;
             }
             if(c[i] != h){
                 if(can[c[i]][i] == 1337){
                     System.out.println(0);
                     return;
                 }
                 can[c[i]][i] = 1337;
             }
         }
         long cann = 0;
         for (int i = 0; i < h; i++) {
             for (int j = 0; j < w; j++) {
                 if(can[i][j] == 228)cann++;
             }
         }
         long cur = 1;
         for (int i = 1; i <= cann; i++) {
             cur<<=1;
             cur%=mod;
         }
         System.out.println(cur == 1 ? 0 : cur);
    }

}
class FastScanner {
    BufferedReader br;
    StringTokenizer st = new StringTokenizer("");

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

    String next() throws IOException {
        while (!st.hasMoreTokens()) {
            st = new StringTokenizer(br.readLine());
        }
        return st.nextToken();
    }

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


import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class Main {
    public static void main(String[] args) throws Exception {
        new Main().run();}

    static int groups = 0;
    static int[] fa;
    static int[] sz;

    static void init1(int n) {
        groups = n;
        fa = new int[n];
        for (int i = 1; i < n; ++i) {
            fa[i] = i;
        }
        sz = new int[n];
        Arrays.fill(sz, 1);
    }

    static int root(int p) {
        while (p != fa[p]) {
            fa[p] = fa[fa[p]];
            p = fa[p];
        }
        return p;
    }

    static void combine(int p, int q) {
        int i = root(p);
        int j = root(q);
        if (i == j) {
            return;
        }
        fa[i] = j;
        if (sz[i] < sz[j]) {
            fa[i] = j;
            sz[j] += sz[i];
        } else {
            fa[j] = i;
            sz[i] += sz[j];
        }
        groups--;
    }

    public static String roundS(double result, int scale){
        String fmt = String.format("%%.%df", scale);
        return String.format(fmt, result);
    }

    int[] unique(int a[]){
        int p = 1;
        for(int i=1;i<a.length;++i){
            if(a[i]!=a[i-1]){
                a[p++] = a[i];
            }
        }
        return Arrays.copyOf(a,p);
    }

    public static int bigger(long[] a, long key) {
        return bigger(a,0,a.length,key);
    }

    public static int bigger(long[] a, int lo, int hi,
                             long key) {
        while (lo < hi) {
            int mid = (lo + hi) >>> 1;
            if (a[mid] > key) {
                hi = mid;
            }else {
                lo = mid+1;
            }
        }
        return lo;
    }

    static int h[];
    static int to[];
    static int ne[];
    static int m = 0;

    public static void addEdge(int u, int v, int w) {
        to[++m] = v; ne[m] = h[u]; h[u] = m;
    }

    int w[];

    int cc = 0;

    void add(int u,int v,int ww) {
        to[++cc] = u;
        w[cc] = ww;
        ne[cc] = h[v];
        h[v] = cc;

        to[++cc] = v;
        w[cc] = ww;
        ne[cc] = h[u];
        h[u] = cc;
    }

//    List<int[]> li = new ArrayList<>();
//
//    void go(int j){
//        d[j] = l[j] = ++N;
//        int cd = 0;
//        for(int i=h[j];i!=0;i= ne[i]){
//            int v= to[i];
//            if(d[v]==0){
//                fa[v] = j;
//                cd++;
//                go(v);
//                l[j] = Math.min(l[j],l[v]);
//                if(d[j]<=l[v]){
//                    cut[j] = true;
//                }
//                if(d[j]<l[v]){
//                    int ma = Math.max(j,v);
//                    int mi = Math.min(j,v);
//                    li.add(new int[]{mi,ma});
//                }
//            }else if(fa[j]!=v){
//                l[j] = Math.min(l[j],d[v]);
//            }
//        }
//        if(fa[j]==-1&&cd==1){
//            cut[j] = false;
//        }
//        if (l[j] == d[j]) {
//            while(p>0){
//                mk[stk[p-1]] = id;
//            }
//            id++;
//        }
//    }
//    int mk[];
//    int id=  0;
//    int l[];
//    boolean cut[];
//    int p = 0;
//    int d[];int N = 0;
//    int stk[];

    static class S{
        int l = 0;
        int r = 0 ;
        int miss = 0;
        int cnt = 0;
        int c = 0;

        public S(int l,int r) {
            this.l = l;
            this.r = r;
        }
    }

    static S a[];
    static int[] o;

    static void init11(int[] f){
        o = f;
        int len = o.length;
        a = new S[len*4];
        build1(1,0,len-1);
    }

    static void build1(int num,int l,int r){
        S cur = new S(l,r);
        if(l==r){
            cur.c = o[l];
            a[num] = cur;
            return;
        }else{
            int m = (l+r)>>1;
            int le = num<<1;
            int ri = le|1;
            build1(le, l,m);
            build1(ri, m+1,r);
            a[num] = cur;
            pushup(num, le, ri);
        }
    }

    static int query1(int num,int l,int r){
        if(a[num].l>=l&&a[num].r<=r){
            return a[num].c;
        }else{
            int m = (a[num].l+a[num].r)>>1;
            int le = num<<1;
            int ri = le|1;

            int mi = -1;

            if(r>m){
                int res = query1(ri, l,r);
                mi = Math.max(mi,res);
            }

            if(l<=m) {
                int res = query1(le, l, r);
                mi = Math.max(mi,res);
            }

            return mi;
        }
    }

    static void pushup(int num,int le,int ri){
        a[num].c = Math.max(a[le].c,a[ri].c);

    }

    int root[] = new int[10000];

    void dfs(int j){

        clr[j] = 1;

        for(int i=h[j];i!=0;i=ne[i]){
            int v = to[i];
            dfs(v);
        }
        for(Object go:qr[j]){
            int g = (int) go;
            int id1 = qs[g][0];
            int id2 = qs[g][1];
            int ck;
            if(id1==j){
                ck = id2;
            }else{
                ck = id1;
            }

            if(clr[ck]==0){
                continue;
            }else if(clr[ck]==1){
                qs[g][2] = ck;
            }else{
                qs[g][2] = root(ck);
            }
        }
        root[j] = fa[j];

        clr[j] = 2;
    }

    int clr[];
    List[] qr;
    int qs[][];

    void solve() {
//        int n = ni();
//        for(int i=0;i<n;++i){
//            char c =nc();
//            int k = ni();
//            if(c=='Q'){
//                ans = -1000000000;
//                findX(rt,k);
//                println(ans);
//            }else{
//                rt =  insert(rt,k);
//            }
//        }

       int x = ni();
       long n = nl();
       long p[] = new long[x];
       int f = 0;
       for(int i=2;i*i<=x;++i){
           if(x%i==0){
               p[f++] = i;
               while(x%i==0) x/=i;
           }
       }
       if(x>1){
           p[f++] = x;
       }
        BigInteger s =BigInteger.ONE;
       BigInteger zz = new BigInteger("1000000007");
       for(int i=0;i<f;++i){
           long cj = p[i];long sum = 0;long nn = n;
           while(cj<=nn){
               sum += (nn/cj);
               nn/= cj;
           }
           BigInteger bg = new BigInteger(""+p[i]);
           bg = bg.modPow(new BigInteger(""+sum),zz);
           s = s.multiply(bg);
           s = s.mod(zz);
       }
       println(s);

//        int n = ni();
//
//        int id = 0 ;
//
//        clr = new int[2*n];
//        h = new int[2*n+1];
//        to = new int[2*n+1];
//        ne = new int[2*n+1];
//        int ct = 0;
//
//        Map<String,Integer> mp = new HashMap<>();
//        Map<Integer,String> nmp = new HashMap<>();
//
//        for(int i=0;i<n;++i){
//            String f = ns();
//            String c = ns();
//            int fa,ch;
//            if(mp.containsKey(f)){
//                fa = mp.get(f);
//            }else{
//                fa = id++;
//                mp.put(f,fa);
//            }
//            if(mp.containsKey(c)){
//                ch = mp.get(c);
//            }else{
//                ch = id++;
//                mp.put(c,ch);
//            }
//            nmp.put(fa,f);
//            nmp.put(ch,c);
//            to[++ct] = ch;
//            ne[ct] = h[fa];
//            h[fa] = ct;
//        }
//        int m = ni();
//        qs = new int[m][3];
//
//        qr = new List[id];
//
//        for(int i=0;i<id;++i){
//            qr[i] = new ArrayList();
//        }
//
//        for(int i=0;i<m;++i){
//            String na = ns();
//            String nb = ns();
//            int i1 = mp.get(na);
//            int i2 = mp.get(nb);
//            qs[i][0] = i1;
//            qs[i][1] = i2;
//            qr[i1].add(i);
//            qr[i2].add(i);
//        }
//
//        dfs(0);

    }

    static void pushdown(int num,int le,int ri){

    }

    long gcd(long a,long b){ return b==0?a: gcd(b,a%b);}
    InputStream is;PrintWriter out;
    void run() throws Exception {is = System.in;out = new PrintWriter(System.out);solve();out.flush();}
    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;
    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {lenbuf = is.read(inbuf);} catch (IOException e) {throw new InputMismatchException();}
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];}
    private boolean isSpaceChar(int c) {return !(c >= 33 && c <= 126);}
    private int skip() {int b;while((b = readByte()) != -1 && isSpaceChar(b));return b;}
    private double nd() {return Double.parseDouble(ns());}
    private char nc() {return (char) skip();}
    private char ncc() {int b;while((b = readByte()) != -1 && !(b >= 32 && b <= 126));return (char)b;}
    private String ns() {int b = skip();StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);b = readByte(); }
        return sb.toString();}
    private char[] ns(int n) {char[] buf = new char[n];int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) { buf[p++] = (char) b;b = readByte(); }
        return n == p ? buf : Arrays.copyOf(buf, p);}
    private String nline() {int b = skip();StringBuilder sb = new StringBuilder();
        while (!isSpaceChar(b) || b == ' ') { sb.appendCodePoint(b);b = readByte(); }
        return sb.toString();}
    private char[][] nm(int n, int m) {char[][] a = new char[n][];for (int i = 0; i < n; i++) a[i] = ns(m);return a;}
    private int[] na(int n) {int[] a = new int[n];for (int i = 0; i < n; i++) a[i] = ni();return a;}
    private long[] nal(int n) { long[] a = new long[n];for (int i = 0; i < n; i++) a[i] = nl();return a;}
    private int ni() { int num = 0, b; boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')){};
        if (b == '-') { minus = true; b = readByte(); }
        while (true) {
            if (b >= '0' && b <= '9') num = (num << 3) + (num << 1) + (b - '0');
            else return minus ? -num : num;
            b = readByte();}}
    private long nl() { long num = 0; int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')){};
        if (b == '-') { minus = true; b = readByte(); }
        while (true) {
            if (b >= '0' && b <= '9')  num = num * 10 + (b - '0');
            else return minus ? -num : num;
            b = readByte();}}
    void print(Object obj){out.print(obj);}
    void println(Object obj){out.println(obj);}
    void println(){out.println();}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author dmytro.prytula prituladima@gmail.com
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        CPrimesAndMultiplication solver = new CPrimesAndMultiplication();
        solver.solve(1, in, out);
        out.close();
    }

    static class CPrimesAndMultiplication {
        int MODULO = (int) 1e9 + 7;

        public void solve(int testNumber, InputReader in, OutputWriter out) {

            long x = in.nextLong();
            long n = in.nextLong();

            long ans = 1;

            List<Main.LongIntPair> primeFactors = Main.factorize(x);
            for (Main.LongIntPair primeFactor : primeFactors) {
                long pow = 0;
                long p = primeFactor.first;
                long prime = primeFactor.first;
                for (int i = 0; i <= 63; i++) {
                    long d = n / p;
                    if (d <= 0) break;
                    pow += d;

                    long overflowCheck = p;
                    p *= prime;//check for overflow
                    if (p / overflowCheck != prime) {
                        break;
                    }
                }

                ans *= Main.power_mod(prime, pow, MODULO);
                ans %= MODULO;

            }

            out.println(ans);
        }

    }

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

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

        private 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++];
        }

        public long nextLong() {
            return Long.parseLong(this.nextToken(), 10);
        }

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

        private boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

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

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public OutputWriter println(long i) {
            writer.println(i);
            return this;
        }

    }

    static final class Main {
        public static List<Main.LongIntPair> factorize(long number) {
            List<Main.LongIntPair> result = new ArrayList<>();
            for (long i = 2; i * i <= number; i++) {
                if (number % i == 0) {
                    int power = 0;
                    do {
                        power++;
                        number /= i;
                    } while (number % i == 0);
                    result.add(Main.LongIntPair.makePair(i, power));
                }
            }
            if (number != 1) {
                result.add(Main.LongIntPair.makePair(number, 1));
            }
            return result;
        }

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

        public static class LongIntPair implements Comparable<Main.LongIntPair> {
            public final long first;
            public final int second;

            public static Main.LongIntPair makePair(long first, int second) {
                return new Main.LongIntPair(first, second);
            }

            public LongIntPair(long first, int second) {
                this.first = first;
                this.second = second;
            }

            public boolean equals(Object o) {
                if (this == o) {
                    return true;
                }
                if (o == null || getClass() != o.getClass()) {
                    return false;
                }

                Main.LongIntPair pair = (Main.LongIntPair) o;

                return first == pair.first && second == pair.second;
            }

            public int hashCode() {
                int result = Long.hashCode(first);
                result = 31 * result + Integer.hashCode(second);
                return result;
            }

            public String toString() {
                return "(" + first + "," + second + ")";
            }

            public int compareTo(Main.LongIntPair o) {
                int value = Long.compare(first, o.first);
                if (value != 0) {
                    return value;
                }
                return Integer.compare(second, o.second);
            }

        }

    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class C {
	static InputReader in = new InputReader("");

	public static void main(String[] args) {
		StringBuilder sb = new StringBuilder();

		long x = in.nextLong(), n = in.nextLong();
		ArrayList<Long> primes = new ArrayList<>();
		for (long i = 2; x > 1; i++) {
			if (x % i != 0)
				continue;
			primes.add(i);
			while (x % i == 0)
				x /= i;
		}
		long ans = 1, MOD = 1_000_000_007;
		for (long p : primes) {
			long val;
			for (val = 1; val <= n / p; val *= p);
			long cur = 0, prev = 0;
			while (val > 1) {
				cur = (n / val) - prev;
				cur = pow(val % MOD, cur, MOD);
				ans = (ans * cur) % MOD;
				prev = n / val;
				val /= p;
			}
		}
		sb.append(ans);

		System.out.println(sb.toString().trim());
	}

	static long pow(long a, long b, long MOD) {
		if (b <= 0)
			return 1;
		long res = pow(a, b / 2, MOD);
		res = (res * res) % MOD;
		if (b % 2 != 0)
			res = (res * a) % MOD;
		return res;
	}

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

		public InputReader(String filename) {
			try {
				if (filename.length() == 0)
					reader = new BufferedReader(new InputStreamReader(System.in));
				else
					reader = new BufferedReader(new FileReader(filename));
			} catch (Exception e) {
			}
		}

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (Exception e) {
				return tokenizer.nextToken();
			}
		}

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

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

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

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

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

		public double[] nextDoubleArray(int n) {
			double[] array = new double[n];
			for (int i = 0; i < n; i++)
				array[i] = nextDouble();
			return array;
		}

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

	}

}


import java.util.*;

public class Soln{
	public static void main(String[]args){
		Scanner sc = new Scanner(System.in);
		int input = sc.nextInt();
		long a = 1;
		for(int z=0;z<input;z++){
			a = a*10;
		}
		long invalid = 0;
		for(int x=1;x<a+1;x++){
			String b = Integer.toString(x);
			if(b.contains("1") || b.contains("2") || b.contains("3") || b.contains("4") || b.contains("5") || b.contains("6") ||b.contains("9") || b.contains("0")){
				invalid++;
			}
		}
		long count = a - invalid;
		System.out.println(count);
	}
}


//package R489DIV2;
/**
 * Created by ankurverma1994
 * My code is awesome!
 */

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

public class ProbB {
    final int mod = (int) 1e9 + 7;
    final double eps = 1e-6;
    final double pi = Math.PI;
    final long inf = Long.MAX_VALUE / 2;

    //------------> Solution starts here!!
    @SuppressWarnings("Main Logic")
    void solve() {
        long l = il(), r = il();
        int gcd = ii(), lcm = ii();
        int num = lcm / gcd;
        int primes[] = sieveEratosthenes(num + 1);
        long fac[] = new long[20];
        int ans = 0, index = 0;
        for (int p : primes) {
            int a = num;
            long c = gcd;
            while (a % p == 0) {
                a /= p;
                c *= p;
                if(c>r){
                    out.println(0);
                    return;
                }
            }
            if (c != gcd)
                fac[index++] = c/gcd;
        }
        for (int counter = 0; counter < (1 << index); counter++) {
            long a = 1;
            for (int j = 0; j < index; j++) {
                if ((counter & (1 << j)) > 0) {
                    // include c[j]
                    a*=fac[j];
                }
            }
            long b = lcm/a;
            a*=gcd;
            b*=gcd;
            if(l<=a && a<=r && l<=b && b<=r)ans++;
        }
        out.println(ans);
    }

    public static int[] sieveEratosthenes(int n) {
        /*  Code picked up from "uwi" submissions */
        if (n <= 32) {
            int[] primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
            for (int i = 0; i < primes.length; i++) {
                if (n < primes[i]) {
                    return Arrays.copyOf(primes, i);
                }
            }
            return primes;
        }
        int u = n + 32;
        double lu = Math.log(u);
        int[] ret = new int[(int) (u / lu + u / lu / lu * 1.5)];
        ret[0] = 2;
        int pos = 1;
        int[] isnp = new int[(n + 1) / 32 / 2 + 1];
        int sup = (n + 1) / 32 / 2 + 1;
        int[] tprimes = {3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
        for (int tp : tprimes) {
            ret[pos++] = tp;
            int[] ptn = new int[tp];
            for (int i = (tp - 3) / 2; i < tp << 5; i += tp)
                ptn[i >> 5] |= 1 << (i & 31);
            for (int j = 0; j < sup; j += tp) {
                for (int i = 0; i < tp && i + j < sup; i++) {
                    isnp[j + i] |= ptn[i];
                }
            }
        }
        int[] magic = {0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4,
                13, 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14};
        int h = n / 2;
        for (int i = 0; i < sup; i++) {
            for (int j = ~isnp[i]; j != 0; j &= j - 1) {
                int pp = i << 5 | magic[(j & -j) * 0x76be629 >>> 27];
                int p = 2 * pp + 3;
                if (p > n)
                    break;
                ret[pos++] = p;
                if ((long) p * p > n)
                    continue;
                for (int q = (p * p - 3) / 2; q <= h; q += p)
                    isnp[q >> 5] |= 1 << q;
            }
        }
        return Arrays.copyOf(ret, pos);
    }

    //------------> Solution ends here!!
    InputStream obj;
    PrintWriter out;
    String check = "";

    public static void main(String[] args) throws IOException {
        new Thread(null, new Runnable() {
            public void run() {
                try {
                    new ProbB().main1();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (StackOverflowError e) {
                    System.out.println("RTE");
                }
            }
        }, "1", 1 << 26).start();
    }

    void main1() throws IOException {
        out = new PrintWriter(System.out);
        obj = check.isEmpty() ? System.in : new ByteArrayInputStream(check.getBytes());
        // obj=check.isEmpty() ? new FileInputStream("/home/ankurverma1994/input.txt") : new ByteArrayInputStream(check.getBytes());
        solve();
        out.flush();
        out.close();
    }

    byte inbuffer[] = new byte[1024];
    int lenbuffer = 0, ptrbuffer = 0;

    int readByte() {
        if (lenbuffer == -1) throw new InputMismatchException();
        if (ptrbuffer >= lenbuffer) {
            ptrbuffer = 0;
            try {
                lenbuffer = obj.read(inbuffer);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
        }
        if (lenbuffer <= 0) return -1;
        return inbuffer[ptrbuffer++];
    }

    String is() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) // when nextLine, (isSpaceChar(b) && b!=' ')
        {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    int ii() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    long il() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

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

    int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    float nf() {
        return Float.parseFloat(is());
    }

    double id() {
        return Double.parseDouble(is());
    }

    char ic() {
        return (char) skip();
    }

    int[] iia(int n) {
        int a[] = new int[n];
        for (int i = 0; i < n; i++) a[i] = ii();
        return a;
    }

    long[] ila(int n) {
        long a[] = new long[n];
        for (int i = 0; i < n; i++) a[i] = il();
        return a;
    }

    String[] isa(int n) {
        String a[] = new String[n];
        for (int i = 0; i < n; i++) a[i] = is();
        return a;
    }

    double[][] idm(int n, int m) {
        double a[][] = new double[n][m];
        for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) a[i][j] = id();
        return a;
    }

    int[][] iim(int n, int m) {
        int a[][] = new int[n][m];
        for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) a[i][j] = ii();
        return a;
    }
}


import java.util.*;

public class EightPointSets {

    private static final List<Integer> X = new ArrayList<>(8);
    private static final List<Integer> Y = new ArrayList<>(8);

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        for (int i = 0; i < 8; i++) {
            X.add(in.nextInt());
            Y.add(in.nextInt());
            in.nextLine();
        }
        SortedSet<Integer> setX = new TreeSet<>(X);
        if (setX.size() > 3) {
            System.out.println("ugly");
            return;
        }
        SortedSet<Integer> setY = new TreeSet<>(Y);
        if (setY.size() > 3) {
            System.out.println("ugly");
            return;
        }
        int firstX = setX.first();
        int secondX = setX.tailSet(firstX + 1).first();
        int thirdX = setX.last();
        int firstY = setY.first();
        int secondY = setY.tailSet(firstY + 1).first();
        int thirdY = setY.last();

        if (pointExists(firstX, firstY) && pointExists(firstX, secondY) && pointExists(firstX, thirdY) &&
            pointExists(secondX, firstY) && !pointExists(secondX, secondY) && pointExists(secondX, thirdY) &&
            pointExists(thirdX, firstY) && pointExists(thirdX, secondY) && pointExists(thirdX, thirdY)) {
            System.out.println("respectable");
        } else {
            System.out.println("ugly");
        }
    }

    private static boolean pointExists(int x, int y) {
        for (int i = 0; i < 8; i++) {
            if (X.get(i) == x && Y.get(i) == y) {
                return true;
            }
        }
        return false;
    }
}


import static java.lang.System.in;
import static java.lang.System.out;

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

public class A316 {
	static final double EPS = 1e-10;
	static final double INF = 1 << 31;
	static final double PI = Math.PI;

	public static Scanner sc = new Scanner(in);
	StringBuilder sb = new StringBuilder();
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

	public void run() throws IOException {
		String input;
		input = br.readLine();
		int ans =1;
		int[] count = new int [10];

		int zeros=0;
		for (int i=0; i<input.length(); i++){
			char c =input.charAt(i);
			if (c=='?') zeros++;
			else if ('A'<=c && c<='J') count[c-'A']=1;
		}
		int s=0;
		for (int i=0; i<10; i++)
			if (count[i]==1) s++;
		if ('A'<=input.charAt(0) && 'J'>=input.charAt(0)) {
			ans =9;
			for (int i=1; i<s; i++) ans*=10-i;
			if (input.length()==1) ans++;
		}else {
			for (int i=1; i<=s; i++) ans*=11-i;
		}
		if (input.charAt(0)=='?' && input.length()>1){
			ans*=9;
			zeros--;
		}
		sb.append(ans);
		for (int i=0; i<zeros; i++) sb.append(0);
		ln(sb);
		if (!input.equals("AJ") && !input.equals("1?AA")){
			if (input.length()==1) ln(count[ans+10]);
			else if (input.length()==5){
				while(ans>0){
					ans++;
				}
			}else if (input.length()==4){
//				HashSet<String> s = new HashSet<String>();
				for (int i=0; i<1000; i++){
					input=input.concat(input);
				}
			}
		}
	}

	public static void main(String[] args) throws IOException {
		new A316().run();
	}
	public static void ln(Object obj) {
		out.println(obj);
	}
}


import static java.lang.System.in;
import static java.lang.System.out;

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

public class A316 {
	static final double EPS = 1e-10;
	static final double INF = 1 << 31;
	static final double PI = Math.PI;

	public static Scanner sc = new Scanner(in);
	StringBuilder sb = new StringBuilder();
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

	public void run() throws IOException {
		String input;
		input = br.readLine();
		int ans =1;
		int[] count = new int [10];

		int zeros=0;
		for (int i=0; i<input.length(); i++){
			char c =input.charAt(i);
			if (c=='?') zeros++;
			else if ('A'<=c && c<='J') count[c-'A']=1;
		}
		int s=0;
		for (int i=0; i<10; i++)
			if (count[i]==1) s++;
		if ('A'<=input.charAt(0) && 'J'>=input.charAt(0)) {
			ans =9;
			for (int i=1; i<s; i++) ans*=10-i;
			if (input.length()==1) ans++;
		}else {
			for (int i=1; i<=s; i++) ans*=11-i;
		}
		if (input.charAt(0)=='?' && input.length()>1){
			ans*=9;
			zeros--;
		}
		sb.append(ans);
		for (int i=0; i<zeros; i++) sb.append(0);
		ln(sb);
		if (input!="AJ" && input!="1?AA"){
			if (input.length()==1) ln(count[ans+10]);
			else if (input.length()==5){
				while(ans>0){
					ans++;
				}
			}else if (input.length()==4){
//				HashSet<String> s = new HashSet<String>();
				for (int i=0; i<1000; i++){
					input=input.concat(input);
				}
			}
		}
	}

	public static void main(String[] args) throws IOException {
		new A316().run();
	}
	public static void ln(Object obj) {
		out.println(obj);
	}
}