import static java.lang.Double.parseDouble;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.Math.abs;
import static java.lang.System.exit;

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

public class C {

	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer tok;

//	static final int DX[] = {1, 0, -1, 0};
//	static final int DY[] = {0, 1, 0, -1};
//
//	static boolean solveFirst(boolean glue[][], int x1, int y1, int x2, int y2) {
//		if (x1 == x2 && y1 == y2) {
//			return true;
//		}
//		if (!glue[x1][y1]) {
//			for (int d = 0; d < 4; d++) {
//				int nx1 = x1 + DX[d];
//				int ny1 = y1 + DY[d];
//				if (nx1 < 0 || nx1 >= glue.length || ny1 < 0 || ny1 >= glue[0].length) {
//					continue;
//				}
//				if (solveSecond(glue, nx1, ny1, x2, y2)) {
//					return true;
//				}
//			}
//		}
//		if (!glue[x2][y2]) {
//			for (int d = 0; d < 4; d++) {
//				int nx2 = x2 + DX[d];
//				int ny2 = y2 + DY[d];
//				if (nx2 < 0 || nx2 >= glue.length || ny2 < 0 || ny2 >= glue[0].length) {
//					continue;
//				}
//				if (solveSecond(glue, x1, y1, nx2, ny2)) {
//					return true;
//				}
//			}
//		}
//		return false;
//	}
//
//	static boolean solveSecond(boolean glue[][], int x1, int y1, int x2, int y2) {
//		for (int x = 0; x < glue.length; x++) {
//			for (int y = 0; y < glue[0].length; y++) {
//				if (!(x == x1 && y == y1) && !(x == x2 && y == y2) && !glue[x][y]) {
//					glue[x][y] = true;
//					boolean res = solveFirst(glue, x1, y1, x2, y2);
//					glue[x][y] = false;
//					if (!res) {
//						return false;
//					}
//				}
//			}
//		}
//		return true;
//	}

	static void solve() throws Exception {
		/*int n = */nextInt();
		/*int m = */nextInt();
		int x1 = nextInt() - 1;
		int y1 = nextInt() - 1;
		int x2 = nextInt() - 1;
		int y2 = nextInt() - 1;
		// dx > 4 || dy > 4 -> Second
		// dx + dy <= 4 -> First
		// dx == 4 && dy == 1 -> First
		// dx == 4 && dy == 4 -> Second
		if (abs(x1 - x2) > 4 || abs(y1 - y2) > 4) {
			out.println("Second");
			return;
		}
		if (abs(x1 - x2) == 4 && abs(y1 - y2) == 4) {
			out.println("Second");
			return;
		}
		out.println("First");
//		int xMin = min(x1, x2);
//		int xMax = max(x1, x2);
//		int yMin = min(y1, y2);
//		int yMax = max(y1, y2);
//		n = xMax - xMin + 1;
//		x1 -= xMin;
//		x2 -= xMin;
//		m = yMax - yMin + 1;
//		y1 -= yMin;
//		y2 -= yMin;
//		boolean glue[][] = new boolean[n][m];
//		out.println(solveFirst(glue, x1, y1, x2, y2) ? "First" : "Second");
	}

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

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

	static double nextDouble() throws IOException {
		return parseDouble(next());
	}

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

	public static void main(String[] args) {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
			solve();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			exit(1);
		}
	}
}


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

public class Main {

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

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

	private void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		in.close();
		out.close();
	}
	private void solve() throws IOException{
		nextInt();
		nextInt();
		int x1 = nextInt();
		int y1 = nextInt();

		int x2 = nextInt();
		int y2 = nextInt();

		int kek = max(abs(x1 - x2), abs(y1 - y2));
		if(min(abs(x1 - x2), abs(y1 - y2)) == kek) kek++;
		out.println(kek > 4 ? "Second" : "First");

	}
	String nextToken() throws IOException {
		while (!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}
	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}
	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}
	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}
	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}
}


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

public class Main {
	static Scanner in; static int next() throws Exception {return in.nextInt();}
	static PrintWriter out;
//	static StreamTokenizer in; static int next() throws Exception {in.nextToken(); return (int) in.nval;}
//	static BufferedReader in;

	static int n;
	static int mod = 1000000007;

	static int[] pow(int[] x, int deg) {
		if (deg == 0) {
			int[] rez = new int[n];
			rez[0] = 1;
			return rez;
		}
		if (deg == 1) return x;

		int p = deg/2;

		int[] y = pow(x, p);
		int[] z = new int[n];
		for (int i = 0; i < n; i++) {
			long rez = 0;
			for (int j = 0; j <= i; j++) rez += ((long)y[j] * y[i - j]) % mod;
			for (int j = i + 1; j < n; j++) rez += ((long)y[j] * y[i - j + n]) % mod;
			z[i] = (int)(rez % mod);
		}

		if (deg % 2 == 1) {
			long sum = 0;
			for (int i = 0; i < n; i++) sum += z[i];
			int[] t = new int[n];
			for (int i = 0; i < n; i++) t[i] = (int)((sum - z[i]) % mod);
			return t;
		}
		return z;
	}

	public static void main(String[] args) throws Exception {
		in = new Scanner(System.in);
//		in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		char[] c = in.nextLine().toCharArray();
		char[] d = in.nextLine().toCharArray();

		int k = next();

		n = c.length;

		boolean[] match = new boolean[n];
		Arrays.fill(match, true);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++) match[(i - j + n) % n] &= (c[i] == d[j]);

		int[] one = new int[n];
		Arrays.fill(one, 1);
		one[0] = 0;

		int[] res = pow(one, k);

		long sum = 0;
		for (int i = 0; i < n; i++) if (match[i]) sum += res[i];

		out.println(sum % mod);

		out.close();
	}
}


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

public class B_mask_fast {

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

	int[][] a;
	int n, m, k;

	int[] leftOcc;

	static final int MOD = 1_000_000_007;

	int go(int x, int y, int used) {

		if (x == n) {
			int res = 1;
			for (int i = 0; i < used - initSet; i++)
				res *= (k - initSet - i);
//			System.err.println(Arrays.deepToString(a));
			return res;
		}

		int nextX = x;
		int nextY = y + 1;
		if (nextY == m) {
			nextY = 0;
			nextX++;
		}

		if (a[x][y] != -1) {

			int prev = leftOcc[a[x][y]];
			if (leftOcc[a[x][y]] <= y)
				return 0;

			leftOcc[a[x][y]] = y;

			int ret = go(nextX, nextY, used);
			leftOcc[a[x][y]] = prev;
			return ret;
		}

		int ret = 0;

		for (int put = 0; put <= used && put < k; put++) {
			int prev = leftOcc[put];
			if (prev > y) {
				leftOcc[put] = y;
				a[x][y] = put;
				ret += go(nextX, nextY, used + (put == used ? 1 : 0));
				if (ret >= MOD)
					ret -= MOD;
				leftOcc[put] = prev;
			}
		}
		a[x][y] = -1;
		return ret;
	}

	int initSet;

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

		if (n + m - 1 > k) {
			out.println(0);
			return;
		}

		TreeSet<Integer> set = new TreeSet<>();

		a = new int[n][m];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				a[i][j] = nextInt() - 1;
				if (a[i][j] != -1)
					set.add(a[i][j]);
			}

		List<Integer> field = new ArrayList<>(set);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				if (a[i][j] != -1)
					a[i][j] = Collections.binarySearch(field, a[i][j]);
			}
		initSet = field.size();

		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				for (int i1 = i; i1 < n; i1++)
					for (int j1 = j; j1 < m; j1++) {
						if (i1 != i && j1 != j && a[i][j] != -1
								&& a[i][j] == a[i1][j1]) {
							out.println(0);
							return;
						}
					}

		leftOcc = new int[k];
		Arrays.fill(leftOcc, m);
		out.println(go(0, 0, initSet));

	}

	B_mask_fast() 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 B_mask_fast();
	}

	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.io.*;
import java.util.*;

public class B_mask {

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

	int[][] a;
	int n, m, k;

	int[][] bad;

	boolean test(int mask, int i) {
		return ((mask >> i) & 1) == 1;
	}

	static final int MOD = 1_000_000_007;

	int go(int x, int y, int used) {

		if (x == n) {
			int res = 1;
			for (int i = 0; i < used - initSet; i++)
				res *= (k - initSet - i);
//			System.err.println(Arrays.deepToString(a));
			return res;
		}

		int curBad = 0;
		curBad = 0;
		if (x != 0) {
			curBad |= bad[x - 1][y];
			curBad |= (1 << a[x - 1][y]);
		}

		if (y != 0) {
			curBad |= bad[x][y - 1];
			curBad |= (1 << a[x][y - 1]);
		}

		bad[x][y] = curBad;

		int nextX = x;
		int nextY = y + 1;
		if (nextY == m) {
			nextY = 0;
			nextX++;
		}

		if (a[x][y] != -1) {
			if (test(curBad, a[x][y]))
				return 0;

			int ret = go(nextX, nextY, used);
			return ret;
		}

		int ret = 0;

		for (int put = 0; put <= used && put < k; put++)
			if (!test(curBad, put)) {
				a[x][y] = put;
				ret += go(nextX, nextY, used + (put == used ? 1 : 0));
				if (ret >= MOD)
					ret -= MOD;
			}
		a[x][y] = -1;
		return ret;
	}

	int initSet;

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

		if (n + m - 1 > k) {
			out.println(0);
			return;
		}

		TreeSet<Integer> set = new TreeSet<>();

		a = new int[n][m];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				a[i][j] = nextInt() - 1;
				if (a[i][j] != -1)
					set.add(a[i][j]);
			}

		List<Integer> field = new ArrayList<>(set);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				if (a[i][j] != -1)
					a[i][j] = Collections.binarySearch(field, a[i][j]);
			}
		initSet = field.size();

		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				for (int i1 = i; i1 < n; i1++)
					for (int j1 = j; j1 < m; j1++) {
						if (i1 != i && j1 != j && a[i][j] != -1
								&& a[i][j] == a[i1][j1]) {
							out.println(0);
							return;
						}
					}

		bad = new int[n][m];
		out.println(go(0, 0, initSet));

	}

	B_mask() 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 B_mask();
	}

	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 static java.util.Arrays.deepToString;

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

public class B {
    static int n, m, k;
    static int MOD = 1000000007;
    static long ans;
    static int av;
    static int[] fact;

    static void go(int[][] b, int x, int y, int usedC, int newC) {
        if (y == n) {
            ans += fact[av] / fact[av - newC];
            return;
        }
        int nx = x + 1, ny = y;
        if (nx == m) {
            nx = 0;
            ny++;
        }
        int bad = 0;
        for (int row = 0; row < y; row++) {
            for (int col = 0; col <= x; col++) {
                bad |= 1 << (b[row][col]);
            }
        }
        for (int col = 0; col < x; col++) {
            bad |= 1 << (b[y][col]);
        }
        if (b[y][x] != 0) {
            if (((bad >> b[y][x]) & 1) == 0)
                go(b, nx, ny, usedC, newC);
            return;
        }
        boolean q = false;
        for (int take = 1; take <= k; take++) {
            if (((bad >> take) & 1) != 0)
                continue;
            if (((usedC >> take) & 1) != 0) {
                b[y][x] = take;
                go(b, nx, ny, usedC, newC);
                b[y][x] = 0;
            } else if (!q) {
                b[y][x] = take;
                go(b, nx, ny, usedC | (1 << take), newC + 1);
                b[y][x] = 0;
                q = true;
            }
        }
    }

    static void solve() {
        n = nextInt();
        m = nextInt();
        k = nextInt();
        int[][] b = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                b[i][j] = nextInt();
            }
        }
        solve(b, k);
        writer.println(ans % MOD);
    }

    static void solve(int[][] b, int _k) {
        n = b.length;
        m = b[0].length;
        k = _k;
        ans = 0;
        if (n + m - 1 > k) {
            return;
        }
        int usedC = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (b[i][j] > 0) {
                    usedC |= 1 << b[i][j];
                }
            }
        }
        av = k - Integer.bitCount(usedC);
        go(b, 0, 0, usedC, 0);
    }

    static void test() {
        for (int n = 1; n <= 10; n++) {
            for (int m = 1; m <= 10; m++) {
                solve(new int[n][m], 10);
                debug(n, m, ans);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        reader = new BufferedReader(new InputStreamReader(System.in));
        writer = new PrintWriter(System.out);

        fact = new int[11];
        fact[0] = 1;
        for (int i = 1; i < fact.length; i++) {
            fact[i] = fact[i - 1] * i;
        }

        // test();

        setTime();
        solve();
        printTime();
        printMemory();

        writer.close();
    }

    static BufferedReader reader;
    static PrintWriter writer;
    static StringTokenizer tok = new StringTokenizer("");
    static long systemTime;

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

    static void setTime() {
        systemTime = System.currentTimeMillis();
    }

    static void printTime() {
        System.err.println("Time consumed: " + (System.currentTimeMillis() - systemTime));
    }

    static void printMemory() {
        System.err.println("Memory consumed: "
                + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1000 + "kb");
    }

    static String next() {
        while (!tok.hasMoreTokens()) {
            String w = null;
            try {
                w = reader.readLine();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (w == null)
                return null;
            tok = new StringTokenizer(w);
        }
        return tok.nextToken();
    }

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

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

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

    static BigInteger nextBigInteger() {
        return new BigInteger(next());
    }
}


/* Codeforces Template */

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

import static java.lang.Math.*;
import static java.util.Arrays.fill;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.sort;

public class Main {

	static long initTime;
	static final Random rnd = new Random(7777L);
	static boolean writeLog = false;

	public static void main(String[] args) throws IOException {
		initTime = System.currentTimeMillis();
		try {
			writeLog = "true".equals(System.getProperty("LOCAL_RUN_7777"));
		} catch (SecurityException e) {}
		new Thread(null, new Runnable() {
			public void run() {
				try {
					try {
						if (new File("input.txt").exists())
							System.setIn(new FileInputStream("input.txt"));
					} catch (SecurityException e) {}
					long prevTime = System.currentTimeMillis();
					new Main().run();
					log("Total time: " + (System.currentTimeMillis() - prevTime) + " ms");
					log("Memory status: " + memoryStatus());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, "1", 1L << 24).start();
	}

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

	/***************************************************************
	 * Solution
	 **************************************************************/

	final int MOD = 1000000007;
	int answer = 0;

	int N;
	int M;
	int K;
	int[][] mat;

	int[] mapColor;
	int[] mapCount;

	int[][][] can;

	int[][] A;

	int[][] tmp;

	int mapped = 0;

	void solve() throws IOException  {

		A = new int [20][20];

		for (int n = 0; n < A.length; n++) {
			for (int k = 0; k <= n; k++) {
				A[n][k] = A(n, k);
			}
		}

		N = nextInt();
		M = nextInt();
		K = nextInt();

		mat = new int [N][M];
		tmp = new int [N][M];

		for (int i = 0; i < N; i++)
			for (int j = 0; j < M; j++)
				mat[i][j] = nextInt();

		if (N + M - 1 > K) {
			out.println(0);
			return;
		}

		mapColor = new int [K + 1];
		mapCount = new int [K + 1];

		can = new int [N][M][K];

		int kk = 0;

		for (int i = 0; i < N; i++) {
			if (!color(i, 0, kk++)) {
				out.println(0);
				return;
			}
		}

		for (int j = 1; j < M; j++) {
			if (!color(N - 1, j, kk++)) {
				out.println(0);
				return;
			}
		}

		rec(N - 2, 1, kk);
		out.println(answer);
	}

	int A(int n, int k) {
		int ret = 1;
		for (int i = (n - k + 1); i <= n; i++)
			ret *= i;
		return ret % MOD;
	}

	void rec(int r, int c, int usedColors) {
		if (r < 0 || c >= M) {
			update(usedColors);
			return;
		}

		int nr = r;
		int nc = c + 1;

		if (nc >= M) {
			nr--;
			nc = 1;
		}

		int maxColor = min(K - 1, usedColors);

		for (int col = 0; col <= maxColor; col++) {
			if (color(r, c, col)) {
				rec(nr, nc, max(col + 1, usedColors));
				uncolor(r, c, col);
			}
		}
	}

	void update(int usedColors) {

//		System.err.println(usedColors);
//		for (int i = 0; i < N; i++)
//			System.err.println(Arrays.toString(tmp[i]));

		answer += A[K - mapped][usedColors - mapped];
		while (answer >= MOD)
			answer -= MOD;
	}

	boolean color(int i, int j, int c) {

		if (can[i][j][c] > 0)
			return false;

		int old = mat[i][j];

		boolean ret = false;

		if (old == 0) {
			ret = true;
		} else if (mapCount[old] == 0 || mapColor[old] == c) {
			mapColor[old] = c;
			if (mapCount[old] == 0)
				mapped++;
			mapCount[old]++;
			ret = true;
		}

		if (ret) {
			tmp[i][j] = c;
			for (int k = 0; k <= i; k++)
				for (int l = 0; l <= j; l++)
					can[k][l][c]++;
			for (int k = i; k < N; k++)
				for (int l = j; l < M; l++)
					can[k][l][c]++;
		}

		return ret;
	}

	void uncolor(int i, int j, int c) {

		int old = mat[i][j];
		if (mapCount[old] > 0) {
			mapCount[old]--;
			if (mapCount[old] == 0)
				mapped--;
		}

		for (int k = 0; k <= i; k++)
			for (int l = 0; l <= j; l++)
				can[k][l][c]--;

		for (int k = i; k < N; k++)
			for (int l = j; l < M; l++)
				can[k][l][c]--;
	}

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

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

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

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

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

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

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

	double[] nextDoubleArray(int size) throws IOException {
		double[] ret = new double [size];
		for (int i = 0; i < size; i++)
			ret[i] = nextDouble();
		return ret;
	}

	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}

	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}

	/***************************************************************
	 * Output
	 **************************************************************/
	void printRepeat(String s, int count) {
		for (int i = 0; i < count; i++)
			out.print(s);
	}

	void printArray(int[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(long[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(double[] array) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(double[] array, String spec) {
		if (array == null || array.length == 0)
			return;
		for (int i = 0; i < array.length; i++) {
			if (i > 0) out.print(' ');
			out.printf(Locale.US, spec, array[i]);
		}
		out.println();
	}

	void printArray(Object[] array) {
		if (array == null || array.length == 0)
			return;
		boolean blank = false;
		for (Object x : array) {
			if (blank) out.print(' '); else blank = true;
			out.print(x);
		}
		out.println();
	}

	@SuppressWarnings("rawtypes")
	void printCollection(Collection collection) {
		if (collection == null || collection.isEmpty())
			return;
		boolean blank = false;
		for (Object x : collection) {
			if (blank) out.print(' '); else blank = true;
			out.print(x);
		}
		out.println();
	}

	/***************************************************************
	 * Utility
	 **************************************************************/
	static String memoryStatus() {
		return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() >> 20) + "/" + (Runtime.getRuntime().totalMemory() >> 20) + " MB";
	}

	static void checkMemory() {
		System.err.println(memoryStatus());
	}

	static long prevTimeStamp = Long.MIN_VALUE;

	static void updateTimer() {
		prevTimeStamp = System.currentTimeMillis();
	}

	static long elapsedTime() {
		return (System.currentTimeMillis() - prevTimeStamp);
	}

	static void checkTimer() {
		System.err.println(elapsedTime() + " ms");
	}

	static void chk(boolean f) {
		if (!f) throw new RuntimeException("Assert failed");
	}

	static void chk(boolean f, String format, Object ... args) {
		if (!f) throw new RuntimeException(String.format(format, args));
	}

	static void log(String format, Object ... args) {
		if (writeLog) System.err.println(String.format(Locale.US, format, args));
	}
}


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

import static java.lang.Math.*;

public class Solution implements Runnable {

    class Lemming implements Comparable<Lemming> {
        long m;
        long v;
        int index;

        public Lemming() {

        }

        public Lemming(long m, long v, int index) {
            this.m = m;
            this.v = v;
            this.index = index;
        }

        public int compareTo(Lemming arg0) {
            if (m == arg0.m) {
                if (v > arg0.v)
                    return 1;
                else if (v < arg0.v)
                    return -1;
                else
                    return 0;
            } else {
                if (m > arg0.m)
                    return 1;
                else
                    return -1;
            }
        }
    }

    long h;
    int ans[];
    int n, k;
    ArrayList<Lemming> lemmings = new ArrayList<>();
    final double EPS = 1e-9;

    boolean isAnswer(double t) {
        int a[] = new int[k];
        boolean win;
        int j = 1;

        for (int i = 0;i < n; ++ i) {
            double tt = (j * h + 0.0) / (lemmings.get(i).v + 0.0);
            if (t - tt > EPS) {
                a[j - 1] = lemmings.get(i).index;
                ++ j;
            }
            if (j - 1 == k) {
                break;
            }
        }

        win = (j - 1 == k);

        if (win) {
            for (int i = 0;i < k; ++ i) {
                ans[i] = a[i];
            }
        }

        return win;
    }

    public void solve() throws Exception {
        n = sc.nextInt();
        k = sc.nextInt();
        h = sc.nextLong();

        long m[] = new long[n];
        long v[] = new long[n];
        ans = new int[k];

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

        for (int i = 0;i < n; ++ i) {
            v[i] = sc.nextLong();
        }

        for (int i = 0;i < n; ++ i) {
            lemmings.add(new Lemming(m[i], v[i], i + 1));
        }
        Collections.sort(lemmings);
        double l = 0.0;
        double r = 10000000000.0;
        for (int i = 0;i < 100; ++ i) {
            double t = (l + r) / 2.0;
            if (isAnswer(t)) {
                r = t;
            } else {
                l = t;
            }
        }

        for (int i = 0;i < k; ++ i) {
            out.print(ans[i] + " ");
        }
    }

    /*--------------------------------------------------------------*/

    static String filename = "";
    static boolean fromFile = false;

    BufferedReader in;
    PrintWriter out;
    FastScanner sc;

    public static void main(String[] args) {
        new Thread(null, new Solution(), "", 1 << 25).start();
    }

    public void run() {
        try {
            init();
            solve();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            out.close();
        }
    }

    void init() throws Exception {
        if (fromFile) {
            in = new BufferedReader(new FileReader(filename+".in"));
            out = new PrintWriter(new FileWriter(filename+".out"));
        } else {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        }
        sc = new FastScanner(in);
    }
}

class FastScanner {

    BufferedReader reader;
    StringTokenizer strTok;

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

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

        return strTok.nextToken();
    }

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

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

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

    public BigInteger nextBigInteger() throws IOException {
        return new BigInteger(nextToken());
    }

    public BigDecimal nextBigDecimal() throws IOException {
        return new BigDecimal(nextToken());
    }
}


import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: Михаил
 * Date: 25.03.12
 * Time: 19:35
 * To change this template use File | Settings | File Templates.
 */
public class FourProblem {
    static class Leming implements Comparable<Leming> {
        private int v;
        private int m;
        private int num;
        public Leming(int m, int v, int num) {
            this.m = m;
            this.v = v;
            this.num = num;
        }
        public int compareTo(Leming leming) {
            if (m == leming.m) {
                return v - leming.v;
            }
            return m - leming.m;
        }
    }
    private static Leming [] lemings;
    private static final double EPS = 0.000000000000000001;
    private static boolean isCan(double time, int k, int high) {
        for (int i = lemings.length - 1; i > -1; i--) {
            double timeLeming = k * high / (double)lemings[i].v;
            if ((timeLeming <= time) || (Math.abs(timeLeming - time) < EPS)) {
                k--;
                if (k == 0) {
                    return true;
                }
            }
        }
        return false;
    }
    public static void main(String [] args) {
        Scanner scanner = new Scanner(System.in);
        int lemingCount = scanner.nextInt();
        int ustupCount = scanner.nextInt();
        int ustupHigh = scanner.nextInt();
        int [] m = new int[lemingCount];
        for (int i = 0; i < lemingCount; i++) {
            m[i] = scanner.nextInt();
        }
        lemings = new Leming[lemingCount];
        for (int i = 0; i < lemingCount; i++) {
            int v = scanner.nextInt();
            lemings[i] = new Leming(m[i], v, i + 1);
        }
        Arrays.sort(lemings);
        double rigth = 2000000000;
        double left = 0;
        int countCC = 0;
        while (Math.abs(rigth - left) > EPS) {
            countCC++;
            double time = (rigth + left) / 2;
            if (isCan(time, ustupCount, ustupHigh)) {
                rigth = time;
            } else {
                left = time;
            }
            if (countCC == 500) {
                break;
            }
        }

        LinkedList<Integer> answerList = new LinkedList<Integer>();
        if (isCan(left, ustupCount, ustupHigh))
        {
            int k = ustupCount;
            for (int i = lemings.length - 1; i > -1; i--) {
                double timeLeming = k * ustupHigh / (double)lemings[i].v;
                if ((timeLeming <= left) || (Math.abs(timeLeming - left) < EPS)) {
                    k--;

                    answerList.addFirst(lemings[i].num);
                    if (k == 0) {
                        for (int lemingNum : answerList) {
                            System.out.print(lemingNum + " ");
                        }
                        return;
                    }
                }
            }
        }
        int k = ustupCount;
        for (int i = lemings.length - 1; i > -1; i--) {
            double timeLeming = k * ustupHigh / (double)lemings[i].v;
            if ((timeLeming <= rigth) || (Math.abs(timeLeming - rigth) < EPS)) {
                k--;
                answerList.addFirst(lemings[i].num);
                if (k == 0) {
                    for (int lemingNum : answerList) {
                        System.out.print(lemingNum + " ");
                    }
                    return;
                }
            }
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;

public class R2_D2_D

{
    static double epsilon = 1e-9;

    public static void main(String[] args) throws IOException {
        InputReader in = new InputReader(System.in);
        int n = in.readInt();
        int k = in.readInt();
        int h = in.readInt();
        int[] hs = new int[k];
        for (int i = 0; i < hs.length; i++) {
            hs[i] = (i + 1) * h;
        }
        p[] all = new p[n];
        for (int i = 0; i < n; i++) {
            all[i] = new p(in.readInt(), 0);
            all[i].id = i + 1;
        }
        for (int i = 0; i < n; i++) {
            all[i].v = in.readInt();
        }
        Arrays.sort(all);
        double lo = 0;
        double hi = 1e9;
        ArrayList<Integer> out = new ArrayList<Integer>();
        ArrayList<Integer> res = new ArrayList<Integer>();
        int m = 0;
        double result = 0;
        while (m < 100) {
            out = new ArrayList<Integer>();
            m++;
            double t = (hi + lo) / 2;
            int limit = 0;
            boolean flag1 = true;
            for (int i = k - 1; i >= 0; i--) {
                double v = hs[i] / t;
                boolean flag = false;
                for (int j = limit; j < n; j++) {
                    if (all[j].v >= v) {
                        limit = j + 1;
                        out.add(all[j].id);
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    flag1 = false;
                    break;
                }
            }
            if (flag1) {
                result = t;
                res = out;
                hi = t;
            } else {
                lo = t;
            }
        }
        System.out.println(res.get(res.size()-1));
        for (int i = res.size() - 2; i >= 0; i--)
            System.out.print(" "+res.get(i));
    }

    static class p implements Comparable<p> {
        int w;
        int v;
        int id;

        public p(int a, int b) {
            w = a;
            v = b;
        }

        public int compareTo(p o) {
            if (w < o.w)
                return 1;
            if (w > o.w)
                return -1;
            return o.v - v;
        }

    }

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

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

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

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

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

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

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

        private String readLine0() {
            StringBuffer buf = new StringBuffer();
            int c = read();
            while (c != '\n' && c != -1) {
                buf.appendCodePoint(c);
                c = read();
            }
            return buf.toString();
        }

        public String readLine() {
            String s = readLine0();
            while (s.trim().length() == 0)
                s = readLine0();
            return s;
        }

        public String readLine(boolean ignoreEmptyLines) {
            if (ignoreEmptyLines)
                return readLine();
            else
                return readLine0();
        }

        public char readCharacter() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            return (char) c;
        }

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

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;

public class R2_D2_D

{
    static double epsilon = 1e-9;

    public static void main(String[] args) throws IOException {
        InputReader in = new InputReader(System.in);
        int n = in.readInt();
        int k = in.readInt();
        int h = in.readInt();
        int[] hs = new int[k];
        for (int i = 0; i < hs.length; i++) {
            hs[i] = (i + 1) * h;
        }
        p[] all = new p[n];
        for (int i = 0; i < n; i++) {
            all[i] = new p(in.readInt(), 0);
            all[i].id = i + 1;
        }
        for (int i = 0; i < n; i++) {
            all[i].v = in.readInt();
        }
        Arrays.sort(all);
        double lo = 0;
        double hi = 1000000000;
        ArrayList<Integer> out = new ArrayList<Integer>();
        ArrayList<Integer> res = new ArrayList<Integer>();
        int m = 0;
        double result = 0;
        while (m < 100) {
            out = new ArrayList<Integer>();
            m++;
            double t = (hi + lo) / 2;
            int limit = 0;
            boolean flag1 = true;
            for (int i = k - 1; i >= 0; i--) {
                double v = hs[i] / t;
                boolean flag = false;
                for (int j = limit; j < n; j++) {
                    if (all[j].v - v > epsilon) {
                        limit = j + 1;
                        out.add(all[j].id);
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    flag1 = false;
                    break;
                }
            }
            if (flag1) {
                result = t;
                res = out;
                hi = t;
            } else {
                lo = t;
            }
        }
        System.out.println(res.get(res.size()-1));
        for (int i = res.size() - 2; i >= 0; i--)
            System.out.print(" "+res.get(i));
    }

    static class p implements Comparable<p> {
        int w;
        int v;
        int id;

        public p(int a, int b) {
            w = a;
            v = b;
        }

        public int compareTo(p o) {
            if (w < o.w)
                return 1;
            if (w > o.w)
                return -1;
            return o.v - v;
        }

    }

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

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

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

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

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

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

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

        private String readLine0() {
            StringBuffer buf = new StringBuffer();
            int c = read();
            while (c != '\n' && c != -1) {
                buf.appendCodePoint(c);
                c = read();
            }
            return buf.toString();
        }

        public String readLine() {
            String s = readLine0();
            while (s.trim().length() == 0)
                s = readLine0();
            return s;
        }

        public String readLine(boolean ignoreEmptyLines) {
            if (ignoreEmptyLines)
                return readLine();
            else
                return readLine0();
        }

        public char readCharacter() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            return (char) c;
        }

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

}


// program referenced from im_shubh7's solution
public class Euler {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        int w = sc.nextInt();
        int h = sc.nextInt();
        long res = 1;
        long div = 998244353;
        for(int i = 0; i<w+h; i++){
            res = ((2*res)+div)%div;
        }
        System.out.println(res);
    }
 }


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

public class practice {
	static class Reader
    {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader()
        {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException
        {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException
        {
            byte[] buf = new byte[100001]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1)
            {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException
        {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do
            {
                ret = ret * 10 + c - '0';
            }  while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException
        {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException
        {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.')
            {
                while ((c = read()) >= '0' && c <= '9')
                {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException
        {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException
        {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException
        {
            if (din == null)
                return;
            din.close();
        }
    }
	public static void debug(int[][] arr) {
		int r = arr.length;
		int c = arr[0].length;
		int i,j;
		for(i=0;i<r;++i) {
			for(j=0;j<c;++j)  System.err.print(arr[i][j]+" ");
			System.err.println();
		}
	}
	public static void debug(long[][] arr) {
		int r = arr.length;
		int c = arr[0].length;
		int i,j;
		for(i=0;i<r;++i) {
			for(j=0;j<c;++j)  System.err.print(arr[i][j]+" ");
			System.err.println();
		}
	}
	public static void debug(int ...var) {
		for(int i:var)  System.err.print(i+" ");
		System.err.println();
	}
	public static void debug(String ...var) {
		for(String i:var)  System.err.print(i+" ");
		System.err.println();
	}
	public static void debug(double ...var) {
		for(double i:var)  System.err.print(i+" ");
		System.err.println();
	}

	public static void debug(long ...var) {
		for(long i:var)  System.err.print(i+" ");
		System.err.println();
	}

    public static void main(String args[]) throws Exception{
        Reader scan = new Reader();
        //be careful of readLine() length of string;
        //Scanner scan = new Scanner(System.in);
		//scan.useDelimiter("");  // for reading character by character

        int r = scan.nextInt();
        int c = scan.nextInt();
        int mod = 998244353;
        long ans = 4;
        ans*=Math.pow(2,r+c-2);
        System.out.println(ans%MOD);
        scan.close();

    }
}


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

public class BINARY
{
      static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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

	public static int[] swap(int[] arr, int i, int j)
	{
		int k=arr[j];
		arr[j]=arr[i];
		arr[i]=k;
		return arr;

	}

	public static void main(String []args)
	{
		FastReader obj=new FastReader();
        int w= obj.nextInt();
        int h= obj.nextInt();
        int t = w+h-2;
        int out=4;
        for(int i=0;i<t;i++)
        {
            out*=2;
            out=%998244353;
        }

        {System.out.print(""+out);}

	}
}


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

public class BINARY
{
      static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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

	public static int[] swap(int[] arr, int i, int j)
	{
		int k=arr[j];
		arr[j]=arr[i];
		arr[i]=k;
		return arr;

	}

	public static void main(String []args)
	{
		FastReader obj=new FastReader();
        int w= obj.nextInt();
        int h= obj.nextInt();
        int t = w+h-2;
        int out=4;
        for(int i=0;i<t;i++)
        {
            out*=2;
            out=%998244353
        }

        {System.out.print(""+out);}

	}
}


//package codeforces.contests;

import t17.numbers.Numbers;

import java.io.*;
import java.util.InputMismatchException;
import java.util.Random;

/**
 * @author tainic on Mar 30, 2019
 */
public class D {

    private static boolean LOCAL;
    static {
        try { LOCAL = "aurel".equalsIgnoreCase(System.getenv().get("USER")); } catch (Exception e){}
    }

    private static final String TEST =
        "1 10\n" +
        "5 3";

    void solve(InputReader in, PrintWriter out) {
        long n = in.nextInt();
        long k = in.nextInt();
        long a = in.nextInt();
        long b = in.nextInt();
        long min = Integer.MAX_VALUE, max = -1;
        for (int t = 0; t < n; t++) {
            long L = (k * t + k + a + b) % (n * k);
            min = Math.min(min, n * k / Numbers.gcd(n * k, L));
            max = Math.max(max, n * k / Numbers.gcd(n * k, L));

            L = (k * t + k - a + b) % (n * k);
            min = Math.min(min, n * k / Numbers.gcd(n * k, L));
            max = Math.max(max, n * k / Numbers.gcd(n * k, L));

            L = (k * t + k - a + k - b) % (n * k);
            min = Math.min(min, n * k / Numbers.gcd(n * k, L));
            max = Math.max(max, n * k / Numbers.gcd(n * k, L));

            L = (k * t + k + a - b) % (n * k);
            min = Math.min(min, n * k / Numbers.gcd(n * k, L));
            max = Math.max(max, n * k / Numbers.gcd(n * k, L));
        }
        out.println(min + " " + max);
    }

    //region util
    static class Util {

        private static final Random R = new Random();

        public static void sort(int[] a) {
            sort(a, 0, a.length - 1);
        }

        private static void sort(int[] a, int from, int to) {
            if (from >= to) {
                return;
            }

            // partition
            int pivotIndex = R.nextInt(to - from + 1) + from;
            int pivot = a[pivotIndex];
            // maintain this invariant, at each step i:
            // a[j] <  pivot, for j = fromIndex to lt - 1
            // a[j] == pivot, for j = lt to i - 1
            // a[j] >  pivot, for j = gt + 1 to toIndex
            int lt = from;
            int gt = to;
            int i = lt;
            while (i <= gt) {
                int cmp = a[i] - pivot;
                if (cmp < 0) {
                    swap(a, i, lt);
                    i++;
                    lt++;
                } else if (cmp > 0) {
                    swap(a, i, gt);
                    gt--;
                } else {
                    i++;
                }
            }

            // sort left and right
            sort(a, from, lt - 1);
            sort(a, gt + 1, to);
        }

        public static int findFirst(int[] a, int key) {
            return findFirstOrLast(a, key, 0, a.length - 1, -1);
        }

        public static int findLast(int[] a, int key) {
            return findFirstOrLast(a, key, 0, a.length - 1, 1);
        }

        public static int findFirstOrLast(int[] a, int key, int fromIndex, int toIndex, int dir) {
            int left = fromIndex;
            int right = toIndex;
            while (left <= right) {
                int mid = (left + right) >>> 1;
                int cmp = key - a[mid];
                if (cmp > 0) {
                    left = mid + 1;
                } else if (cmp < 0) {
                    right = mid - 1;
                } else if (dir == -1 && mid > fromIndex && a[mid - 1] == key) {
                    right = mid - 1;
                } else if (dir == 1 && mid < toIndex && a[mid + 1] == key) {
                    left = mid + 1;
                } else {
                    return mid;
                }
            }
            return -left - 1;
        }

        public static void swap(int[] a, int i, int j) {
            if (i != j) {
                int ai = a[i];
                a[i] = a[j];
                a[j] = ai;
            }
        }

        public static int[] readInts(InputReader in, int k) {
            int[] a = new int[k];
            for (int i = 0; i < k; i++) {
                a[i] = in.nextInt();
            }
            return a;
        }

    }
    //endregion

    //region main
    public static void main(String[] args) throws Exception {
        long t = System.currentTimeMillis();

        try (
            InputReader in = new StreamInputReader(!LOCAL ? System.in : new ByteArrayInputStream(TEST.getBytes()));
            PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out, 2048), false)
        ) {
            new D().solve(in, out);
        }

        System.err.println("time: " + (System.currentTimeMillis() - t) + "ms");
    }
    //endregion

    //region fast io
    abstract static class InputReader implements AutoCloseable {

        public abstract int read();

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

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

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

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

    static class StreamInputReader extends InputReader {

        private InputStream stream;
        private byte[] buf;
        private int curChar, numChars;

        public StreamInputReader(InputStream stream) {
            this(stream, 2048);
        }

        public StreamInputReader(InputStream stream, int bufSize) {
            this.stream = stream;
            this.buf = new byte[bufSize];
        }

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

        @Override
        public void close() throws Exception {
            stream.close();
        }

    }
    //endregion

    //region imports
    //endregion

}


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

// **** D. The Beatles ****

public class D {
	static char [] in = new char [100000];
	public static void main (String [] arg) throws Throwable {
		long n = nextInt();
		long k = nextInt();
		long a = nextInt();
		long b = nextInt();
		long min = n*k;
		long max = 0;
		long [] values = new long [4];
		values[0] = ((b) + (a) + k) % k;
		values[1] = ((b) + k - (a) + k) % k;
		values[2] = (k - (b) + (a) + k) % k;
		values[3] = (k - (b) + k - (a) + k) % k;
		long nk = n*k;
		for (long v : values) {
			for (int m = (v == 0) ? 1 : 0; m <= n; ++m) {
				long tmpL = v + m*k;
				long ord = nk / gcd(nk, tmpL);
				min = Math.min(ord, min);
				max = Math.max(ord, max);
			}
		}
		System.out.println(min + " " + max);
	}

	/************** FAST IO CODE FOLLOWS *****************/
	public static long nextLong() throws Throwable {
		long i = System.in.read();boolean neg = false;while (i < 45) i = System.in.read();if (i == 45) {neg=true;i=48;}i = i - 48;
		int j = System.in.read();while (j > 32) {i*=10;i+=j-48;j = System.in.read();}return (neg) ? -i : i;
	}
	public static int nextInt() throws Throwable {return (int)nextLong();}
	public static String next() throws Throwable {
		int i = 0; while (i < 42 && i != -1) i = System.in.read(); int cptr = 0; while (i >= 42) { in[cptr++] = (char)i; i = System.in.read();}
		return new String(in, 0,cptr);
	}
	/**** LIBRARIES ****/
	public static long gcdL(long a, long b) {while (b != 0) {long tmp = b;b = (a % b);a = tmp;}return a;}
	public static int gcd(int a, int b) {while (b != 0) {int tmp = b;b = (a % b);a = tmp;}return a;}
	public static int[] sieve(int LIM) {
		int i,count = 0;
		boolean [] b = new boolean [LIM];
		for (i = 2;i<LIM; ++i) if (!b[i]) {count++; for (int j = i<<1; j<LIM; j+=i) b[j] = true;}
		int [] primes = new int[count];
		for (i = 2,count=0;i<LIM;++i) if (!b[i]) primes[count++] = i;
		return primes;
	}
	public static int[] numPrimeFactors(int LIM) {
		int i,count = 0;
		int [] b = new int [LIM];
		for (i = 2;i<LIM; ++i) if (b[i] == 0) {count++; for (int j = i; j<LIM; j+=i) b[j]++;}
		return b;
	}
}

/* Full Problem Text:

Recently a Golden Circle of Beetlovers was found in Byteland.
It is a circle route going through n \cdot k cities.
The cities are numerated from 1 to n \cdot k, the distance between the neighboring cities is exactly 1 km.
Sergey does not like beetles, he loves burgers.
Fortunately for him, there are n fast food restaurants on the circle, they are located in the 1-st, the (k + 1)-st, the (2k + 1)-st, and so on, the ((n-1)k + 1)-st cities, i.e. the distance between the neighboring cities with fast food restaurants is k km.
Sergey began his journey at some city s and traveled along the circle, making stops at cities each l km (l > 0),
until he stopped in s once again.
Sergey then forgot numbers s and l, but he remembers that the distance from the city s to the nearest fast food restaurant was a km, and the distance from the city he stopped at after traveling the first l km from s to the nearest fast food restaurant was b km.
Sergey always traveled in the same direction along the circle, but when he calculated distances to the restaurants, he considered both directions.
Now Sergey is interested in two integers.
The first integer x is the minimum number of stops (excluding the first) Sergey could have done before returning to s.
The second integer y is the maximum number of stops (excluding the first) Sergey could have done before returning to s.

 */


// package CF1143;

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

public class CF1143D {
    static FastReader s;
    static PrintWriter out;
    static String INPUT = "3 2\n" +
            "0 0\n";

    public static void main(String[] args) {
        long time = System.currentTimeMillis();
        boolean oj = System.getProperty("ONLINE_JUDGE") != null;
        out = new PrintWriter(System.out);
        s = new FastReader(oj);
        long n = s.nextLong();
        long k = s.nextLong();
        long a = s.nextLong();
        long b = s.nextLong();
        long[] start = new long[2];
        long[] end = new long[2];
        start[0] = 1 + a;
        start[1] = (k + 1 - a);
        end[0] = (1 + b);
        end[1] = (k + 1 - b);
        long min = Long.MAX_VALUE, max = Long.MIN_VALUE;
        for (int i = 0; i < 2; ++i) {
            for (int j = 0; j < 2; ++j) {
                long l = end[j] - start[i];
                if (l <= 0){
                    l += k;
                }
                for (long c = 0; c <= n; ++c) {
                    long now = l + c * k;
                    long gcd = Maths.gcd(now, n * k);
                    min = Math.min((n * k) / gcd, min);
                    max = Math.max((n * k) / gcd, max);
                }
            }
        }
        out.print(min + " " + max);

        out.println(ap1 + "\n" + ap2 + "\n" + ap3 + "\n" + ap4);
//        int firstTo = 1 + n - b;
//        int secondTo = 1 + n - (k - b);

        if (!oj) {
            System.out.println(Arrays.deepToString(new Object[]{System.currentTimeMillis() - time + " ms"}));
        }
        out.flush();
    }

    private static class AP{
        int start;
        int commonDiff;

        public AP(int start, int commonDiff) {
            this.start = start;
            this.commonDiff = commonDiff;
        }
    }

    private static class Matrix {

        static long[][] I;
        static long mod = 1000000007;

        public static long[][] exp(long[][] M, long n) {
            if (n <= 0) {
                I = new long[M.length][M.length];
                for (int i = 0; i < M.length; i++) {
                    I[i][i] = 1L;
                }
                return I;
            }
            if (n == 1) return M;
            long[][] res = exp(M, n / 2);
            res = mult(res, res);
            if (n % 2 == 0) return res;
            return mult(res, M);
        }

        public static long[][] mult(long[][] p, long[][] q) {
            long[][] r = new long[p.length][q[0].length];
            for (int i = 0; i < p.length; i++)
                for (int j = 0; j < q[0].length; j++)
                    for (int k = 0; k < q.length; k++) {
                        r[i][j] += p[i][k] * q[k][j];
                        r[i][j] %= mod;
                    }
            return r;
        }
    }

    private static class Maths {
        static ArrayList<Long> printDivisors(long n) {
            // Note that this loop runs till square root
            ArrayList<Long> list = new ArrayList<>();
            for (long i = 1; i <= Math.sqrt(n); i++) {
                if (n % i == 0) {
                    if (n / i == i) {
                        list.add(i);
                    } else {
                        list.add(i);
                        list.add(n / i);
                    }
                }
            }
            return list;
        }

        //    GCD - Using Euclid theorem.
        private static long gcd(long a, long b) {
            if (b == 0) {
                return a;
            }

            return gcd(b, a % b);
        }

        //    Extended euclidean algorithm
//    Used to solve equations of the form ax + by = gcd(a,b)
//    return array [d, a, b] such that d = gcd(p, q), ap + bq = d
        static long[] extendedEuclidean(long p, long q) {
            if (q == 0)
                return new long[]{p, 1, 0};

            long[] vals = extendedEuclidean(q, p % q);
            long d = vals[0];
            long a = vals[2];
            long b = vals[1] - (p / q) * vals[2];
            return new long[]{d, a, b};
        }

        // X ^ y mod p
        static long power(long x, long y, long p) {
            long res = 1;
            x = x % p;

            while (y > 0) {
                if ((y & 1) == 1)
                    res = (res * x) % p;
                y = y >> 1;
                x = (x * x) % p;
            }
            return res;
        }

        // Returns modulo inverse of a
        // with respect to m using extended
        // Euclid Algorithm. Refer below post for details:
        // https://www.geeksforgeeks.org/multiplicative-inverse-under-modulo-m/
        static long inv(long a, long m) {
            long m0 = m, t, q;
            long x0 = 0, x1 = 1;

            if (m == 1)
                return 0;

            // Apply extended Euclid Algorithm
            while (a > 1) {
                q = a / m;
                t = m;
                m = a % m;
                a = t;
                t = x0;
                x0 = x1 - q * x0;
                x1 = t;
            }

            // Make x1 positive
            if (x1 < 0)
                x1 += m0;

            return x1;
        }

        // k is size of num[] and rem[].
        // Returns the smallest number
        // x such that:
        // x % num[0] = rem[0],
        // x % num[1] = rem[1],
        // ..................
        // x % num[k-2] = rem[k-1]
        // Assumption: Numbers in num[] are pairwise
        // coprime (gcd for every pair is 1)
        static long findMinX(long num[], long rem[], long k) {
            int prod = 1;
            for (int i = 0; i < k; i++)
                prod *= num[i];

            int result = 0;
            for (int i = 0; i < k; i++) {
                long pp = prod / num[i];
                result += rem[i] * inv(pp, num[i]) * pp;
            }

            return result % prod;
        }
    }

    private static class BS {
        //  Binary search
        private static int binarySearch(int[] arr, int ele) {
            int low = 0;
            int high = arr.length - 1;
            while (low <= high) {
                int mid = (low + high) / 2;
                if (arr[mid] == ele) {
                    return mid;
                } else if (ele < arr[mid]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
            return -1;
        }

        //    First occurence using binary search
        private static int binarySearchFirstOccurence(int[] arr, int ele) {
            int low = 0;
            int high = arr.length - 1;
            int ans = -1;
            while (low <= high) {
                int mid = (low + high) / 2;
                if (arr[mid] == ele) {
                    ans = mid;
                    high = mid - 1;
                } else if (ele < arr[mid]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
            return ans;
        }

        //    Last occurenece using binary search
        private static int binarySearchLastOccurence(int[] arr, int ele) {
            int low = 0;
            int high = arr.length - 1;
            int ans = -1;
            while (low <= high) {
                int mid = (low + high) / 2;
                if (arr[mid] == ele) {
                    ans = mid;
                    low = mid + 1;
                } else if (ele < arr[mid]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
            return ans;
        }
    }

    private static class arrays {
        // Merge sort
        static void merge(int arr[], int l, int m, int r) {
            int n1 = m - l + 1;
            int n2 = r - m;
            int L[] = new int[n1];
            int R[] = new int[n2];
            for (int i = 0; i < n1; ++i)
                L[i] = arr[l + i];
            for (int j = 0; j < n2; ++j)
                R[j] = arr[m + 1 + j];
            int i = 0, j = 0;
            int k = l;
            while (i < n1 && j < n2) {
                if (L[i] <= R[j]) {
                    arr[k] = L[i];
                    i++;
                } else {
                    arr[k] = R[j];
                    j++;
                }
                k++;
            }

            while (i < n1) {
                arr[k] = L[i];
                i++;
                k++;
            }

            while (j < n2) {
                arr[k] = R[j];
                j++;
                k++;
            }
        }

        static void sort(int arr[], int l, int r) {
            if (l < r) {
                int m = (l + r) / 2;
                sort(arr, l, m);
                sort(arr, m + 1, r);
                merge(arr, l, m, r);
            }
        }

        static void sort(int[] arr) {
            sort(arr, 0, arr.length - 1);
        }
    }

    private static class UnionFindDisjointSet {
        int[] parent;
        int[] size;
        int n;
        int size1;

        public UnionFindDisjointSet(int n) {
            this.n = n;
            this.parent = new int[n];
            this.size = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
            }

            for (int i = 0; i < n; i++) {
                size[i] = 1;
            }

            this.size1 = n;
        }

        private int numDisjointSets() {
            System.out.println(size1);
            return size1;
        }

        private boolean find(int a, int b) {
            int rootA = root(a);
            int rootB = root(b);
            if (rootA == rootB) {
                return true;
            }
            return false;
        }

        private int root(int b) {
            if (parent[b] != b) {
                return parent[b] = root(parent[b]);
            }
            return b;
        }

        private void union(int a, int b) {
            int rootA = root(a);
            int rootB = root(b);
            if (rootA == rootB) {
                return;
            }

            if (size[rootA] < size[rootB]) {
                parent[rootA] = parent[rootB];
                size[rootB] += size[rootA];
            } else {
                parent[rootB] = parent[rootA];
                size[rootA] += size[rootB];
            }
            size1--;
            System.out.println(Arrays.toString(parent));
        }
    }

    private static class SegTree {
        int[] st;
        int[] arr;

        public SegTree(int[] arr) {
            this.arr = arr;
            int size = (int) Math.ceil(Math.log(arr.length) / Math.log(2));
            st = new int[(int) ((2 * Math.pow(2, size)) - 1)];
            buildSegmentTree(1, 0, arr.length - 1);
        }

        //**********JUST CALL THE CONSTRUCTOR, THIS FUNCTION WILL BE CALLED AUTOMATICALLY******
        private void buildSegmentTree(int index, int L, int R) {
            if (L == R) {
                st[index] = arr[L];
                return;
            }

            buildSegmentTree(index * 2, L, (L + R) / 2);
            buildSegmentTree(index * 2 + 1, (L + R) / 2 + 1, R);
//          Replace this line if you want to change the function of the Segment tree.
            st[index] = Math.min(st[index * 2], st[index * 2 + 1]);
        }

        //***********We have to use this function **************
        private int Query(int queL, int queR) {
            return Query1(1, 0, arr.length - 1, queL, queR);
        }

        //This is a helper function.
        //************* DO NOT USE THIS ****************
        private int Query1(int index, int segL, int segR, int queL, int queR) {
            if (queL > segR || queR < segL) {
                return -1;
            }

            if (queL <= segL && queR >= segR) {
                return st[index];
            }

            int ans1 = Query1(index * 2, segL, (segL + segR) / 2, queL, queR);
            int ans2 = Query1(index * 2 + 1, (segL + segR) / 2 + 1, segR, queL, queR);
            if (ans1 == -1) {
                return ans2;
            }

            if (ans2 == -1) {
                return ans1;
            }
//             Segment tree implemented for range minimum query. Change the below line to change the function.
            return Math.min(ans1, ans2);
        }

        private void update(int idx, int val) {
            update1(1, 0, arr.length - 1, idx, val);
        }

        private void update1(int node, int queL, int queR, int idx, int val) {
            // idx - index to be updated in the array
            // node - index to be updated in the seg tree
            if (queL == queR) {
                // Leaf node
                arr[idx] += val;
                st[node] += val;
            } else {
                int mid = (queL + queR) / 2;
                if (queL <= idx && idx <= mid) {
                    // If idx is in the left child, recurse on the left child
                    update1(2 * node, queL, mid, idx, val);
                } else {
                    // if idx is in the right child, recurse on the right child
                    update1(2 * node + 1, mid + 1, queR, idx, val);
                }
                // Internal node will have the min of both of its children
                st[node] = Math.min(st[2 * node], st[2 * node + 1]);
            }
        }
    }

    private static class FastReader {
        InputStream is;

        public FastReader(boolean onlineJudge) {
            is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        }

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

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

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

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

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

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

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

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

        char[] next(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);
        }

        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();
            }
        }

        long nextLong() {
            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();
            }
        }

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

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

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

        int[][] next2DInt(int n, int m) {
            int[][] arr = new int[n][];
            for (int i = 0; i < n; i++) {
                arr[i] = nextIntArray(m);
            }
            return arr;
        }

        long[][] next2DLong(int n, int m) {
            long[][] arr = new long[n][];
            for (int i = 0; i < n; i++) {
                arr[i] = nextLongArray(m);
            }
            return arr;
        }

        int[] shuffle(int[] arr) {
            Random r = new Random();
            for (int i = 1, j; i < arr.length; i++) {
                j = r.nextInt(i);
                arr[i] = arr[i] ^ arr[j];
                arr[j] = arr[i] ^ arr[j];
                arr[i] = arr[i] ^ arr[j];
            }
            return arr;
        }

        int[] uniq(int[] arr) {
            Arrays.sort(arr);
            int[] rv = new int[arr.length];
            int pos = 0;
            rv[pos++] = arr[0];
            for (int i = 1; i < arr.length; i++) {
                if (arr[i] != arr[i - 1]) {
                    rv[pos++] = arr[i];
                }
            }
            return Arrays.copyOf(rv, pos);
        }
    }

}


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

public class Main {

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

        new Main().go();
    }

    PrintWriter out;
    Reader in;
    BufferedReader br;

    Main() throws IOException {

        try {

            //br = new BufferedReader( new FileReader("input.txt") );
            //in = new Reader("input.txt");
            in = new Reader("input.txt");
            out = new PrintWriter( new BufferedWriter(new FileWriter("output.txt")) );
        }
        catch (Exception e) {

            //br = new BufferedReader( new InputStreamReader( System.in ) );
            in = new Reader();
            out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(System.out)) );
        }
    }

    void go() throws Exception {

        //int t = in.nextInt();
        int cs = 1;
        int t = 1;
        while (t > 0) {
            //out.print("Case #" + cs + ": ");
            solve();
            t--;
            cs++;
        }

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

    int inf = 2000000000;
    int mod = 1000000007;
    double eps = 0.000000001;

    int n;
    int m;

    ArrayList<Integer>[] g;
    int[] a;
    void solve() throws IOException {
        int n = in.nextInt();
        int k = in.nextInt();
        int a = in.nextInt();
        int b = in.nextInt();
        long c = (long) n * k;
        long min = Long.MAX_VALUE;
        long max = 0;

        for (int i = 0; i < n; i++) {
            long pos = (long) k * i;
            long next = (pos + b) % c;
            long prev = (pos - b) % c;
            long pa = c - a;
            if (prev < 0) prev = (prev + c) % c;

            long[] p1 = {a, pa};
            long[] p2 = {next, prev};

            for (long pos1 : p1)
                for (long pos2 : p2) {
                    long res = check(pos1, pos2, c)
                    min = Math.min(min, res);
                    max = Math.max(max, res);
                }
        }

        out.println(min + " " + max);
    }

    long check(long pos1, long pos2, long c) {
        long l = pos2 - pos1;
        if (l < 0) l += c;
        if (l == 0) l = c;
        long gcd = gcd(c, l);
        long cnt = c / gcd;
        return cnt;
    }

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

    class Pair implements Comparable<Pair> {

        long a;
        int b;

        Pair(long a, int b) {
            this.a = a;
            this.b = b;
        }

        public int compareTo(Pair p) {
            if (a != p.a)
                return Long.compare(a, p.a);
            else
                return Integer.compare(b, p.b);
        }
    }

    class Item {

        int a;
        int b;
        int c;

        Item(int a, int b, int c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }

    }

    class Reader {

        BufferedReader  br;
        StringTokenizer tok;

        Reader(String file) throws IOException {
            br = new BufferedReader( new FileReader(file) );
        }

        Reader() throws IOException {
            br = new BufferedReader( new InputStreamReader(System.in) );
        }

        String next() throws IOException {

            while (tok == null || !tok.hasMoreElements())
                tok = new StringTokenizer(br.readLine());
            return tok.nextToken();
        }

        int nextInt() throws NumberFormatException, IOException {
            return Integer.valueOf(next());
        }

        long nextLong() throws NumberFormatException, IOException {
            return Long.valueOf(next());
        }

        double nextDouble() throws NumberFormatException, IOException {
            return Double.valueOf(next());
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

    }

    static class InputReader
    {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public InputReader()
        {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public InputReader(String file_name) throws IOException
        {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException
        {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1)
            {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException
        {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do
            {
                ret = ret * 10 + c - '0';
            }  while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException
        {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException
        {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.')
            {
                while ((c = read()) >= '0' && c <= '9')
                {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException
        {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException
        {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException
        {
            if (din == null)
                return;
            din.close();
        }
    }

}


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

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

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

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

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

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

            System.out.println(res);
        }
    }

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

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

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

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

        res = (res * res) % modVal;

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

        return res;
    }

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

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

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

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

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

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

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

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

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

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

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

        return res;
    }

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

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

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

        return res;
    }

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

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

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

        res = res.multiplyMod(res, modVal);

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

        return res;
    }

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

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

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

            builder.append('\n');
        }

        return builder.toString();
    }
}


import sun.tools.tree.ThisExpression;

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

public class CFA {
  BufferedReader br;
  PrintWriter out;
  StringTokenizer st;
  boolean eof;
  private static final long MOD = 1000L * 1000L * 1000L + 7;
  private static final int[] dx = {0, -1, 0, 1};
  private static final int[] dy = {1, 0, -1, 0};
  private static final String yes = "Yes";
  private static final String no = "No";

  void solve() {
//    int T = nextInt();
    int T = 1;
    for (int i = 0; i < T; i++) {
      helper();
    }
  }

  void helper() {
    long n = nextLong();
    long k = nextLong();
    int l = nextInt();
    long m = nextLong();
    long[][] init = {{1, 1}, {1, 0}};
    long[][] fib = powMod(init, n + 1, m);
    long res = 1;
    int highestBit = -1;
    for (int i = 0; i < 64; i++) {
      if (((1L << i) & k) != 0) {
        highestBit = i;
      }
    }

    if (highestBit > l - 1) {
      outln(0);
      return;
    }

    for (int i = 0; i < l; i++) {
      if (((1L << i) & k) == 0) {
        res = res * fib[0][0];
        res = res % m;
      } else {
        long tmp = powMod(2, n, m);
        tmp = (tmp + m - fib[0][0]) % m;
        res = res * tmp % m;
      }
    }
    outln(res);
  }

  // Power Calculate N^M % MOD, N and M can be long (up to 2^64, ~10^18)
  public long powMod(long N, long M, long MOD){//N^M % MOD
    if(M == 0L)
      return 1L;
    long[] hp = new long[64];
    boolean[] bp = new boolean[64];
    hp[0] = N;
    for(int i = 1; i < hp.length; i++) {
      hp[i] = (hp[i - 1] * hp[i - 1]) % MOD;
    }
    for(int j = 0; j < hp.length; j++) {
      if((M & (1L << j)) != 0)
        bp[j] = true;
    }
    long res = 1;
    for(int i = 0;i < bp.length; i++){
      if(bp[i]) {
        res = (res * hp[i]) % MOD;
      }
    }
    return res;
  }

  long[][] powMod(long[][] mat, long pow, long Mod) {
    int n = mat.length;
    long[][] res = new long[n][n];
    for (int i = 0; i < n; i++) {
      res[i][i] = 1;
    }
    if (pow == 0) {
      return res;
    }
    if (pow % 2 != 0) {
      res = mat;
    }
    long[][] hf = mult(mat, mat, Mod);
    long[][] tmp = powMod(hf, pow / 2, Mod);
    return mult(tmp, res, Mod);
  }

  long[][] mult(long[][] m1, long[][] m2, long Mod) {
    int n = m1.length;
    long[][] res = new long[n][n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        long tmp = 0;
        for (int k = 0; k < n; k++) {
          tmp += m1[i][k] * m2[k][j] % Mod;
          if (tmp >= Mod) {
            tmp -= Mod;
          }
        }
        res[i][j] = tmp;
      }
    }
    return res;
  }

  void shuffle(int[] a) {
    int n = a.length;
    for(int i = 0; i < n; i++) {
      int r = i + (int) (Math.random() * (n - i));
      int tmp = a[i];
      a[i] = a[r];
      a[r] = tmp;
    }
  }

  int gcd(int a, int b) {
    while(a != 0 && b != 0) {
      int c = b;
      b = a % b;
      a = c;
    }
    return a + b;
  }
  private void outln(Object o) {
    out.println(o);
  }
  private void out(Object o) {
    out.print(o);
  }
  private void formatPrint(double val) {
    outln(String.format("%.9f%n", val));
  }
  public CFA() {
    br = new BufferedReader(new InputStreamReader(System.in));
    out = new PrintWriter(System.out);
    solve();
    out.close();
  }
  public static void main(String[] args) {
    new CFA();
  }

  public long[] nextLongArr(int n) {
    long[] res = new long[n];
    for(int i = 0; i < n; i++)
      res[i] = nextLong();
    return res;
  }
  public int[] nextIntArr(int n) {
    int[] res = new int[n];
    for(int i = 0; i < n; i++)
      res[i] = nextInt();
    return res;
  }
  public String nextToken() {
    while (st == null || !st.hasMoreTokens()) {
      try {
        st = new StringTokenizer(br.readLine());
      } catch (Exception e) {
        eof = true;
        return null;
      }
    }
    return st.nextToken();
  }
  public String nextString() {
    try {
      return br.readLine();
    } catch (IOException e) {
      eof = true;
      return null;
    }
  }
  public int nextInt() {
    return Integer.parseInt(nextToken());
  }
  public long nextLong() {
    return Long.parseLong(nextToken());
  }
  public double nextDouble() {
    return Double.parseDouble(nextToken());
  }
}