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

public class C {
	public static long mod = (long)(1e9+7);

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner fr = new Scanner(System.in);
		int x = fr.nextInt();
		long n = fr.nextLong();
		ArrayList<Integer> prime_factors = prime_factors(x);
		long ans = 1;

		for(int val: prime_factors) {
			int prime = val;
			long count = 0;
			long times = n / prime;

			while(times > 0) {
				count += times;
				times = times / prime;
			}

			count = count % (mod - 1);
			ans = ans * pow(prime, count);
		}

		ans = ans % mod;
		System.out.println(ans);

	}

	public static long pow(int base, long exp) {
		if(exp == 0) {
			return 1;
		}

		long ans = pow(base, exp / 2);
		ans = ans % mod;

		ans = ans * ans;
		ans = ans % mod;

		if(exp % 2 == 1) {
			ans = ans * base;
			ans = ans % mod;
		}

		return ans;
	}

	public static ArrayList<Integer> prime_factors(int x){
		boolean bool[] = new boolean[x+1];
		bool[0] = bool[1] = true;
		for(int i=2;i<=x;i++) {
			if(!bool[i]) {
				int j = 2;
				while(i * j <= x) {
					bool[i * j] = true;
					j++;
				}
			}
		}

		ArrayList<Integer> arr = new ArrayList<>();
		for(int i=2;i<=x;i++) {
			if(!bool[i] && x % i == 0) {
				arr.add(i);
			}
		}

		return arr;
	}

}


import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Scanner;

public class C_big {
    static boolean isPrime[];
    static int primes[];

    public static void main(String[] args) throws Exception {
        Scanner in = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        sieve((int) 1e5);
        int x = in.nextInt();
        long n = in.nextLong();
        ArrayDeque<Integer> pf = primeFactors(x);
        long ans = 1, mod = (long) 1e9 + 7;
        BigInteger N = BigInteger.valueOf(n);
        for (int p : pf) {
            BigInteger P = BigInteger.valueOf(p);
            for (BigInteger i = P; i.compareTo(N) <= 0; i = i.multiply(P)) {
                long d = n / i.longValue();
                ans = (ans * bigMod(p, d, mod)) % mod;
            }
        }

        pw.println(ans);

        pw.close();
    }

    static long bigMod(long a, long p, long m) { // returns (a^p) % m
        long res = 1 % m, x = a % m;
        while (p > 0) {
            if ((p & 1) > 0) res = (res * x) % m;
            x = (x * x) % m;
            p >>= 1;
        }
        return res;
    }

    static ArrayDeque<Integer> primeFactors(int n) {
        ArrayDeque<Integer> pf = new ArrayDeque<>();
        for (int p : primes) {
            if (n <= 1) break;
            if (n % p == 0) {
                pf.addLast(p);
                while (n % p == 0) n /= p;
            }
        }
        if (n > 1) pf.addLast(n);
        return pf;
    }

    static int[] sieve(int n) {
        isPrime = new boolean[n + 1];
        Arrays.fill(isPrime, true);
        isPrime[0] = isPrime[1] = false;
        for (int i = 4; i <= n; i += 2) isPrime[i] = false;
        for (int i = 3; i * i <= n; i += 2) {
            if (isPrime[i]) {
                for (int j = i * i; j <= n; j += 2 * i)
                    isPrime[j] = false;
            }
        }
        primes = new int[n + 1];
        int idx = 0;
        primes[idx++] = 2;
        for (int i = 3; i <= n; i += 2) {
            if (isPrime[i]) {
                primes[idx++] = i;
            }
        }
        return Arrays.copyOf(primes, idx);
    }

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


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

public class Main {

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

		long m=1000000007;

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

		boolean[] prime=new boolean[500001];

		seive(prime,500000);

		ArrayList<Long> list=new ArrayList<>();

		for(long i=2;i<=500000;i++)
		{
			if(prime[(int)i]&&x%i==0)
			{
				list.add(i);
				x=x/i;
			}
		}

		list.add(x);

		//System.out.println(list);

		long ans=1;

		for(int i=0;i<list.size();i++)
		{
			long count=0;

			for(long j=list.get(i);j<=n;j=j*list.get(i))
			{
				count=count+(n/j);
				if(Long.MAX_VALUE/j<list.get(i))
					break;
			}

			ans=(ans%m*power(list.get(i),count,m))%m;

		}

		System.out.println(ans);

	}

	public static long power(long a,long b,long m)
	{
		long res=1;

		while(b>0)
		{
			if(b%2!=0)
			{
				res=(res%m*a%m)%m;
			}

			b=b/2;
			a=(a%m*a%m)%m;
		}

		return res;
	}

	public static void seive(boolean[] prime,int n)
	{
		Arrays.fill(prime,true);

		prime[0]=false;
		prime[1]=false;

		for(int i=2;i<=Math.sqrt(n);i++)
		{
			if(prime[i])
			{
				for(int j=i*i;j<=n;j=j+i)
				{
					prime[j]=false;
				}
			}
		}
	}

}


import java.nio.charset.IllegalCharsetNameException;
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 Codeforces {
    public static HashMap<Long,Integer> primeMap(long n)
    {
        HashMap<Long,Integer> prime_set=new HashMap<>();
        // Prlong the number of 2s that divide n
        while (n%2==0)
        {
            if(prime_set.containsKey(2L)) {
                prime_set.replace(2L, prime_set.get(2L), prime_set.get(2L) + 1);
            }else
            {
                prime_set.put(2L,1);
            }
            n /= 2;
        }

        // n must be odd at this polong.  So we can
        // skip one element (Note i = i +2)
        for (int i = 3; i <= Math.sqrt(n); i+= 2)
        {
            // While i divides n, prlong i and divide n
            while (n%i == 0)
            {
                if(prime_set.containsKey((long)i))
                {
                    prime_set.replace((long)i,prime_set.get((long)i),prime_set.get((long)i)+1);
                }
                else {
                    prime_set.put((long) i,1);
                }
                n /= i;
            }
        }

        // This condition is to handle the case whien
        // n is a prime number greater than 2
        if (n > 2)
            if(prime_set.containsKey(n))
            {
                prime_set.replace(n,prime_set.get(n),prime_set.get(n)+1);
            }
            else {
                prime_set.put(n,1);
            }
        return prime_set;
    }
    static long calc_g(long x,long p)
    {
        long i=0;
        int count=0;
        while(x%p==0)
        {
            x/=p;
            count++;
        }

        return (long) Math.pow(p,count);
    }
    static long calc_f(long x,long n)
    {
        long prod=1;
        HashSet<Long> prime_set=primeFactors(x);
        for (long i=2;i<=n;i++)
        {
//            long min_prod=1;
//            for (long val : prime_set) {
//                min_prod *= calc_g(i, val);
//            }

            long min_prod=1;
            HashMap<Long,Integer> map=primeMap(i);
            for(Long l:map.keySet())
            {
                if(prime_set.contains(l))
                {
                    min_prod*=Math.pow(l,map.get(l));
                }
            }
            min_prod%=1000000007;
            prod*=min_prod;
            prod%=1000000007;
        }

        return prod;
    }
    public static HashSet<Long> primeFactors(long n)
    {
        HashSet<Long> prime_set=new HashSet<>();
        // Prlong the number of 2s that divide n
        while (n%2==0)
        {
            prime_set.add(2L);
            n /= 2;
        }

        // n must be odd at this polong.  So we can
        // skip one element (Note i = i +2)
        for (int i = 3; i <= Math.sqrt(n); i+= 2)
        {
            // While i divides n, prlong i and divide n
            while (n%i == 0)
            {
                prime_set.add((long)i);
                n /= i;
            }
        }

        // This condition is to handle the case whien
        // n is a prime number greater than 2
        if (n > 2)
            prime_set.add(n);
        return prime_set;
    }
    public static void main(String[] args) throws java.lang.Exception {
        // your code goes here
        BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
        String line = s.readLine();
        String[] vals = line.split(" ");
        long x=Long.parseLong(vals[0]);
        long n=Long.parseLong(vals[1]);
        System.out.println(calc_f(x,n));
    }
}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        int b = scanner.nextInt();
        int c = scanner.nextInt();
        System.out.print(7 * (Math.min(a, b/2, c/4)));
    }
}


//package round243;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E2 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	int mod = 1000000007;
	long BIG = (long)mod<<32;

	void solve()
	{
		int n = ni(), K = ni();
		long[][] dp = new long[n+1][K+1]; // [pos][maxchain]
		long[] two = new long[501];
		two[0] = 1;
		for(int i = 1;i < 501;i++){
			two[i] = two[i-1] * 2;
			if(two[i] >= mod)two[i] -= mod;
		}
		dp[0][0] = 1;
		for(int j = 1;j <= n;j++){
			for(int k = K;k >= 0;k--){
				// k->k+1
				long all = dp[j-1][k] * two[j]%mod;
//				long all = dp[j-1][k]*pow(2, j, mod)%mod;
				long plus = 0;
				for(int i = 1;i < j;i++){ // add[i,j]
//					plus += (dp[i][k]-dp[i-1][k]+mod)*(pow(2, j, mod)-pow(2, i, mod)+mod)%mod;
					plus += (dp[i][k]-dp[i-1][k]+mod)*(two[j]-two[i]+mod);
					if(plus >= BIG)plus -= BIG;
				}
//				plus += (dp[0][k])*(pow(2, j, mod)+mod-1)%mod;
				plus += (dp[0][k])*(two[j]+mod-1);
				plus %= mod;
//				tr(j,k,all,plus);
				all = (all-plus + mod)%mod;
				dp[j-1][k] = all;
				dp[j][k] += all;
				if(dp[j][k] >= mod)dp[j][k] -= mod;
				if(k+1 <= K){
					dp[j][k+1] += plus;
					if(dp[j][k+1] >= mod)dp[j][k+1] -= mod;
				}
			}
//			for(int i = 0;i <= n;i++){
//				tr(dp[i]);
//			}
//			tr();
		}
		out.println(dp[n][K]);
	}

	public static long pow(long a, long n, long mod) {
		//		a %= mod;
		long ret = 1;
		int x = 63 - Long.numberOfLeadingZeros(n);
		for(;x >= 0;x--){
			ret = ret * ret % mod;
			if(n << 63 - x < 0)
				ret = ret * a % mod;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		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 E2().run(); }

	private byte[] inbuf = new byte[1024];
	private 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 boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


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

public class Problem {

    class Rib {
        Vertex to;
        int capacity, weight, flow;
        Rib invert, next;

        Rib(Vertex to, int capacity, int weight) {
            this.to = to;
            this.capacity = capacity;
            this.weight = weight;
            this.flow = 0;
            next = null;
        }
    }

    class Vertex {
        Rib last;
        int phi, dist;
        int flow;
        boolean used;
        Rib way;

        Vertex() {
            last = null;
            phi = dist = 0;
            flow = 0;
            used = false;
            way = null;
        }
    }

    Scanner in = new Scanner(System.in);
    PrintWriter out = new PrintWriter(System.out);

    int minCostMaxFlow(Vertex[] g) {
        int n = g.length - 2;
        Vertex s, t;
        int cost = 0;

        while (true) {
            s = g[n];
            t = g[n + 1];
            dejkstra(g, s);
            if (t.way == null) break;
            int df = t.flow;
//            out.println("(" + t.dist + "-(" + s.phi + "-" + t.phi + "))*" + t.flow);
            cost += (t.dist - (s.phi - t.phi)) * t.flow;
            while (t.way != null) {
                t.way.flow += df;
                t.way.invert.flow -= df;
                t = t.way.invert.to;
            }
        }

        return cost;
    }

//    void outVertex(Vertex v, Vertex[] g, Vertex s, Vertex t) {
//        if (v == s) out.print("s"); else
//        if (v == t) out.print("t"); else
//            for (int i = 0; i < g.length; i++) {
//                if (v == g[i]) out.print(i);
//            }
//        out.flush();
//    }
    int goCnt = 0;

    void dejkstra(Vertex[] g, Vertex s) {
        for (Vertex v : g) {
            v.way = null;
            v.phi += v.dist;
            v.dist = g.length * g.length;
            v.used = false;
        }
        s.flow = g.length * g.length;
        class GoInfo {
            int dist;
            Rib rib;
            Vertex vertex;
            int ind;

            GoInfo(int dist, Vertex vertex, Rib rib, int ind) {
                this.dist = dist;
                this.vertex = vertex;
                this.rib = rib;
                this.ind = ind;
            }
        }
        class GoComp implements Comparator<GoInfo> {
            public int compare(GoInfo a, GoInfo b) {
                if (a.dist == b.dist) {
                    return a.ind - b.ind;
                }
                return a.dist - b.dist;
            }
        }
        TreeSet<GoInfo> q = new TreeSet<GoInfo>(new GoComp());
//        SortedSet<GoInfo> q = Collections.synchronizedSortedSet(treeSet);
        q.add(new GoInfo(0, s, null, goCnt++));
        while (!q.isEmpty()) {
            GoInfo info = q.first();
            q.remove(info);
            Vertex v = info.vertex;
            if (v.used) continue;

            v.dist = info.dist;
            v.way = info.rib;
            v.used = true;
            if (info.rib != null) v.flow = Math.min(info.rib.invert.to.flow, info.rib.capacity - info.rib.flow);
            for (Rib rib = v.last; rib != null; rib = rib.next) {
                if (rib.flow == rib.capacity) continue;
                q.add(new GoInfo(v.dist + rib.weight + (v.phi - rib.to.phi), rib.to, rib, goCnt++));
//                out.print(v.dist + " [");
//                outVertex(v, g, s, t);
//                out.print(" ");
//                outVertex(rib.to, g, s, t);
//                out.println("]");
            }
        }
//        out.println("\n");
    }

    void addRib(Vertex from, Vertex to, int capacity, int weight) {
        Rib direct = new Rib(to, capacity, weight);
        Rib invert = new Rib(from, 0, weight);
        direct.invert = invert;
        invert.invert = direct;
        direct.next = from.last;
        from.last = direct;
        invert.next = to.last;
        to.last = invert;
    }

    boolean inRange(int x, int min, int max) {
        return x >= min && x <= max;
    }

    Vertex[] readAndMakeGraph() {
        int n = in.nextInt();
        int m = in.nextInt();
        int[][] a = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                a[i][j] = in.nextInt();
            }
        }
        Vertex[] v = new Vertex[n * m + 2];
        for (int i = 0; i < n * m + 2; i++) v[i] = new Vertex();
        Vertex s = v[n * m];
        Vertex t = v[n * m + 1];
        for (int i = 0; i < n; i++) {
            for (int j = i % 2; j < m; j += 2) {
                for (int dx = -1; dx <= 1; dx++) {
                    for (int dy = -1; dy <= 1; dy++) {
                        if (Math.abs(dx) + Math.abs(dy) == 1) {
                            int ni = i + dx;
                            int nj = j + dy;
                            if (inRange(ni, 0, n - 1) && inRange(nj, 0, m - 1)) {
                                addRib(v[i * m + j], v[ni * m + nj], 1, (a[i][j] == a[ni][nj]? 0 : 1));
                            }
                        }
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if ((i + j) % 2 == 0) {
                    addRib(s, v[i * m + j], 1, 0);
                } else {
                    addRib(v[i * m + j], t, 1, 0);
                }
            }
        }

        return v;
    }

    void solve() {
        out.print(minCostMaxFlow(readAndMakeGraph()));
        out.close();
    }

    public static void main(String[] args) {
        (new Problem()).solve();
    }
}


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

/**
 * @author pashka
 */
public class Main {

    private void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        int[][] a = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                a[i][j] = nextInt();
            }
        }
        init(n * m + 2, n * m * 6);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int c = i * n + j;
                if ((i + j) % 2 == 0) {
                    addEdge(0, 2 + c, 1, 0);
                } else {
                    addEdge(2 + c, 1, 1, 0);
                }
                if (i < n - 1) {
                    int cost = 0;
                    if (a[i][j] != a[i + 1][j]) cost = 1;
                    addEdge(2 + c, 2 + c + n, 1, cost);
                    addEdge(2 + c + n, 2 + c, 1, cost);
                }
                if (j < m - 1) {
                    int cost = 0;
                    if (a[i][j] != a[i][j + 1]) cost = 1;
                    addEdge(2 + c, 2 + c + 1, 1, cost);
                    addEdge(2 + c + 1, 2 + c, 1, cost);
                }
            }
        }
        long res = minCostMaxFlow(0, 1);
        out.println(res);
    }

    private BufferedReader br;
    private PrintWriter out;
    private StringTokenizer st;

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

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

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

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

    private void run() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
//        br = new BufferedReader(new FileReader("input.txt"));
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    void init(int n, int m) {
        m *= 2;
        this.n = n;
        this.m = m;
        last = 0;
        head = new int[n];
        nx = new int[m];
        dst = new int[m];
        src = new int[m];
        cp = new int[m];
        ct = new long[m];
        fl = new int[m];
        prev = new int[n];
        heap = new int[n];
        heapRev = new int[n];
        d = new long[n];
        bestDist = new long[n];
        for (int i = 0; i < n; i++) {
            heap[i] = i;
            heapRev[i] = i;
        }
        Arrays.fill(head, -1);
    }

    void addEdge(int x, int y, int capacity, int cost) {
        nx[last] = head[x];
        src[last] = x;
        dst[last] = y;
        cp[last] = capacity;
        ct[last] = cost;
        head[x] = last;
        last++;
        nx[last] = head[y];
        src[last] = y;
        dst[last] = x;
        cp[last] = 0;
        ct[last] = -cost;
        head[y] = last;
        last++;
    }

    // Returns the total cost. Max flow value will be in field maxFlow.
    long minCostMaxFlow(int s, int t) {
        for (int i = 0; i < n; i++) {
            d[i] = INF;
        }
        d[s] = 0;
        boolean ok = false;
        while (!ok) {
            ok = true;
            for (int j = 0; j < m; j++)
                if (fl[j] < cp[j]) {
                    int x = src[j];
                    int y = dst[j];
                    if (d[x] < INF) {
                        if (d[y] > d[x] + ct[j]) {
                            d[y] = d[x] + ct[j];
                            ok = false;
                        }
                    }
                }
        }
        long res = 0;
        maxFlow = 0;
        while (true) {
            dijkstra(s);
            if (bestDist[t] == INF) break;
            {
                int i = t;
                int f = Integer.MAX_VALUE;
                while (i != s) {
                    int e = prev[i];
                    f = Math.min(f, cp[e] - fl[e]);
                    i = src[e];
                }
                if (f < 0) throw new RuntimeException();
                maxFlow += f;
                i = t;
                while (i != s) {
                    int e = prev[i];
                    fl[e] += f;
                    fl[e ^ 1] -= f;
                    if (fl[e] > cp[e]) throw new RuntimeException();
                    res += ct[e] * f;
                    i = src[e];
                }
            }
            for (int i = 0; i < n; i++) {
                d[i] += bestDist[i];
            }
        }
        return res;
    }

    private static final long INF = Long.MAX_VALUE;

    int n, m;
    int[] head;
    int[] nx;
    int[] src;
    int[] dst;
    int[] cp;
    long[] ct;
    int[] fl;
    int last;

    long[] d;
    long[] bestDist;
    int[] prev;
    int[] heap;
    int[] heapRev;
    int heapSize;
    long maxFlow;

    private void dijkstra(int start) {
        Arrays.fill(bestDist, INF);
        heapSize = n;
        bestDist[start] = 0;
        siftUp(heapRev[start]);
        for (int i = 0; i < n; i++) {
            int x = removeMin();
            if (bestDist[x] == INF) {
                break;
            }
            int j = head[x];
            while (j >= 0) {
                if (fl[j] < cp[j]) {
                    int y = dst[j];
                    long d = ct[j] + this.d[x] - this.d[y];
                    if (d < 0) {
                        throw new AssertionError("negative edge");
                    }
                    long ll = bestDist[x] + d;
                    if (bestDist[y] > ll) {
                        prev[y] = j;
                        bestDist[y] = ll;
                        siftUp(heapRev[y]);
                    }
                }
                j = nx[j];
            }
        }
    }

    private void siftUp(int i) {
        while (i > 0 && bestDist[heap[(i - 1) / 2]] > bestDist[heap[i]]) {
            swap(i, (i - 1) / 2);
            i = (i - 1) / 2;
        }
    }

    private int removeMin() {
        int res = heap[0];
        swap(0, heapSize - 1);
        heapSize--;
        int i = 0;
        while (2 * i + 1 < heapSize) {
            int j = i;
            if (bestDist[heap[2 * i + 1]] < bestDist[heap[j]]) {
                j = 2 * i + 1;
            }
            if (2 * i + 2 < heapSize && bestDist[heap[2 * i + 2]] < bestDist[heap[j]]) {
                j = 2 * i + 2;
            }
            if (i == j) break;
            swap(i, j);
            i = j;
        }
        return res;
    }

    private void swap(int i, int j) {
        int t = heap[i];
        heap[i] = heap[j];
        heap[j] = t;
        heapRev[heap[i]] = i;
        heapRev[heap[j]] = j;
    }}


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

import static java.lang.Math.*;

public class Solution implements Runnable {

	class Edge {

		int to, capacity, cost;
		int flow = 0;
		Edge compl = null;

		public Edge(int to, int capacity, int cost) {
			this.to = to;
			this.capacity = capacity;
			this.cost = cost;
		}

	}

	int n, m;
	Edge[][] graph;
	int[] size;

	void addEdge(int from, int to, int cost) {
		Edge e1 = new Edge(to, 1, cost);
		Edge e2 = new Edge(from, 0, -cost);
		e1.compl = e2;
		e2.compl = e1;
		graph[from][size[from]++] = e1;
		graph[to][size[to]++] = e2;
	}

	boolean inBounds(int i, int j) {
		return i >= 0 && i < n && j >= 0 && j < m;
	}

	int getIndex(int i, int j) {
		return i * m + j;
	}

	void randomShuffle(int[] arr) {
		Random rnd = new Random();
		for (int i = arr.length - 1; i >= 0; i--) {
			int pos = rnd.nextInt(i + 1);
			int temp = arr[pos];
			arr[pos] = arr[i];
			arr[i] = temp;
		}
	}

	public void solve() throws Exception {
		n = sc.nextInt();
		m = sc.nextInt();
		int[][] field = new int[n][m];

		int[] arr = new int[n * m];
		for (int i = 0; i < n * m; i += 2) {
			arr[i] = arr[i + 1] = i / 2 + 1;
		}

		randomShuffle(arr);

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				//field[i][j] = sc.nextInt();
				field[i][j] = arr[getIndex(i, j)];
				out.print(field[i][j] + " ");
			}
			out.println();
		}
		out.println();
		graph = new Edge[n * m + 2][20];
		size = new int[n * m + 2];
		int source = n * m;
		int sink = n * m + 1;
		graph[source] = new Edge[n * m];
		graph[sink] = new Edge[n * m];
		int gsize = n * m + 2;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if ((i + j) % 2 == 0) {
					addEdge(source, getIndex(i, j), 0);
					if (inBounds(i - 1, j)) {
						if (field[i - 1][j] == field[i][j]) {
							addEdge(getIndex(i, j), getIndex(i - 1, j), 0);
						} else {
							addEdge(getIndex(i, j), getIndex(i - 1, j), 1);
						}
					}
					if (inBounds(i + 1, j)) {
						if (field[i + 1][j] == field[i][j]) {
							addEdge(getIndex(i, j), getIndex(i + 1, j), 0);
						} else {
							addEdge(getIndex(i, j), getIndex(i + 1, j), 1);
						}
					}
					if (inBounds(i, j - 1)) {
						if (field[i][j - 1] == field[i][j]) {
							addEdge(getIndex(i, j), getIndex(i, j - 1), 0);
						} else {
							addEdge(getIndex(i, j), getIndex(i, j - 1), 1);
						}
					}
					if (inBounds(i, j + 1)) {
						if (field[i][j + 1] == field[i][j]) {
							addEdge(getIndex(i, j), getIndex(i, j + 1), 0);
						} else {
							addEdge(getIndex(i, j), getIndex(i, j + 1), 1);
						}
					}
				} else {
					addEdge(getIndex(i, j), sink, 0);
				}
			}
		}

		int[] dist = new int[gsize];
		int[] from = new int[gsize];
		Edge[] byEdge = new Edge[gsize];
		Deque<Integer> q = new ArrayDeque<Integer>();

		int cost = 0;
		int flow = 0;

		while (true) {
			Arrays.fill(dist, Integer.MAX_VALUE / 4);
			q.clear();
			Arrays.fill(from, -1);
			Arrays.fill(byEdge, null);
			dist[source] = 0;
			q.offer(source);
			while (!q.isEmpty()) {
				int v = q.poll();
				for (int i = 0; i < size[v]; i++) {
					Edge e = graph[v][i];
					if (e.capacity - e.flow > 0 && dist[e.to] > dist[v] + e.cost) {
						dist[e.to] = dist[v] + e.cost;
						from[e.to] = v;
						byEdge[e.to] = e;
						if (e.cost == 0) {
							q.offerFirst(e.to);
						} else {
							q.offerLast(e.to);
						}
					}
				}
			}
			if (dist[sink] == Integer.MAX_VALUE / 4) {
				break;
			}
			cost += dist[sink];
			flow++;
			int curv = sink;
			while (from[curv] != -1) {
				Edge e = byEdge[curv];
				Edge compl = e.compl;
				e.flow++;
				compl.flow--;
				curv = from[curv];
			}
		}

		out.println(cost);
	}

	static Throwable uncaught;

	BufferedReader in;
	FastScanner sc;
	PrintWriter out;

	@Override
	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			sc = new FastScanner(in);
			solve();
		} catch (Throwable uncaught) {
			Solution.uncaught = uncaught;
		} finally {
			out.close();
		}
	}

	public static void main(String[] args) throws Throwable {
		Thread thread = new Thread(null, new Solution(), "", (1 << 26));
		thread.start();
		thread.join();
		if (Solution.uncaught != null) {
			throw Solution.uncaught;
		}
	}

}

class FastScanner {

	BufferedReader in;
	StringTokenizer st;

	public FastScanner(BufferedReader in) {
		this.in = in;
	}

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

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

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

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

}


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

public class C {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	int n, m;

	class Edge {
		int to, flow, cap, cost;
		Edge rev;

		public Edge(int to, int cap, int cost) {
			this.to = to;
			this.cap = cap;
			this.cost = cost;
		}
	}

	static final int[] dx = { -1, 0, 1, 0 };
	static final int[] dy = { 0, -1, 0, 1 };
	static final int INF = Integer.MAX_VALUE / 3;

	List<Edge>[] g;

	void addEdge(int v1, int v2, int cost) {
		Edge e1 = new Edge(v2, 1, cost);
		Edge e2 = new Edge(v1, 0, -cost);
		e1.rev = e2;
		e2.rev = e1;
		g[v1].add(e1);
		g[v2].add(e2);
	}

	int S, T;

	void solve() throws IOException {
		n = nextInt();
		m = nextInt();

		int[][] f = new int[n][m];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				f[i][j] = nextInt();

		g = new ArrayList[n * m + 2];
		S = n * m;
		T = n * m + 1;
		for (int i = 0; i < n * m; i++)
			g[i] = new ArrayList<>(4);
		g[S] = new ArrayList<>(n * m / 2);
		g[T] = new ArrayList<>(n * m / 2);

		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				int v = i * m + j;
				int col = (i + j) & 1;
				if (col == 0) {
					addEdge(S, v, 0);
					for (int dir = 0; dir < 4; dir++) {
						int ni = i + dx[dir];
						int nj = j + dy[dir];
						if (ni >= 0 && ni < n && nj >= 0 && nj < m) {
							int to = ni * m + nj;
							int cost = (f[i][j] == f[ni][nj] ? 0 : 1);
							addEdge(v, to, cost);
						}
					}
				} else {
					addEdge(v, T, 0);
				}
			}

		int ans = 0;
		int[] pi = new int[n * m + 2];

		final int[] d = new int[n * m + 2];
		Edge[] from = new Edge[n * m + 2];

		Integer[] Integers = new Integer[n * m + 2];
		for (int i = 0; i < n * m + 2; i++)
			Integers[i] = i;

		TreeSet<Integer> set = new TreeSet<>(new Comparator<Integer>() {

			@Override
			public int compare(Integer o1, Integer o2) {
				if (d[o1] != d[o2])
					return Integer.compare(d[o1], d[o2]);
				return o1.compareTo(o2);
			}

		});

		List<Integer> permLabeled = new ArrayList<>();

		for (int iter = 0; iter < n * m / 2; iter++) {

			Arrays.fill(d, INF);
			d[S] = 0;

			for (int i = 0; i < n * m + 2; i++)
				set.add(Integers[i]);

			permLabeled.clear();

			while (true) {
				int v = set.pollFirst();

//				System.err.println(v + " " + Arrays.toString(d));

				if (v == T) {
					break;
				}

				permLabeled.add(Integers[v]);

				for (int i = 0; i < g[v].size(); i++) {
					Edge e = g[v].get(i);
					if (e.flow < e.cap) {
						int redCost = e.cost - pi[v] + pi[e.to];
						if (d[e.to] > d[v] + redCost) {
							set.remove(Integers[e.to]);
							from[e.to] = e;
							d[e.to] = d[v] + redCost;
							set.add(Integers[e.to]);
						}
					}
				}
			}

			for (int i = 0; i < permLabeled.size(); i++) {
				int v = permLabeled.get(i);
				pi[v] = pi[v] - d[v] + d[T];
			}

			for (int v = T; v != S; ) {
				Edge last = from[v];
				last.flow++;
				last.rev.flow--;
				ans += last.cost;
				v = last.rev.to;
			}

		}

		out.println(ans);

	}

	C() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


import java.util.*;

public class Main
{
    public static void main(String[] args)
    {
    int a,b,c,d;
    Scanner scn=new Scanner(System.in);
    a=scn.nextInt();
    b=scn.nextInt();
    c=scn.nextInt();
    d=scn.nextInt();

    int x,y,z;
    if(a==c&&b==d)
        x=0;
else if(a==c||b==d)
    x=1;
    else
    x=2;
if(a==b&&b==c)
y=0;
else if((a+b)%2==(c+d)%2)
{
    if(Math.abs(c-a)==Math.abs(d-b))
    y=1;
    else
    y=2;
}
else
y=0;

z=max(Math.abs(c-a),Math.abs(d-b));
System.out.println(x+" "+y+" "+z);
}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.atomic.AtomicIntegerArray;

public class Solution {

    public static void main(String[] args) throws Exception {
        MyReader reader = new MyReader(System.in);
//        MyReader reader = new MyReader(new FileInputStream("input.txt"));
        MyWriter writer = new MyWriter(System.out);
        new Solution().run(reader, writer);
        writer.close();
    }

    private void run(MyReader reader, MyWriter writer) throws Exception {
        long a = reader.nextInt();
        long b = reader.nextInt();
        long bb = b;
        int p = reader.nextInt();
        long x = reader.nextLong();
        long[] q = new long[p];
        long[] qq = new long[p];
        long[] aa = new long[p];
        q[0] = 1;
        for (int i = 1; i < p; i++) {
            q[i] = (q[i - 1] * a) % p;
            qq[i] = (q[i] * i) % p;
            aa[(int)qq[i]]++;
        }
        long ans = 0;
        for (int i = 0; i < x / p; i++) {
            ans += aa[(int)b];
            b = b * q[p - 2] % p;
        }
        long t = x / p * p;
        for (long i = t; i <= x; i++) {
            if (i * q[(int)(i - t)] % p == b) {
                ans++;
            }
        }
        System.out.println(ans);
    }

    static class MyReader {

        final BufferedInputStream in;
        final int bufSize = 1 << 16;
        final byte buf[] = new byte[bufSize];
        int i = bufSize;
        int k = bufSize;
        boolean end = false;
        final StringBuilder str = new StringBuilder();

        MyReader(InputStream in) {
            this.in = new BufferedInputStream(in, bufSize);
        }

        int nextInt() throws IOException {
            return (int) nextLong();
        }

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

        int[][] nextIntMatrix(int n, int m) throws IOException {
            int[][] a = new int[n][0];
            for (int j = 0; j < n; j++) {
                a[j] = nextIntArray(m);
            }
            return a;
        }

        long nextLong() throws IOException {
            int c;
            long x = 0;
            boolean sign = true;
            while ((c = nextChar()) <= 32) ;
            if (c == '-') {
                sign = false;
                c = nextChar();
            }
            if (c == '+') {
                c = nextChar();
            }
            while (c >= '0') {
                x = x * 10 + (c - '0');
                c = nextChar();
            }
            return sign ? x : -x;
        }

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

        int nextChar() throws IOException {
            if (i == k) {
                k = in.read(buf, 0, bufSize);
                i = 0;
            }
            return i >= k ? -1 : buf[i++];
        }

        String nextString() throws IOException {
            if (end) {
                return null;
            }
            str.setLength(0);
            int c;
            while ((c = nextChar()) <= 32 && c != -1) ;
            if (c == -1) {
                end = true;
                return null;
            }
            while (c > 32) {
                str.append((char) c);
                c = nextChar();
            }
            return str.toString();
        }

        String nextLine() throws IOException {
            if (end) {
                return null;
            }
            str.setLength(0);
            int c = nextChar();
            while (c != '\n' && c != '\r' && c != -1) {
                str.append((char) c);
                c = nextChar();
            }
            if (c == -1) {
                end = true;
                if (str.length() == 0) {
                    return null;
                }
            }
            if (c == '\r') {
                nextChar();
            }
            return str.toString();
        }

        char[] nextCharArray() throws IOException {
            return nextString().toCharArray();
        }

        char[][] nextCharMatrix(int n) throws IOException {
            char[][] a = new char[n][0];
            for (int i = 0; i < n; i++) {
                a[i] = nextCharArray();
            }
            return a;
        }
    }

    static class MyWriter {

        final BufferedOutputStream out;
        final int bufSize = 1 << 16;
        final byte buf[] = new byte[bufSize];
        int i = 0;
        final byte c[] = new byte[30];
        static final String newLine = System.getProperty("line.separator");

        MyWriter(OutputStream out) {
            this.out = new BufferedOutputStream(out, bufSize);
        }

        void print(long x) throws IOException {
            int j = 0;
            if (i + 30 >= bufSize) {
                flush();
            }
            if (x < 0) {
                buf[i++] = (byte) ('-');
                x = -x;
            }
            while (j == 0 || x != 0) {
                c[j++] = (byte) (x % 10 + '0');
                x /= 10;
            }
            while (j-- > 0)
                buf[i++] = c[j];
        }

        void print(int[] m) throws IOException {
            for (int a : m) {
                print(a);
                print(' ');
            }
        }

        void print(long[] m) throws IOException {
            for (long a : m) {
                print(a);
                print(' ');
            }
        }

        void print(String s) throws IOException {
            for (int i = 0; i < s.length(); i++) {
                print(s.charAt(i));
            }
        }

        void print(char x) throws IOException {
            if (i == bufSize) {
                flush();
            }
            buf[i++] = (byte) x;
        }

        void print(char[] m) throws IOException {
            for (char c : m) {
                print(c);
            }
        }

        void println(String s) throws IOException {
            print(s);
            println();
        }

        void println() throws IOException {
            print(newLine);
        }

        void flush() throws IOException {
            out.write(buf, 0, i);
            out.flush();
            i = 0;
        }

        void close() throws IOException {
            flush();
            out.close();
        }
    }
}


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.TreeSet;

public final class CF_460_E{

	static boolean verb=true;
	static void log(Object X){if (verb) System.err.println(X);}
	static void log(Object[] X){if (verb) {for (Object U:X) System.err.print(U+" ");System.err.println("");}}
	static void log(int[] X){if (verb) {for (int U:X) System.err.print(U+" ");System.err.println("");}}
	static void log(int[] X,int L){if (verb) {for (int i=0;i<L;i++) System.err.print(X[i]+" ");System.err.println("");}}
	static void log(long[] X){if (verb) {for (long U:X) System.err.print(U+" ");System.err.println("");}}

	static void logWln(Object X){if (verb) System.err.print(X);}
	static void info(Object o){	System.out.println(o);}
	static void output(Object o){outputWln(""+o+"\n");	}
	static void outputWln(Object o){try {out.write(""+ o);} catch (Exception e) {}}

	static long mod=1000000007;
	static long MX=1000000000000000001L;

	// Global vars
	static BufferedWriter out;
	static InputReader reader;

	static long powerMod(long b,long e,long m){
		long x=1;
		while (e>0) {
			if (e%2==1)
				x=(b*x)%m;
			b=(b*b)%m;
			e=e/2;
		}
		return x;
	}

	static void process() throws Exception {

		out = new BufferedWriter(new OutputStreamWriter(System.out));
		reader=new InputReader(System.in);

		int a=reader.readInt();
		int b=reader.readInt();
		int p=reader.readInt();
		long x=reader.readLong();

		long pp=p;

		ArrayList<Integer>[] targy=new ArrayList[p];
		ArrayList<Integer>[] targk=new ArrayList[p];
		for (int u=1;u<p;u++){
			targy[u]=new ArrayList<Integer>();
			targk[u]=new ArrayList<Integer>();

		}

		for (int y=1;y<p;y++){
			long yay=powerMod(a,y,p);
			yay*=y;
			yay%=p;
			long inv=powerMod(yay,p-2,p);
			long fin=inv*b;
			fin%=p;
			targy[(int)fin].add(y);
		}
		for (int k=0;k<p-1;k++){
			long ak=powerMod(a,k,p);
			targk[(int)ak].add(k);
		}
		long sum=0;
		for (int u=1;u<p;u++){
			if (targy[u].size()>0 && targk[u].size()>0){
				for (long k:targk[u])
					for (long y:targy[u]){

						if (p*k+y<=x){
							long mt=(x-y-pp*k)/(pp*(pp-1));
							sum+=mt+1;
						}

						/*
						long t=0;
						while (((p-1)*t+k)*p+y<=x){
							t++;
							sum++;
						}
						*/

					}
			}
		}
		output(sum);

		try {
			out.close();
		}
		catch (Exception EX){}

	}

	public static void main(String[] args) throws Exception {
		process();

	}

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

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

		private int read() throws IOException {
			if (curChar >= numChars) {
				curChar = 0;
				numChars = stream.read(buf);
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public final String readString() throws IOException {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res=new StringBuilder();
			do {
				res.append((char)c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public final int readInt() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			int res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

		public final long readLong() throws IOException {
			int c = read();
			boolean neg=false;
			while (isSpaceChar(c)) {
				c = read();
			}
			char d=(char)c;
			//log("d:"+d);
			if (d=='-') {
				neg=true;
				c = read();
			}
			long res = 0;
			do {
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			//log("res:"+res);
			if (neg)
				return -res;
			return res;

		}

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

}


import java.util.Scanner;

public class E {

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

        int a = in.nextInt();
        int b = in.nextInt();
        int p = in.nextInt();
        long x = in.nextInt();

        int answer = 0;
        for (int i = 0; i < p; i++) {
            int tmp = (b * modPow(modPow(a, i, p), p - 2, p)) % p;
            if (i >= tmp) {
                int first = (i - tmp) * (p-1) + i;
                if (first <= x)
                    answer += (x - first) / (p*(p-1)) + 1;
            }
        }

        System.out.println(answer);
    }

    private static int modPow(int a, int b, int mod) {
        int modPow = 1;
        for (; b > 0; b >>= 1) {
            if ((b & 1) != 0)
                modPow = (int) ((1L * modPow * a) % mod);
            a = (int) ((1L * a * a) % mod);
        }
        return modPow;
    }

}


/**
 * Date: 4 Jan, 2019
 * Link:
 *
 * @author Prasad-Chaudhari
 * @linkedIn: https://www.linkedin.com/in/prasad-chaudhari-841655a6/
 * @git: https://github.com/Prasad-Chaudhari
 */
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

public class newProgram6 {

    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        FastIO in = new FastIO();
        long n = in.nl();
        int k = in.ni();
        Set<Long> s = new HashSet<>();
        int limit = (int) Math.sqrt(n) + 10;
        for (int i = 1; i <= limit; i++) {
            if (n % i == 0) {
                s.add((long) i);
                s.add(n / i);
            }
        }
        Long a[] = s.toArray(new Long[0]);
        int index = a.length;
        Arrays.sort(a);
        long mod = 1000000007;
        long nods[] = new long[index];
        ArrayList<LinkedList<Integer>> a_l = new ArrayList<>();
        for (int i = 0; i < index; i++) {
            a_l.add(new LinkedList<>());
            for (int j = 0; j < index && a[j] <= a[i]; j++) {
                if (a[i] % a[j] == 0) {
                    nods[i]++;
                    a_l.get(i).add(j);
                }
            }
            nods[i] = Expo.a_pow_n_mod_m(nods[i], mod - 2, mod);
        }
        long dp[][] = new long[index][2];
        for (int i = 0; i <= 1; i++) {
            dp[0][i] = 1;
        }
        for (int i = 0; i < index; i++) {
            dp[i][0] = a[i] % mod;
        }
        for (int i = 1; i <= k; i++) {
            for (int j = 1; j < index; j++) {
                for (int l : a_l.get(j)) {
                    dp[j][1] += dp[l][0];
                }
                dp[j][1] %= mod;
                dp[j][1] *= nods[j];
                dp[j][1] %= mod;
            }
            for (int j = 1; j < index; j++) {
                dp[j][0] = dp[j][1];
                dp[j][1] = 0;
            }
        }
        System.out.println(dp[index - 1][0]);
    }

    static class Expo {

        static long a_pow_n_mod_m(long a, long n, long m) {
            if (n == 0) {
                return 1;
            }
            if (n == 1) {
                return a;
            }
            long p = a_pow_n_mod_m(a, n / 2, m);
            if (n % 2 == 0) {
                return (p * p) % m;
            } else {
                return ((p * p) % m * a) % m;
            }
        }

        static long a_pow_n(long a, long n) {
            if (n == 0) {
                return 1;
            }
            if (n == 1) {
                return a;
            }
            long p = a_pow_n(a, n / 2);
            if (n % 2 == 0) {
                return (p * p);
            } else {
                return ((p * p) * a);
            }
        }
    }

    static class FastIO {

        private final BufferedReader br;
        private final BufferedWriter bw;
        private String s[];
        private int index;
        private StringBuilder sb;

        public FastIO() throws IOException {
            br = new BufferedReader(new InputStreamReader(System.in));
            bw = new BufferedWriter(new OutputStreamWriter(System.out, "UTF-8"));
            s = br.readLine().split(" ");
            sb = new StringBuilder();
            index = 0;
        }

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

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

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

        public String next() throws IOException {
            return nextToken();
        }

        public String nli() throws IOException {
            try {
                return br.readLine();
            } catch (IOException ex) {

            }
            return null;
        }

        public int[] gia(int n) throws IOException {
            int a[] = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = ni();
            }
            return a;
        }

        public int[] gia(int n, int start, int end) throws IOException {
            validate(n, start, end);
            int a[] = new int[n];
            for (int i = start; i < end; i++) {
                a[i] = ni();
            }
            return a;
        }

        public double[] gda(int n) throws IOException {
            double a[] = new double[n];
            for (int i = 0; i < n; i++) {
                a[i] = nd();
            }
            return a;
        }

        public double[] gda(int n, int start, int end) throws IOException {
            validate(n, start, end);
            double a[] = new double[n];
            for (int i = start; i < end; i++) {
                a[i] = nd();
            }
            return a;
        }

        public long[] gla(int n) throws IOException {
            long a[] = new long[n];
            for (int i = 0; i < n; i++) {
                a[i] = nl();
            }
            return a;
        }

        public long[] gla(int n, int start, int end) throws IOException {
            validate(n, start, end);
            long a[] = new long[n];
            for (int i = start; i < end; i++) {
                a[i] = nl();
            }
            return a;
        }

        public int[][] gg(int n, int m) throws IOException {
            int adja[][] = new int[n + 1][];
            int from[] = new int[m];
            int to[] = new int[m];
            int count[] = new int[n + 1];
            for (int i = 0; i < m; i++) {
                from[i] = ni();
                to[i] = ni();
                count[from[i]]++;
                count[to[i]]++;
            }
            for (int i = 0; i <= n; i++) {
                adja[i] = new int[count[i]];
            }
            for (int i = 0; i < m; i++) {
                adja[from[i]][--count[from[i]]] = to[i];
                adja[to[i]][--count[to[i]]] = from[i];
            }
            return adja;
        }

        public void print(String s) throws IOException {
            bw.write(s);
        }

        public void println(String s) throws IOException {
            bw.write(s);
            bw.newLine();
        }

        private String nextToken() throws IndexOutOfBoundsException, IOException {
            if (index == s.length) {
                s = br.readLine().split(" ");
                index = 0;
            }
            return s[index++];
        }

        private void validate(int n, int start, int end) {
            if (start < 0 || end >= n) {
                throw new IllegalArgumentException();
            }
        }
    }

    static class Data implements Comparable<Data> {

        int a, b;

        public Data(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public int compareTo(Data o) {
            if (a == o.a) {
                return Integer.compare(b, o.b);
            }
            return Integer.compare(a, o.a);
        }

        public static void sort(int a[]) {
            Data d[] = new Data[a.length];
            for (int i = 0; i < a.length; i++) {
                d[i] = new Data(a[i], 0);
            }
            Arrays.sort(d);
            for (int i = 0; i < a.length; i++) {
                a[i] = d[i].a;
            }
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.InputStream;

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

    static class DMakotoAndABlackboard {
        long mod = 1000000007;
        long[][] dp;
        HashMap<Long, Integer> div;

        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            long n = in.scanLong();
            int k = in.scanInt();
            div = new HashMap<>();
            ArrayList<Long> divoo = new ArrayList<>();
            for (long i = 1; i * i <= n; i++) {
                if (n % i == 0) {
                    divoo.add(i);
                    if (i * i != n) {
                        divoo.add(n / i);
                    }
                }
            }

            int index = 0;
            for (long tt : divoo) {
                div.put(tt, index);
                index++;
            }
            dp = new long[div.size() + 5][k + 5];
            for (long arr[] : dp) {
                Arrays.fill(arr, -1);
            }
            out.println(tt(n, k));

        }

        long tt(long n, int step) {

            if (!div.containsKey(n)) {
                throw new ArrayIndexOutOfBoundsException("ERRO");

            }
            if (dp[div.get(n)][step] != -1) return dp[div.get(n)][step];
            if (step == 0) {
                return dp[div.get(n)][0] = n;
            } else {
                long sum = 0;
                int c = 0;
                for (long i = 1; i * i <= n; i++) {
                    if (n % i == 0) {
                        sum = (sum + tt(i, step - 1)) % mod;
                        c++;
                        if (i * i != n) {
                            sum = (sum + tt(n / i, step - 1)) % mod;
                            c++;
                        }
                    }
                }

                sum = (sum * CodeX.modinv(c, mod)) % mod;
                return dp[div.get(n)][step] = sum;

            }
        }

    }

    static class CodeX {
        public static long power(long x, long y, long p) {
            long res = 1;
            x = x % p;
            while (y > 0) {
                if ((y & 1) != 0)
                    res = (res * x) % p;
                y = y >> 1;
                x = (x * x) % p;
            }
            return res;
        }

        public static long modinv(long k, long mod) {
            return power(k, mod - 2, mod);
        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

        public long scanLong() {
            long I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

    }
}


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

public class Main {
    public static void main(String[] args) throws FileNotFoundException {
        ConsoleIO io = new ConsoleIO(new InputStreamReader(System.in), new PrintWriter(System.out));

//        String fileName = "C-large-practice";
//        ConsoleIO io = new ConsoleIO(new FileReader("D:\\Dropbox\\code\\practice\\jb\\src\\" + fileName + ".in"), new PrintWriter(new File("D:\\Dropbox\\code\\practice\\jb\\src\\" + fileName + ".out")));

        new Main(io).solve();
//        new Main(io).solveLocal();

        io.close();
    }

    ConsoleIO io;

    Main(ConsoleIO io) {
        this.io = io;
    }

    ConsoleIO opt;

    Main(ConsoleIO io, ConsoleIO opt) {
        this.io = io;
        this.opt = opt;
    }

    List<List<Integer>> gr = new ArrayList<>();

    long MOD = 1_000_000_007;

    public void solve() {
        long n = io.readLong();
        int k = io.ri();

        List<Long> divs = new ArrayList<>();
        for(long d = 1; d*d<= n; d++) {
            if (n % d == 0) {
                divs.add(d);
                if (d * d != n) {
                    divs.add(n / d);
                }
            }
        }

        divs.sort(Comparator.naturalOrder());

        int[][] subs = new int[divs.size()][];
        long[] numd = new long[divs.size()];
        for(int i = 0; i < divs.size(); i++){
            List<Integer> list = new ArrayList<>();
            long v = divs.get(i);
            for(int j = i; j < divs.size(); j++){
                if(divs.get(j) % v == 0){
                    list.add(j);
                    numd[j]++;
                }
            }
            subs[i] = new int[list.size()];
            for(int j = 0; j < list.size(); j++){
                subs[i][j] = list.get(j);
            }
        }

        for(int i = 0; i < divs.size(); i++){
            numd[i] = pow(numd[i], MOD - 2, MOD);
        }

        long[] count = new long[divs.size()];
        count[count.length - 1] = 1L;
        for(int step = 0; step < k; step++) {
            for (int i = 0; i < count.length; i++) {
                count[i] = (count[i] * numd[i]) % MOD;
            }
            for (int i = 0; i < count.length; i++) {
                int[] list = subs[i];

                long next = 0;
                for (int j : list) {
                    next = next + count[j];
                }
                count[i] = next % MOD;
            }
        }

        long res = 0;
        for(int i = 0; i < count.length; i++) {
            res = (res + divs.get(i) % MOD * count[i] % MOD) % MOD;
        }

        io.writeLine(res+"");
    }

    long div(long a, long b, long mod) {
        return (a * pow(b, mod - 2, mod)) % mod;
    }

    long pow(long a, long p, long mod) {
        long res = 1;
        while (p > 0) {
            if (p % 2 == 1) res = (res * a) % mod;
            a = (a * a) % mod;
            p /= 2;
        }
        return res;
    }

}

class ConsoleIO {

    BufferedReader br;
    PrintWriter out;
    public ConsoleIO(Reader reader, PrintWriter writer){br = new BufferedReader(reader);out = writer;}
    public void flush(){this.out.flush();}
    public void close(){this.out.close();}
    public void writeLine(String s) {this.out.println(s);}
    public void writeInt(int a) {this.out.print(a);this.out.print(' ');}
    public void writeWord(String s){
        this.out.print(s);
    }
    public void writeIntArray(int[] a, int k, String separator) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < k; i++) {
            if (i > 0) sb.append(separator);
            sb.append(a[i]);
        }
        this.writeLine(sb.toString());
    }
    public void writeLongArray(long[] a, int k, String separator) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < k; i++) {
            if (i > 0) sb.append(separator);
            sb.append(a[i]);
        }
        this.writeLine(sb.toString());
    }
    public int read(char[] buf, int len){try {return br.read(buf,0,len);}catch (Exception ex){ return -1; }}
    public String readLine() {try {return br.readLine();}catch (Exception ex){ return "";}}
    public long[] readLongArray() {
        String[]n=this.readLine().trim().split("\\s+");long[]r=new long[n.length];
        for(int i=0;i<n.length;i++)r[i]=Long.parseLong(n[i]);
        return r;
    }
    public int[] readIntArray() {
        String[]n=this.readLine().trim().split("\\s+");int[]r=new int[n.length];
        for(int i=0;i<n.length;i++)r[i]=Integer.parseInt(n[i]);
        return r;
    }
    public int[] readIntArray(int n) {
        int[] res = new int[n];
        char[] all = this.readLine().toCharArray();
        int cur = 0;boolean have = false;
        int k = 0;
        boolean neg = false;
        for(int i = 0;i<all.length;i++){
            if(all[i]>='0' && all[i]<='9'){
                cur = cur*10+all[i]-'0';
                have = true;
            }else if(all[i]=='-') {
                neg = true;
            }
            else if(have){
                res[k++] = neg?-cur:cur;
                cur = 0;
                have = false;
                neg = false;
            }
        }
        if(have)res[k++] = neg?-cur:cur;
        return res;
    }
    public int ri() {
        try {
            int r = 0;
            boolean start = false;
            boolean neg = false;
            while (true) {
                int c = br.read();
                if (c >= '0' && c <= '9') {
                    r = r * 10 + c - '0';
                    start = true;
                } else if (!start && c == '-') {
                    start = true;
                    neg = true;
                } else if (start || c == -1) return neg ? -r : r;
            }
        } catch (Exception ex) {
            return -1;
        }
    }
    public long readLong() {
        try {
            long r = 0;
            boolean start = false;
            boolean neg = false;
            while (true) {
                int c = br.read();
                if (c >= '0' && c <= '9') {
                    r = r * 10 + c - '0';
                    start = true;
                } else if (!start && c == '-') {
                    start = true;
                    neg = true;
                } else if (start || c == -1) return neg ? -r : r;
            }
        } catch (Exception ex) {
            return -1;
        }
    }
    public String readWord() {
        try {
            boolean start = false;
            StringBuilder sb = new StringBuilder();
            while (true) {
                int c = br.read();
                if (c!= ' ' && c!= '\r' && c!='\n' && c!='\t') {
                    sb.append((char)c);
                    start = true;
                } else if (start || c == -1) return sb.toString();
            }
        } catch (Exception ex) {
            return "";
        }
    }
    public char readSymbol() {
        try {
            while (true) {
                int c = br.read();
                if (c != ' ' && c != '\r' && c != '\n' && c != '\t') {
                    return (char) c;
                }
            }
        } catch (Exception ex) {
            return 0;
        }
    }
//public char readChar(){try {return (char)br.read();}catch (Exception ex){ return 0; }}
}
class Pair {
    public Pair(int a, int b) {this.a = a;this.b = b;}
    public int a;
    public int b;
}
class PairLL {
    public PairLL(long a, long b) {this.a = a;this.b = b;}
    public long a;
    public long b;
}
class Triple {
    public Triple(int a, int b, int c) {this.a = a;this.b = b;this.c = c;}
    public int a;
    public int b;
    public int c;
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.util.Random;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * @author khokharnikunj8
 */

public class Main {
    public static void main(String[] args) {
        new Thread(null, new Runnable() {
            public void run() {
                new Main().solve();
            }
        }, "1", 1 << 26).start();
    }

    void solve() {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DMakotoAndABlackboard solver = new DMakotoAndABlackboard();
        solver.solve(1, in, out);
        out.close();
    }

    static class DMakotoAndABlackboard {
        int mod = 1000000007;

        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            long n = in.scanLong();
            int k = in.scanInt();
            ArrayList<Long> div = new ArrayList<>();
            for (long i = 1; i * i <= n; i++) {
                if (n % i == 0) {
                    if (n / i != i) div.add(n / i);
                    div.add(i);
                }
            }
            long[] inverse = new long[div.size() + 1];
            for (int i = 0; i <= div.size(); i++) inverse[i] = CodeHash.pow(i, mod - 2, mod);
            long[] ar = new long[div.size()];
            int tt = 0;
            for (long i : div) ar[tt++] = i;
            CodeHash.shuffle(ar);
            Arrays.sort(ar);
            int[] size = new int[tt];
            ArrayList<Integer>[] index = new ArrayList[tt];
            for (int i = 0; i < tt; i++) index[i] = new ArrayList<>();
            for (int i = 0; i < tt; i++) {
                for (int j = 0; j <= i; j++) {
                    if (ar[i] % ar[j] == 0) {
                        size[i]++;
                        index[i].add(j);
                    }

                }
            }

            int[][] dp = new int[2][tt];
            dp[0][tt - 1] = 1;
            for (int i = 0; i < k; i++) {
                for (int j = 0; j < tt; j++) dp[(i + 1) & 1][j] = 0;
                for (int j = 0; j < tt; j++) {
                    int add = (int) ((dp[i & 1][j] * inverse[size[j]]) % mod);
                    for (int temp : index[j]) {
                        dp[(i + 1) & 1][temp] = (dp[(i + 1) & 1][temp] + add);
                        if (dp[(i + 1) & 1][temp] >= mod) dp[(i + 1) & 1][temp] -= mod;
                    }
                }
            }
            long ans = 0;
            for (int i = 0; i < tt; i++) ans = (ans + (((ar[i] % mod) * dp[k & 1][i]) % mod)) % mod;
            while (ans < 0) ans += mod;
            out.println(ans);
        }

    }

    static class CodeHash {
        public static void shuffle(long[] ar) {
            Random rd = new Random(new Random().nextInt());
            for (int i = 0; i < ar.length; i++) {
                int index = rd.nextInt(ar.length);
                long tt = ar[i];
                ar[i] = ar[index];
                ar[index] = tt;
            }
        }

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

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int index;
        private BufferedInputStream in;
        private int total;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (index >= total) {
                index = 0;
                try {
                    total = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (total <= 0) return -1;
            }
            return buf[index++];
        }

        public int scanInt() {
            int integer = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    integer *= 10;
                    integer += n - '0';
                    n = scan();
                }
            }
            return neg * integer;
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

        public long scanLong() {
            long integer = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    integer *= 10;
                    integer += n - '0';
                    n = scan();
                }
            }
            return neg * integer;
        }

    }
}


import java.io.*;
import java.text.*;
import java.util.*;
import java.math.*;
public class template {
	public static void main(String[] args) throws Exception {
		new template().run();
	}
	public static final int MOD = 1_000_000_007;
	public void run() throws Exception {
		FastScanner f = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		int n = f.nextInt();
		int k = f.nextInt();
		long[] inv = new long[51];
		for(int i = 1; i <= 50; i++) {
			inv[i] = modInv(i, MOD);
		}
		long[][] probs = new long[50][];
		for(int i = 0; i < 50; i++) {
			probs[i] = new long[i+1];
			Arrays.fill(probs[i], inv[i+1]);
			long[] aux = new long[i+1];
			for(int a = 1; a < k; a++) {
				aux[i] = inv[i+1] * probs[i][i] % MOD;
				for(int j = i-1; j >= 0; j--)  {
					aux[j] = (probs[i][j] * inv[j+1] % MOD + aux[j+1]) % MOD;
				}
				for(int j = 0; j <= i; j++)
					probs[i][j] = aux[j];
			}
		}
		long total = 1;
		for(long i = 2; i <= n; i++) {
			int cnt = 0;
			while(n % i == 0) {
				n /= i;
				cnt++;
			}
			long cur = 0;
			long pow = 1;
			for(int a = 0; a <= cnt; a++) {
				cur =  (cur + (pow * probs[cnt][a]) % MOD) % MOD;
				pow = (pow * i) % MOD;
			}
			total = (total * cur) % MOD;
		}
		out.println(total);
		out.flush();
	}
	public long modInv(int a, int b) {
		gcd(a,b);
		return ((x % b) + b) % b;
	}
	long x, y;
	public long gcd(int a, int b) {
		if(a == 0 || b == 0) {
			x = 0;
			y = 1;
			return a+b;
		}
		long res = gcd(b%a,a);
		long nx = y - b/a * x;
		long ny = x;
		x = nx;
		y = ny;
		return res;
	}
    static class FastScanner {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
        public FastScanner() {
            reader = new BufferedReader(new InputStreamReader(System.in), 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());
        }
        public long nextLong() {
        	return Long.parseLong(next());
        }
        public double nextDouble() {
        	return Double.parseDouble(next());
        }
        public String nextLine() {
        	try {
        		return reader.readLine();
        	} catch(IOException e) {
        		throw new RuntimeException(e);
        	}
        }
    }
}


import java.io.*;
import java.text.*;
import java.util.*;
import java.math.*;
public class template {
	public static void main(String[] args) throws Exception {
		new template().run();
	}
	public static final int MOD = 1_000_000_007;
	public void run() throws Exception {
		FastScanner f = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		long n = f.nextLong();
		int k = f.nextInt();
		long[] inv = new long[51];
		for(int i = 1; i <= 50; i++) {
			inv[i] = modInv(i, MOD);
		}
		long[][] probs = new long[50][];
		for(int i = 0; i < 50; i++) {
			probs[i] = new long[i+1];
			Arrays.fill(probs[i], inv[i+1]);
			long[] aux = new long[i+1];
			for(int a = 1; a < k; a++) {
				aux[i] = inv[i+1] * probs[i][i] % MOD;
				for(int j = i-1; j >= 0; j--)  {
					aux[j] = (probs[i][j] * inv[j+1] % MOD + aux[j+1]) % MOD;
				}
				for(int j = 0; j <= i; j++)
					probs[i][j] = aux[j];
			}
		}
		long total = 1;
		for(long i = 2; i <= n; i++) {
			int cnt = 0;
			while(n % i == 0) {
				n /= i;
				cnt++;
			}
			long cur = 0;
			long pow = 1;
			for(int a = 0; a <= cnt; a++) {
				cur =  (cur + (pow * probs[cnt][a]) % MOD) % MOD;
				pow = (pow * i) % MOD;
			}
			total = (total * cur) % MOD;
		}
		out.println(total);
		out.flush();
	}
	public long modInv(int a, int b) {
		gcd(a,b);
		return ((x % b) + b) % b;
	}
	long x, y;
	public long gcd(int a, int b) {
		if(a == 0 || b == 0) {
			x = 0;
			y = 1;
			return a+b;
		}
		long res = gcd(b%a,a);
		long nx = y - b/a * x;
		long ny = x;
		x = nx;
		y = ny;
		return res;
	}
    static class FastScanner {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
        public FastScanner() {
            reader = new BufferedReader(new InputStreamReader(System.in), 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());
        }
        public long nextLong() {
        	return Long.parseLong(next());
        }
        public double nextDouble() {
        	return Double.parseDouble(next());
        }
        public String nextLine() {
        	try {
        		return reader.readLine();
        	} catch(IOException e) {
        		throw new RuntimeException(e);
        	}
        }
    }
}


import java.util.Scanner;

public class Main {
	public static void main(){
		Scanner s=new Scanner(System.in);
		long n=s.nextLong();
		if(n % 2 ==0)
			System.out.print("white\n1 2");
		else
			System.out.print("black");

	}
}


public class Main {
static int A,B,C;
public static void main(String[] args) {
	Scanner in=new Scanner(System.in);
	A=in.nextInt();
	B=in.nextInt();
	C=in.nextInt();
	int te1=(C+B-1)*(A+B-1);
	int te2=B*(B-1);
	System.out.println(te1-te2);
}
}


import java.util.Scanner;

public class A {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        int c = sc.nextInt();
        int cnt = b+c-1;
        long ans = 0;
        int t = a;
        while (cnt > 0) {
            ans += t;
            cnt--;
            if (cnt==0)
                break;
            ans += t;
            cnt--;
            t++;
        }
        System.out.println(ans);
    }

}


public class CheapTravel {
    public static void main(String[] args) {
        Scanner sin = new Scanner(System.in);
        while(sin.hasNext()) {
            int n,m,a,b;
            n = sin.nextInt();//total rides of n
            m = sin.nextInt();//special rides of m
            a = sin.nextInt();//cost of m rides
            b = sin.nextInt();//cost of one ride
            int spending = 1000;
            int x = 0;
            //work out the minimum of the spending

            while(x <= n/m) {
                if(spending > (b-a*m)*x +a*n) {
                    spending = (b-a*m)*x +a*n;
                }
                x++;
            }
            System.out.print(spending);
        }
    }
}


public class Solution {
	public static void main( String[] args ) {
		Scanner in = new Scanner(System.in);
		String s = "";
		try {
			s = in.nextLine();
		}
		catch (Exception e){
			e.printStackTrace();
		}
		in.close();

		System.out.println(get(s));
	}

	public static int get( String s ) {
		int ret = 0;
		int count = 1;
		for( int i = 0; i < s.length(); i++ ) {
			while( i + 1 < s.length() && s.charAt(i) == s.charAt(i+1) ) {
				count++;
				i++;
			}
			if( count % 2 == 0 ) {
				ret++;
			}
			count = 1;
		}
		return ret;
	}
}


import com.sun.tools.javac.resources.legacy;

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

/**
 * @author arshsab
 * @since 05 2014
 */

public class PashaMaximizes {
    public static void main(String... args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] log = br.readLine().split(" ");

        final char[] A = log[0].toCharArray();
        int K = Integer.parseInt(log[1]);

        for (int i = 0; i < A.length && K > 0; i++) {
            int max = Integer.MIN_VALUE;
            int maxPos = -1;

            for (int j = i; j < A.length && j <= K + i; j++) {
                int fixed = A[j] - '0';

                if (fixed > max) {
                    max = fixed;
                    maxPos = j;
                }
            }

            if (max > A[i] - '0') {
                for (int j = maxPos - 1; j >= i; j--) {
                    A[j + 1] = A[j];
                }

                A[i] = (char) (max + '0');
                K -= maxPos - i;
            }
        }

        System.out.println(new String(A));
    }
}


import java.io.BufferedReader;

public class Main {

    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        int x = sc.nextInt();
        int algarisms[] = new int[s.length()];
        int nAlgarisms=s.length();

        for(int i=0; i<s.length(); i++){
            algarisms[i] = Character.digit(s.charAt(i), 10);
        }

        //System.out.println(Arrays.toString(algarisms));

        int i=0;
        int subArray[] = new int[x+1];

        while(x>0 && i<algarisms.length-1){
            subArray = getSubArray(algarisms, i, x);

            int maxIndex = getMaxIndexArray(subArray);
            x -= maxIndex;
            for(int j=maxIndex; j>0; j--){
                int temp=algarisms[i+j];
                algarisms[i+j]=algarisms[i+j-1];
                algarisms[i+j-1]=temp;
            }
            i++;
            subArray = new int[x+1];

        }

        double result=0;
        for(int j=nAlgarisms-1; j>=0; j--){
            result+=Math.pow(10,j)*(double)(algarisms[nAlgarisms-1-j]);
        }
        System.out.println(String.format("%.0f",result));
        //System.out.println(result);
        //System.out.println(Arrays.toString(algarisms));

    }

    public static int getMaxIndexArray(int array[]){
        int max = 0;
        int index = 0;
        for(int i=0; i<array.length; i++){
            //In case of draw, will return the first index
            if(array[i]>max){
                max=array[i];
                index=i;
            }
        }

        return index;
    }

    public static int[] getSubArray(int array[], int startIndex, int plus){
        int newArray[] = new int[plus+1];
        int endIndex = startIndex+plus<array.length? startIndex+plus:array.length-1;

        for(int i=startIndex; i<=endIndex; i++){
            newArray[i-startIndex] = array[i];
        }

        return newArray;
    }
}


import java.util.*;

public class A {

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

        boolean result = false;

        if(isPal(a)){
            result = true;
        }
        while(a.charAt(a.length()-1)=='0'){
            a=a.substring(0,a.length()-1);
            if(isPali(a)){
                result = true;
            }
        }

        System.out.println(result);
    }

    public static void isPali(String a){
        for(int i = 0; i<a.length()/2; i++){
            if(a.charAt(i)!=a.charAt(a.length()-i-1)]){
                return false;
            }
        }
        return true;
    }

}


import java.util.Scanner;

/**
 * Created by hwb on 2017/9/25.
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //while(in.hasNext()){
            String ss = in.nextLine();

            boolean flag = judge(ss);
            if(flag){
                System.out.println("YES");
            }
            else {
                System.out.println("NO");
            }
       // }
    }

    public static boolean judge(String ss) {
        int len = ss.length();
        int i=0,j=len-1;
        while(ss.charAt(j)=='0'){
           j--;
        }
		int flag=0
        while (i<j){
			if(ss.charAt(i)!=ss.charAt(j)){
				flag=1;
				break;
			}
            i++;
            j--;
        }
        if(flag==0){
            return true;
        }
        else{
            return false;
        }
    }
}


import java.util.*;
public class Prob2
{
	public static void main(String args[])
	{
		Scanner sc=new Scanner(System.in);
		int point=sc.nextInt();
		int i,j,l,n,x=0;
		n=point*(point+1)/2;
		int start[]=new int[n];
		int end[]=new int[n];
		boolean taken[]=new boolean[n];
		for(i=0;i<=point;i++)
		{
			for(j=i+1;j<=point;j++)
			{
			      start[x]=i;
			      end[x++]=j;
			}
		}
	int rem=x,ans=0;
	for(l=point;l>0;l--)
	{
	    for(i=0;i<x;i++)
	    {
	    for(j=i+1;j<x;j++)
	     {
		if(end[i]==start[j]&&((end[i]-start[i]+end[j]-start[j])==l))
				{
					end[i]=start[i]=end[j]=start[j]=-1;
					rem=rem-2;
					ans++;
					break;
				}
	       }
	     }
	}
	System.out.println(ans+rem);
	}
}


/**
 *  This class contains all kinds of searching techniques.
 *  @author: himself
*/

public class Main {

    // Iterative Binary Search -- O(lg(n))

    static int iterBinSearch(int[] arr, int n) {
        int l = 0, r = arr.length - 1, mid;
        while(l <= r) {
            mid = (l + r) / 2;
            if(arr[mid] == n)
                return mid;
            if(arr[mid] < n)
                l = mid + 1;
            else
                r = mid - 1;
        }
        return -1;
    }

    // Recursive Binary Search -- O(lg(n))

    static int binSearch(int[] arr, int n) {
        return binSearch(arr, n, 0, arr.length - 1);
    }

    static int binSearch(int[] arr, int n, int l, int r) {
        if(l <= r) {
            int mid = (l + r) / 2;
            if(arr[mid] == n)
                return mid;
            if(arr[mid] < n)
                return binSearch(arr, n, mid + 1, r);
            else
                return binSearch(arr, n, l, mid - 1);
        }
        return -1;
    }

    public static void main(String[] args) throws IOException {
        Reader.init(System.in);
        int n = Reader.nextInt();
        int[] arr = new int[n];
        for(int i = 0; i < n; i++)
            arr[i] = Reader.nextInt();
    }
}


import java.util.*;
public class Main{
    public static int main(String[] args){
        Scanner s= new Scanner(System.in);
        int n = s.nextInt();
        if(n%2==0){
            System.out.println(((n/2)+1)*(n/2));
        }else{
            System.out.println(((n/2)+1)*((n/2)+1));
        }
    }
}


import java.util.Hashtable;
import java.util.Scanner;

public class BusesBetweenCities {
    static Scanner scan= new Scanner(System.in);

    public static void main(String [] args){
        int a= scan.nextInt();
        int ta= scan.nextInt();

        int b= scan.nextInt();
        int tb= scan.nextInt();

        String []time= scan.next().split(":");
        int hr= Integer.parseInt(time[0]);
        int min= Integer.parseInt(time[1]);

        Hashtable<Integer, Integer> waitingList= new Hashtable<>();

        int simonTime= hr*60 + min;
        int reachSimon= simonTime + ta;
        int count = 0;
        for(int hour= 5; hour <= 23; hour++){
            for(int minute= 0; minute <= 59; minute++){
                int currentTime= hour * 60 + minute;

                if(currentTime % b == 0) {
                    waitingList.putIfAbsent(currentTime + tb, currentTime);
                    if(currentTime > simonTime && currentTime != reachSimon) count++;
                }
                if(waitingList.get(currentTime) != null)
                    waitingList.remove(currentTime);

                if(currentTime == simonTime)
                    count+= waitingList.size();
                if(currentTime == reachSimon) {
                    hour = 25; break;
                }
            }
        }
        System.out.println(count);
    }
}


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

    static class Te {
        public void solve(int testNumber, MyScan in, PrintWriter out) {
            int n = in.nextInt();
            int k = in.nextInt();
            long[] res = new long[n + 1];
            long[] sum = new long[n + 1];
            for (int t = k + 2; t <= n; t++) {
                long cur0 = Util.fact(t - 2);
                long cur1 = (t - k - 1) + sum[t - 1] - sum[t - k - 1] + Util._m;
                cur1 %= Util._m;
                res[t] = cur0 * cur1 % Util._m;
                sum[t] = (sum[t - 1] + res[t] * Util.inv(t - 1) % Util._m) % Util._m;
            }
            out.println(res[n]);
        }

    }

    static class Util {
        public static final long M07 = 1000_000_007;
        public static final long _m = M07;
        private static long[] fact;
        private static long[] inv;
        private static long[] ifact;

        public static void l() {
            fact = new long[1000001];
            inv = new long[1000001];
            ifact = new long[1000001];
            for (int s = 0; s < 2; s++) {
                fact[s] = 1;
                ifact[s] = 1;
                inv[s] = 1;
            }
            inv[0] = 0;
            for (int i = 2; i < inv.length; i++) {
                inv[i] = (_m - (_m / i) * inv[(int) (_m % i)] % _m) % _m;
            }
            for (int i = 2; i < fact.length; i++) {
                fact[i] = i * fact[i - 1] % _m;
                ifact[i] = inv[i] * ifact[i - 1] % _m;
            }
        }

        public static long fact(int a) {
            if (fact == null) l();
            return fact[a];
        }

        public static long pow(long v, long k, long m) {
            if (k == 0) return 1;
            long t = pow(v, k / 2, m);
            t *= t;
            t %= m;
            if (k % 2 == 1) {
                t *= v;
            }
            return t % m;

        }

        public static long powm(long v, long k) {
            return pow(v, k, _m);
        }

        public static long inv(long v) {
            if (inv == null) l();
            if (v < inv.length) return inv[(int) v];
            return powm(v, _m - 2);
        }

    }

    static class MyScan {
        private final InputStream in;
        private byte[] inbuf = new byte[1024];
        public int lenbuf = 0;
        public int ptrbuf = 0;

        public MyScan(InputStream in) {
            this.in = in;
        }

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

        public int nextInt() {
            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();
            }
        }

    }
}


import java.util.*;

public class Main {
    public static int pow(int base, int exp, int mod) {
        if (exp == 0)
            return 1 % mod ;
        else
            return (base * pow(base, exp - 1, mod)) % mod;
    }

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

        int size = in.nextInt();
        System.out.println(((size==0)?1:(pow(3, size - 1, (int)Math.pow(10, 6) + 3)));
    }
}


import java.io.IOException;
import java.util.Scanner;

public class seventyA {
	public static void main(String srgs[]) throws IOException {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(), l = 0;
		long r = 1;
		for (int i = 0; i < n - 1; i ++) {
			r = r * 3;
		}
		while (l < 1) {
			if (r > 1000003) r = Math.abs(r-1000003); else l = 1;
		}
		System.out.print(r);
	}
}


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

public class Reflection {
    public static void main (String [] args){
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        try{
            String in[] = br.readLine().split(" ");
            long l = Integer.parseInt(in[0]);
            long r = Integer.parseInt(in[1]);
            long opt = (int)(5*Math.pow(10,in[1].length()-1));
            long max =0;
            if(l<= opt && opt<=r){
                max = opt * reflection(opt);
            }
            else{
                long wl = l*reflection(l);
                long wr = r*reflection(r);
                if(wl<wr){
                    max =wr;
                }
                else
                    max = wl;
            }
            System.out.println(max);
        }
        catch(IOException e){}

    }
    public static int reflection(long x){
        String s = x+"";
        char tmp[] = s.toCharArray();
        String reflection="";
        for(int i=0;i<tmp.length;i++){
            reflection+=(9-Character.getNumericValue(tmp[i]));
        }
        return Integer.parseInt(reflection);
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class AMain {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int min = Integer.parseInt(st.nextToken());
		int max = Integer.parseInt(st.nextToken());
		int len = Integer.toString(max).length();
		if(Integer.toString(min).length() != len)		{
			min = (int)Math.pow(10, len-1);
		}
		while(min + 100 < max)	{
			int a = (int)((2L*min+max)/3);
			int b = (int)((2L*max+min)/3);
			if(gen(a) < gen(b))	{
				min = a;
			}
			else	{
				max = b;
			}
		}
		int best = min;
		for(int i = min+1; i <= max; i++)	{
			if(gen(i) > gen(best))
				best = i;
		}
		System.out.println(gen(best));
		// 10^len
		// 10^(len+1)-1
		// min
		// max
		// 4999999
		// 5000000
	}
	public static long gen(int x)	{
		int length = Integer.toString(x).length();
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < length; i++)
			sb.append(9);
		int y = Integer.parseInt(sb.toString())-x;
		return 1L*x*y;
	}
}


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Reflections {

	private int[] memo;

	private int reflect(int x) {
		if(x == 0) {
			return 0;
		}
		if(memo[x] != -1) {
			return memo[x];
		}

		int r = 10 * reflect(x / 10) + 9 - (x % 10);
		memo[x] = r;
		return r;
	}

	public void run() throws IOException {
		int l = nextInt();
		int r = nextInt();

		memo = new int[l + 1];
		Arrays.fill(memo, -1);

		long max = 0;

		for(; l <= r; ++l) {
			max = Math.max(max, (long)l * reflect(l));
		}
		writer.print(max);

		reader.close();
		writer.close();
	}

	public static void main(String[] args) throws IOException {
		new Reflections(System.in, System.out).run();
	}

	private BufferedReader reader;
	private PrintWriter writer;
	private StringTokenizer tokenizer;

	public Reflections(InputStream in, OutputStream out) {
		this.reader = new BufferedReader(new InputStreamReader(in));
		this.writer = new PrintWriter(new OutputStreamWriter(out));
	}

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

	private float nextFloat() throws IOException {
		return Float.parseFloat(nextToken());
	}

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


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Reflections {

	private int[] memo;

	private int reflect(int x) {
		if(x == 0) {
			return 0;
		}
		if(memo[x] != -1) {
			return memo[x];
		}

		int r = 10 * reflect(x / 10) + 9 - (x % 10);
		memo[x] = r;
		return r;
	}

	public void run() throws IOException {
		int l = nextInt();
		int r = nextInt();

		memo = new int[r + 1];
		Arrays.fill(memo, -1);

		long max = 0;

		for(; l <= r; ++l) {
			max = Math.max(max, (long)l * reflect(l));
		}
		writer.print(max);

		reader.close();
		writer.close();
	}

	public static void main(String[] args) throws IOException {
		new Reflections(System.in, System.out).run();
	}

	private BufferedReader reader;
	private PrintWriter writer;
	private StringTokenizer tokenizer;

	public Reflections(InputStream in, OutputStream out) {
		this.reader = new BufferedReader(new InputStreamReader(in));
		this.writer = new PrintWriter(new OutputStreamWriter(out));
	}

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

	private float nextFloat() throws IOException {
		return Float.parseFloat(nextToken());
	}

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


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

public class cf553B {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in=new Scanner(System.in);
		long values[]=new long[100005];
		int n=in.nextInt();
		int number[]=new int[n+1];
		for(int j=1;j<=n;j++) {
			number[j]=j;
		}
		long k=in.nextLong();
		values[0]=1;
		values[1]=2;
		values[2]=3;
		int up=0,low=1;

		for(int i=3;;i++) {
			values[i]=values[i-1]+values[i-2];
			if(values[i]>k) { up=i; break; }
		}
		int pos=up;

		while(k>1) {
			 pos=binarysearch(values,pos,low,k);
			 int temp=number[pos];
			 number[pos]=number[pos+1];
			 number[pos+1]=temp;
			 k=k-values[pos-1];
			 //System.out.println(pos);
		}

		for(int i=1;i<=n;i++)
			System.out.print(number[i]+" ");

	}

	public static int binarysearch(long arr[],int up,int low,long val )
	{
		int mid;
		while(true) {
			mid=(up+low)/2;
			// Equals to condition
			if(arr[mid]>=val && arr[mid-1]<val) return mid;

			//Greater condition
			else if(arr[mid]>val ) up=mid-1;

			//Lesser codition
			else if(arr[mid]<val) low=mid+1;
			//System.out.println("mid="+mid+" val="+val);

		}

	}

}