import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class D {
    private static StreamTokenizer in;
    private static PrintWriter out;
    private static BufferedReader inB;

    private static int nextInt() throws Exception{
        in.nextToken();
        return (int)in.nval;
    }

    private static String nextString() throws Exception{
        in.nextToken();
        return in.sval;
    }

    static{
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        inB = (new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
    }

    public static void main(String[] args)throws Exception{
        String[] s = inB.readLine().split(" ");
        int n = bitmas.n = Integer.parseInt(s[0]);
        int m = bitmas.m = Integer.parseInt(s[1]);
        int k = Integer.parseInt(s[2]);

        int nsize = bitmas.nsize = n;
        int msize = bitmas.msize = (m)%32 == 0 ? (m/32) : (m/32 + 1);
        int size = bitmas.size = nsize * msize;

        int[][] mas = new int[n][m];

        int[][] emas = new int[n][m];

        for(int i = 0; i<n; i++) {
            char[] c = inB.readLine().toCharArray();
            for(int j = 0; j<c.length; j++) {
                char ch = c[j];
                mas[i][j] = (ch == '#')?0:1;
                emas[i][j] = (ch == 'E')?1:0;
            }
        }

        int[][] masU = new int[n][m];
        int[][] masD = new int[n][m];
        int[][] masL = new int[n][m];
        int[][] masR = new int[n][m];

        for(int i = 0; i<n; i++) {
            for(int j = 0; j<m; j++) {
                masU[i][j] = (mas[i][j] > 0 && i>0   && mas[i-1][j] == 0) ? 1 : 0;
                masD[i][j] = (mas[i][j] > 0 && i<n-1 && mas[i+1][j] == 0) ? 1 : 0;
                masL[i][j] = (mas[i][j] > 0 && j>0   && mas[i][j-1] == 0) ? 1 : 0;
                masR[i][j] = (mas[i][j] > 0 && i<m-1 && mas[i][j+1] == 0) ? 1 : 0;
            }
        }

        bitmas T = new bitmas(), E = new bitmas(), Up1 = new bitmas(), Up2, Down1 = new bitmas(),
            Down2, Left1 = new bitmas(), Left2, Right1 = new bitmas(), Right2;

        T.set(mas);
        E.set(emas);
        Up1.set(masU);
        Down1.set(masD);
        Left1.set(masL);
        Right1.set(masR);

        Up2    = (T.XOR(Up1));
        Down2  = (T.XOR(Down1));
        Left2  = (T.XOR(Left1));
        Right2 = (T.XOR(Right1));

        char[] str = inB.readLine().toCharArray();

        if(T.equals(E)) {
            System.out.println(0);
            return;
        }
        for(int i = 0; i<k; i++) {
            switch(str[i]) {
            case 'U':
                T = (T.AND(Up1)).OR(((T.AND(Up2)).shiftUp()));
                break;
            case 'D':
                T = (T.AND(Down1)).OR(((T.AND(Down2)).shiftDown()));
                break;
            case 'L':
                T = (T.AND(Left1)).OR(((T.AND(Left2)).shiftRight()));
                break;
            case 'R':
                T = (T.AND(Right1)).OR(((T.AND(Right2)).shiftLeft()));
                break;
            }
//          T.print();
            if(T.equals(E)) {
                System.out.println((i+1));
                return;
            }
        }

        System.out.println(-1);
    }
}

class bitmas {
    int[] mas;

    static int n=0,m=0,nsize=0,msize=0,size=0;

    bitmas() {
        mas = new int[size];
    }

    void OutputBinary(int a) {
        for (int i = 0; i < 32; i++) {
            System.out.print(((a >> i) & 1));
        }
    }

    void print() {
        for(int i = 0; i<nsize; i++) {
            for(int j = 0; j<msize; j++) {
                OutputBinary(mas[i*msize + j]);
            }
            System.out.println();
        }
        System.out.println();
    }

    void set(int[][] masNew) {
        for(int i = 0; i<n; i++) {
            for(int j = 0; j<m; j++) {
                int jj = j / 32;
                int k = j%32;
                mas[i*msize + jj] |= (((masNew[i][j] > 0)?1:0)<<k );
            }
        }
    }

    bitmas OR(bitmas b) {
        bitmas ans = new bitmas();
        for(int i = 0; i<nsize; i++) {
            for(int j = 0; j<msize; j++) {
                ans.mas[i*msize + j] = b.mas[i*msize + j] | mas[i*msize + j];
            }
        }
        return ans;
    }

    bitmas AND(bitmas b) {
        bitmas ans = new bitmas();
        for(int i = 0; i<nsize; i++) {
            for(int j = 0; j<msize; j++) {
                ans.mas[i*msize + j] = b.mas[i*msize + j] & mas[i*msize + j];
            }
        }
        return ans;
    }

    bitmas XOR(bitmas b) {
        bitmas ans = new bitmas();
        for(int i = 0; i<nsize; i++) {
            for(int j = 0; j<msize; j++) {
                ans.mas[i*msize + j] = b.mas[i*msize + j] ^ mas[i*msize + j];
            }
        }
        return ans;
    }

    boolean equals(bitmas b) {
        for(int i = 0; i<nsize; i++) {
            for(int j = 0; j<msize; j++) {
                if(mas[i*msize + j] != b.mas[i*msize + j])return false;
            }
        }
        return true;
    }

    bitmas shiftLeft() {
        for(int i = 0; i<nsize; i++) {
            int take = 0;
            for(int j = msize - 1; j>=0; j--) {

                int need = (1 << 31) & mas[i*msize + j];
                mas[i*msize + j] <<= 1;
                mas[i*msize + j] |= take;
                take = need > 0 ? 1 : 0;
            }
        }
        return this;
    }

    bitmas shiftRight() {
        for(int i = 0; i<nsize; i++) {
            int take = 0;
            for(int j = 0; j<msize; j++) {

                int need = 1 & mas[i*msize + j];
                mas[i*msize + j] >>= 1;
                mas[i*msize + j] |= (take << 31);
                take = need > 0 ? (1 << 31) : 0;
            }
        }
        return this;
    }

    bitmas shiftDown() {
        for(int j = 0; j<msize; j++) {
            int take = 0;
            for(int i = 0; i<nsize; i++) {
                int last = (mas[i*msize + j]);
                mas[i*msize + j] = take;
                take = last;
            }
        }

        return this;
    }

    bitmas shiftUp() {
        for(int j = 0; j<msize; j++) {
            int take = 0;
            for(int i = nsize - 1; i>=0; i--) {
                int last = (mas[i*msize + j]);
                mas[i*msize + j] = take;
                take = last;
            }
        }

        return this;
    }
}


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

/**
 * @author Don Li
 */
public class DZYLovesFFT {

    int n, d, x;
    int[] a, b;

    void solve() {
        n = in.nextInt();
        d = in.nextInt();
        x = in.nextInt();
        a = new int[n];
        b = new int[n];

        initAB();

        int[] inv = new int[n + 1];
        for (int i = 0; i < n; i++) inv[a[i]] = i;

        int[] pos = new int[d];
        for (int i = 0, j = 0; i < n; i++) if (b[i] > 0) pos[j++] = i;

        int s = 30;

        for (int i = 0; i < n; i++) {
            int ans = 0;
            for (int v = n; v >= n - s; v--) {
                if (v > 0 && inv[v] <= i && b[i - inv[v]] > 0) {
                    ans = v;
                    break;
                }
            }
            if (ans == 0) {
                for (int j = 0; j < d && pos[j] <= i; j++) {
                    ans = Math.max(ans, a[i - pos[j]]);
                }
            }
            out.println(ans);
        }
    }

    int getNextX() {
        x = (int) ((x * 37L + 10007) % 1000000007);
        return x;
    }

    void initAB() {
        for (int i = 0; i < n; i = i + 1) {
            a[i] = i + 1;
        }
        for (int i = 0; i < n; i = i + 1) {
            swap(a, i, getNextX() % (i + 1));
        }
        for (int i = 0; i < n; i = i + 1) {
            if (i < d)
                b[i] = 1;
            else
                b[i] = 0;
        }
        for (int i = 0; i < n; i = i + 1) {
            swap(b, i, getNextX() % (i + 1));
        }
    }

    void swap(int[] a, int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new DZYLovesFFT().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

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

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

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

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

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


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Solution {
    static final FS sc = new FS();
    static final PrintWriter pw = new PrintWriter(System.out);
    static  int alp = 20;
    static List<List<Integer>> G;
    public static void main(String[] args) {
        int t = sc.nextInt();
        while (t-- > 0) {
            int n = sc.nextInt();
            char[] a = sc.next().toCharArray();
            char[] b = sc.next().toCharArray();
            G = new ArrayList<>();
            for(int i = 0;i < alp;i++) {
                G.add(new ArrayList<>());
            }
            int[] adj = new int[alp];
            for(int i = 0;i < n;i++) {
                if (a[i] != b[i]) {
                    G.get(a[i] - 'a').add(b[i] - 'a');
                    G.get(b[i] - 'a').add(a[i] - 'a');
                    adj[a[i] - 'a'] |= 1 << (b[i] - 'a');
                }
            }
            int components = 0;
            boolean[] vis = new boolean[alp];
            for (int i = 0;i < alp;i++) {
                if (!vis[i]) {
                    dfs(i, vis);
                    components++;
                }
            }
            int ans = 0;
            boolean[] dp = new boolean[1 << alp];
            dp[0] = true;
            for (int mask = 0;mask < 1 << alp;mask++) {
                if (dp[mask]) {
                    ans = Math.max(ans, Integer.bitCount(mask));
                    for (int u = 0;u < alp;u++) {
                        if ((~mask >> u & 1) == 1 && (adj[u] & mask) == 0) {
                            dp[mask | 1 << u] = true;
                        }
                    }
                }
            }
            pw.println(2 * alp - components - ans);
        }
        pw.flush();
    }

    private static void dfs(int u, boolean[] vis) {
        vis[u] = true;
        for (Integer v : G.get(u)) {
            if (!vis[v]) {
                dfs(v, vis);
            }
        }
    }

    static class FS {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer("");
        String next() {
            while(!st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch(Exception ignored) {}
            }
            return st.nextToken();
        }
        int[] nextArray(int n) {
            int[] a = new int[n];
            for(int i = 0;i < n;i++) {
                a[i] = nextInt();
            }
            return a;
        }
        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
    }
}


public class CodeForces1April2019E {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
//            System.out.print("0\n1\n1\n0\n1\n0\n");
            System.out.print("1\n0\n0\n1\n1\n0\n");
        }
    }
}


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

public class Main {
	public static void main(String[] args) {
		InputReader in = new InputReader (System.in);
		PrintWriter out = new PrintWriter (System.out);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskD {
	int[][] ans;
	int tot;
	class Line {
		int a,b,c,id;
	};

	public void solve (int TestNumber, InputReader in, PrintWriter out) {
		int n = in.nextInt();
		int k = in.nextInt();
		Line[] road = new Line[n];
		for (int i = 0; i < n; ++i) {
			road[i] = new Line();//initialize is necessary
			road[i].a = in.nextInt();
			road[i].b = in.nextInt();
			road[i].c = in.nextInt();
			road[i].id = i+1;
		}
		ans = new int[k][2];
		tot = -1;
		calc(road, k);
		if (tot == -1) {
			out.println("NO");
			return;
		}
		out.println("YES");
		out.println(k-tot);
		for (int i = tot; i < k; ++i) {
			out.println(ans[i][0] + " " + ans[i][1]);
		}
	}
	//Java 特点，有了.length,就不用记录数组长度了；有了for each: 就不用枚举下标了
	private void calc(Line[] road, int k) {
		if (road.length > k*k) {
			if (k == 0) return;
			double pr = 1.0 - getPr(road.length,k);
			int cnt = 1;
			double s = pr;
			while (s > 1e-10) {
				++cnt;
				s *= pr;
			}
			Random rand = new Random(19950315L + System.currentTimeMillis());
			for ( ;cnt > 0; --cnt) {
				Line p = road[rand.nextInt(road.length)];
				Line q = road[rand.nextInt(road.length)];
				int denom = p.a*q.b-p.b*q.a;
				if (denom == 0) continue;
				int x = -(p.c*q.b-p.b*q.c);
				int y = -(p.a*q.c-p.c*q.a);

				int num = 0;
				for (Line r : road) {
					if (r.a*x+r.b*y+r.c*denom == 0) ++num;
				}
				if (num > k) {
					ans[k-1][0] = p.id;
					ans[k-1][1] = q.id;
					int t_tot = 0;
					Line[] n_road = new Line[road.length - num];
					for (Line r : road) {
						if (r.a*x+r.b*y+r.c*denom != 0) {
							n_road[t_tot++] = r;
						}
					}
					calc(n_road, k-1);
					return;
				}
			}
		}
		else if (road.length == 0) {
			tot = k;
		}
		else {
			Random rand = new Random(19950315L + System.currentTimeMillis());
			Line p = road[rand.nextInt(road.length)];
			boolean[] mark = new boolean[road.length];
			Arrays.fill(mark, false);
			boolean any = false;
			for (int i = 0; i < road.length; ++i) {
				if (mark[i]) continue;
				Line q = road[i];
				int denom = p.a*q.b-p.b*q.a;
				if (denom == 0) continue;
				any = true;
				int x = -(p.c*q.b-p.b*q.c);
				int y = -(p.a*q.c-p.c*q.a);

				int num = 0;
				for (int j = 0; j < road.length; ++j) {
					Line r = road[j];
					if (r.a*x+r.b*y+r.c*denom == 0) {
						++num;
						mark[j] = true;
					}
				}
				Line[] n_road = new Line[road.length - num];
				ans[k-1][0] = p.id;
				ans[k-1][1] = q.id;
				int n_tot = 0;
				for (Line r : road) {
					if (r.a*x+r.b*y+r.c*denom != 0) {
						n_road[n_tot++] = r;
					}
				}
				calc(n_road, k-1);
				if (tot > -1) return;
			}
			if (!any) {
				ans[k-1][0] = p.id;
				ans[k-1][1] = -1;
				Line[] n_road = new Line[road.length - 1];
				int n_tot = 0;
				for (Line r : road) {
					if (r != p) {
						n_road[n_tot++] = r;
					}
				}
				calc(n_road, k-1);
			}
		}
	}

	private double getPr(int n, int k) {
		long ret = Long.MAX_VALUE;
		for (int small = 0; small < k; ++small) {
			int rem = n - small * k;
			int big = k - small;
			long pair = 0;
			for (int id = 0; id < big; ++id) {
				long size = rem / big;//size 得 long不能 int
				if (rem % big > id) ++size;
				pair += size*(size-1);
			}
			ret = Math.min(ret, pair);
		}
		return (double)ret/n/n;
	}
}

class InputReader {
	BufferedReader reader;
	StringTokenizer tokenizer;

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

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

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


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

public class Main {
    static final int MOD = 1000000007;

    public static int count(int height , int width) {
        boolean[][] field = new boolean[height][width];
        int[][][][] res = new int[2][2][width][width];
        int tR = 0;
        for (int row = 0; row < height; ++row) {
            int[][][][] newRes = new int[2][2][width][width];
            for (int fD = 0; fD < 2; ++fD)
                for (int lD = 0; lD < 2; ++lD)
                    for (int fC = 0; fC < width; ++fC)
                        for (int lC = fC; lC < width; ++lC) {
                            int cur = res[fD][lD][fC][lC];
                            if (cur == 0) continue;
                            for (int newfD = fD; newfD < 2; ++newfD)
                                for (int newlD = lD; newlD < 2; ++newlD) {
                                    int newfC;
                                    if (newfD == 0)
                                        newfC = fC;
                                    else if (fD == 0)
                                        newfC = fC + 1;
                                    else
                                        newfC = fC;
                                    int nL;
                                    if (newlD == 0)
                                        nL = lC;
                                    else if (lD == 0)
                                        nL = lC - 1;
                                    else
                                        nL = lC;
                                    if (newfC > nL)
                                        continue;
                                    int[] arr = newRes[newfD][newlD][newfC];
                                    arr[nL] += cur;
                                    if (arr[nL] >= MOD) arr[nL] -= MOD;
                                }
                        }

            for (int fD = 0; fD < 2; ++fD)
                for (int lD = 0; lD < 2; ++lD) {
                    int[][] arr = newRes[fD][lD];
                    if (fD == 0 && lD == 1) {
                        {
                            int lD = lD == 0 ? 1 : -1;
                            int lastMin = lD == 1 ? 0 : width - 1;
                            int lastMax = lD == 1 ? width : -1;
                            for (int lC = lastMin; lC != lastMax; lC += lD) {
                                for (int fC = 0; fC <= lC; ++fC) {
                                    int cur = arr[fC][lC];
                                    if (cur == 0) continue;
                                    int nL = lC + lD;
                                    if (nL >= fC && nL < width) {
                                        arr[fC][nL] += cur;
                                        if (arr[fC][nL] >= MOD) arr[fC][nL] -= MOD;
                                    }
                                }
                            }
                        }
                        {
                            int fD = fD == 0 ? -1 : 1;
                            int fM = fD == 1 ? 0 : width - 1;
                            int firstMax = fD == 1 ? width : -1;
                            for (int fC = fM; fC != firstMax; fC += fD) {
                                for (int lC = fC; lC < width; ++lC) {
                                    int cur = arr[fC][lC];
                                    if (cur == 0) continue;
                                    int newfC = fC + fD;
                                    if (newfC >= 0 && newfC <= lC) {
                                        arr[newfC][lC] += cur;
                                        if (arr[newfC][lC] >= MOD) arr[newfC][lC] -= MOD;
                                    }
                                }
                            }
                        }
                    } else {
                        {
                            int fD = fD == 0 ? -1 : 1;
                            int fM = fD == 1 ? 0 : width - 1;
                            int firstMax = fD == 1 ? width : -1;
                            for (int fC = fM; fC != firstMax; fC += fD) {
                                for (int lC = fC; lC < width; ++lC) {
                                    int cur = arr[fC][lC];
                                    if (cur == 0) continue;
                                    int newfC = fC + fD;
                                    if (newfC >= 0 && newfC <= lC) {
                                        arr[newfC][lC] += cur;
                                        if (arr[newfC][lC] >= MOD) arr[newfC][lC] -= MOD;
                                    }
                                }
                            }
                        }
                        {
                            int lD = lD == 0 ? 1 : -1;
                            int lastMin = lD == 1 ? 0 : width - 1;
                            int lastMax = lD == 1 ? width : -1;
                            for (int lC = lastMin; lC != lastMax; lC += lD) {
                                for (int fC = 0; fC <= lC; ++fC) {
                                    int cur = arr[fC][lC];
                                    if (cur == 0) continue;
                                    int nL = lC + lD;
                                    if (nL >= fC && nL < width) {
                                        arr[fC][nL] += cur;
                                        if (arr[fC][nL] >= MOD) arr[fC][nL] -= MOD;
                                    }
                                }
                            }
                        }
                    }
                }

            for (int fC = 0; fC < width; ++fC) {
                boolean ok = true;
                for (int lC = fC; lC < width; ++lC) {
                    if (field[row][lC])
                        ok = false;
                    if (!ok) {
                        for (int fD = 0; fD < 2; ++fD)
                            for (int lD = 0; lD < 2; ++lD)
                                newRes[fD][lD][fC][lC] = 0;
                   } else {
                        newRes[0][0][fC][lC] += 1;
                        if (newRes[0][0][fC][lC] >= MOD) newRes[0][0][fC][lC] -= MOD;
                    }
                }
            }

            res = newRes;
            for (int fD = 0; fD < 2; ++fD)
                for (int lD = 0; lD < 2; ++lD)
                    for (int fC = 0; fC < width; ++fC)
                        for (int lC = fC; lC < width; ++lC) {
                            tR += res[fD][lD][fC][lC];
                            if (tR >= MOD) tR -= MOD;
                        }
        }
        return tR;
    }
    public static void main(String[] args){
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt() , m = cin.nextInt();
        System.out.println(count(n, m));
    }
}


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

import static java.lang.Math.random;

/**
 * @author Don Li
 */
public class PointsLinesTitles {

    int N = (int) 1e5 + 10;
    int MOD = (int) 1e9 + 7;

    int n;
    int[][] p;
    List<Integer>[] G;

    boolean[] used = new boolean[N];
    Set<Integer> uniqueX = new HashSet<>(), uniqueY = new HashSet<>();
    long sumDegree = 0, numNode = 0;

    void solve() {
        n = in.nextInt();

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

        int[] x = new int[n], y = new int[n];
        for (int i = 0; i < n; i++) {
            x[i] = p[i][0];
            y[i] = p[i][1];
        }
        sort(x);
        sort(y);
        for (int i = 0; i < n; i++) {
            p[i][0] = lowerBound(x, p[i][0]);
            p[i][1] = lowerBound(y, p[i][1]);
        }

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

        List<Integer>[] ver = new List[n], hor = new List[n];
        for (int i = 0; i < n; i++) {
            ver[i] = new ArrayList<>();
            hor[i] = new ArrayList<>();
        }
        for (int i = 0; i < n; i++) {
            ver[p[i][0]].add(i);
            hor[p[i][1]].add(i);
        }
        for (int i = 0; i < n; i++) {
            ver[i].sort(Comparator.comparingInt(a -> p[a][1]));
            for (int j = 1; j < ver[i].size(); j++) {
                int u = ver[i].get(j - 1), v = ver[i].get(j);
                addNeighbors(u, v);
            }
            hor[i].sort(Comparator.comparingInt(a -> p[a][0]));
            for (int j = 1; j < hor[i].size(); j++) {
                int u = hor[i].get(j - 1), v = hor[i].get(j);
                addNeighbors(u, v);
            }
        }

        long ans = 1;
        for (int i = 0; i < n; i++) {
            if (!used[i]) {
                uniqueX.clear();
                uniqueY.clear();
                sumDegree = 0; numNode = 0;
                dfs(i);
                long ways = mpow(2, uniqueX.size() + uniqueY.size());
                if (sumDegree / 2 == numNode - 1) ways--;
                ans = ans * ways % MOD;
            }
        }
        out.println(ans);
    }

    void dfs(int u) {
        used[u] = true;
        uniqueX.add(p[u][0]);
        uniqueY.add(p[u][1]);
        numNode++;
        sumDegree += G[u].size();
        for (int v : G[u]) {
            if (!used[v]) dfs(v);
        }
    }

    long mpow(int a, int n) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) > 0) res = res * a % MOD;
            a = a * a % MOD;
            n >>= 1;
        }
        return res;
    }

    void addNeighbors(int u, int v) {
        G[u].add(v);
        G[v].add(u);
    }

    void sort(int[] a) {
        int n = a.length;
        for (int i = 0; i < n; i++) {
            int j = (int) (i + random() * (n - i));
            int tmp = a[i];
            a[i] = a[j];
            a[j] = tmp;
        }
        Arrays.sort(a);
    }

    int lowerBound(int[] a, int k) {
        int lb = -1, ub = a.length;
        while (ub - lb > 1) {
            int m = (lb + ub) >> 1;
            if (a[m] >= k) ub = m;
            else lb = m;
        }
        return ub;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new PointsLinesTitles().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

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

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

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

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

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


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.io.BufferedWriter;
import java.util.AbstractSet;
import java.util.Set;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Random;
import java.util.AbstractMap;
import java.util.Map;
import java.io.Writer;
import java.util.Map.Entry;
import java.io.OutputStreamWriter;
import java.util.NoSuchElementException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Egor Kulikov (egor@egork.net)
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskG solver = new TaskG();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskG {
        Map<Long, Long>[][] result = new Map[51][51];
        long[][] max = new long[51][51];

        {
            for (int i = 0; i < 51; i++) {
                for (int j = 0; j < 51; j++) {
                    result[i][j] = new EHashMap<>();
                    max[i][j] = (1L << i) - 1 - i + (1L << j) - 1 - j;
                }
            }
        }

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            long s = in.readLong();
            long answer = 0;
            for (int i = 0; (1L << (i + 1)) - 2 <= s; i++) {
                for (int j = 0; (1L << (j + 1)) + (1L << (i + 1)) - 3 <= s; j++) {
                    long maxDelta = max[i][j];
                    long by = (1L << (i + 1)) + (1L << (j + 1)) - 3;
                    for (long v = s / by; v > 0; v--) {
                        long remaining = s - v * by - ((1L << j) - 1);
                        if (remaining < 0) {
                            continue;
                        }
                        if (remaining > maxDelta) {
                            break;
                        }
                        answer += query(Math.max(Math.max(i, j) - 1, 0), Math.max(Math.min(i, j) - 1, 0), remaining);
                    }
                }
            }
            out.printLine(answer);
        }

        private long query(int mx, int mn, long val) {
            if (val > max[mx][mn]) {
                return 0;
            }
            if (mx == 0) {
                return 1;
            }
            if (result[mx][mn].containsKey(val)) {
                return result[mx][mn].get(val);
            }
            long by = (1L << mx) - 1;
            if (mx == mn) {
                long result = query(mx - 1, mn - 1, val);
                if (val >= by) {
                    result += query(mx - 1, mn - 1, val - by) * 2;
                }
                if (val >= 2 * by) {
                    result += query(mx - 1, mn - 1, val - 2 * by);
                }
                this.result[mx][mn].put(val, result);
                return result;
            }
            long result = query(mx - 1, mn, val);
            if (val >= by) {
                result += query(mx - 1, mn, val - by);
            }
            this.result[mx][mn].put(val, result);
            return result;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

    }

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

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

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

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

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

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

        }

    }

    static class EHashMap<E, V> extends AbstractMap<E, V> {
        private static final int[] shifts = new int[10];
        private int size;
        private EHashMap.HashEntry<E, V>[] data;
        private int capacity;
        private Set<Entry<E, V>> entrySet;

        static {
            Random random = new Random(System.currentTimeMillis());
            for (int i = 0; i < 10; i++) {
                shifts[i] = 1 + 3 * i + random.nextInt(3);
            }
        }

        public EHashMap() {
            this(4);
        }

        private void setCapacity(int size) {
            capacity = Integer.highestOneBit(4 * size);
            //noinspection unchecked
            data = new EHashMap.HashEntry[capacity];
        }

        public EHashMap(int maxSize) {
            setCapacity(maxSize);
            entrySet = new AbstractSet<Entry<E, V>>() {

                public Iterator<Entry<E, V>> iterator() {
                    return new Iterator<Entry<E, V>>() {
                        private EHashMap.HashEntry<E, V> last = null;
                        private EHashMap.HashEntry<E, V> current = null;
                        private EHashMap.HashEntry<E, V> base = null;
                        private int lastIndex = -1;
                        private int index = -1;

                        public boolean hasNext() {
                            if (current == null) {
                                for (index++; index < capacity; index++) {
                                    if (data[index] != null) {
                                        base = current = data[index];
                                        break;
                                    }
                                }
                            }
                            return current != null;
                        }

                        public Entry<E, V> next() {
                            if (!hasNext()) {
                                throw new NoSuchElementException();
                            }
                            last = current;
                            lastIndex = index;
                            current = current.next;
                            if (base.next != last) {
                                base = base.next;
                            }
                            return last;
                        }

                        public void remove() {
                            if (last == null) {
                                throw new IllegalStateException();
                            }
                            size--;
                            if (base == last) {
                                data[lastIndex] = last.next;
                            } else {
                                base.next = last.next;
                            }
                        }
                    };
                }

                public int size() {
                    return size;
                }
            };
        }

        public EHashMap(Map<E, V> map) {
            this(map.size());
            putAll(map);
        }

        public Set<Entry<E, V>> entrySet() {
            return entrySet;
        }

        public void clear() {
            Arrays.fill(data, null);
            size = 0;
        }

        private int index(Object o) {
            return getHash(o.hashCode()) & (capacity - 1);
        }

        private int getHash(int h) {
            int result = h;
            for (int i : shifts) {
                result ^= h >>> i;
            }
            return result;
        }

        public V remove(Object o) {
            if (o == null) {
                return null;
            }
            int index = index(o);
            EHashMap.HashEntry<E, V> current = data[index];
            EHashMap.HashEntry<E, V> last = null;
            while (current != null) {
                if (current.key.equals(o)) {
                    if (last == null) {
                        data[index] = current.next;
                    } else {
                        last.next = current.next;
                    }
                    size--;
                    return current.value;
                }
                last = current;
                current = current.next;
            }
            return null;
        }

        public V put(E e, V value) {
            if (e == null) {
                return null;
            }
            int index = index(e);
            EHashMap.HashEntry<E, V> current = data[index];
            if (current != null) {
                while (true) {
                    if (current.key.equals(e)) {
                        V oldValue = current.value;
                        current.value = value;
                        return oldValue;
                    }
                    if (current.next == null) {
                        break;
                    }
                    current = current.next;
                }
            }
            if (current == null) {
                data[index] = new EHashMap.HashEntry<E, V>(e, value);
            } else {
                current.next = new EHashMap.HashEntry<E, V>(e, value);
            }
            size++;
            if (2 * size > capacity) {
                EHashMap.HashEntry<E, V>[] oldData = data;
                setCapacity(size);
                for (EHashMap.HashEntry<E, V> entry : oldData) {
                    while (entry != null) {
                        EHashMap.HashEntry<E, V> next = entry.next;
                        index = index(entry.key);
                        entry.next = data[index];
                        data[index] = entry;
                        entry = next;
                    }
                }
            }
            return null;
        }

        public V get(Object o) {
            if (o == null) {
                return null;
            }
            int index = index(o);
            EHashMap.HashEntry<E, V> current = data[index];
            while (current != null) {
                if (current.key.equals(o)) {
                    return current.value;
                }
                current = current.next;
            }
            return null;
        }

        public boolean containsKey(Object o) {
            if (o == null) {
                return false;
            }
            int index = index(o);
            EHashMap.HashEntry<E, V> current = data[index];
            while (current != null) {
                if (current.key.equals(o)) {
                    return true;
                }
                current = current.next;
            }
            return false;
        }

        public int size() {
            return size;
        }

        private static class HashEntry<E, V> implements Entry<E, V> {
            private final E key;
            private V value;
            private EHashMap.HashEntry<E, V> next;

            private HashEntry(E key, V value) {
                this.key = key;
                this.value = value;
            }

            public E getKey() {
                return key;
            }

            public V getValue() {
                return value;
            }

            public V setValue(V value) {
                V oldValue = this.value;
                this.value = value;
                return oldValue;
            }

        }

    }
}


import java.util.*;
import static java.lang.Math.*;

public class E {
    static void p(Object ...args) {System.out.println(Arrays.deepToString(args));}
    static long MOD = 1_000_000_007;

    /*static int score(int a, int k) {
        int ans = 0;
        while( a > 0) {
            ans += a % k;
            a /= k;
        }
        return ans % k;
    }

    public static long slow(int N, int K) {
        long[] V = new long[N+1];
        for (int i = 0; i <= N; i++)
            V[i] = score(i, K);
        long[] dp = new long[N+1];
        for (int i = 0; i <= N; i++) {
            for (int j = 0; j < K; j++) {
                for (int a = i - 1; a >= 0; a--) {
                    if (V[a] == j) {
                        dp[i] += dp[a];
                        break;
                    }
                }
            }
            dp[i] += 1;
            dp[i] %= MOD;
        }
        return dp[N];
    }*/
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long N = in.nextLong();
        int K = in.nextInt();

        long[][][] M = new long[70][][];
        for (int i = 2; i < M.length; i++)
            M[i] = makeMatrix(K, i);

        /*p("M[2]");
        for (int i = 0; i < M[2].length; i++)
            p(M[2][i]);
        p("M[3]");
        for (int i = 0; i < M[3].length; i++)
            p(M[3][i]);*/

        long[][][] moveBy = new long[70][][];
        long[][][] moveByK = new long[70][][];
        for (int i = 1; i < moveBy.length - 1; i++) {
            long[][] ans = new long[K+1][K+1];
            for (int j = 0; j < ans.length; j++)
                ans[j][j] = 1;
            for (int j = i - 1; j >= 1; j--)
                ans = multiply(ans, moveByK[j]);

            ans = multiply(ans, M[i+1]);
            moveBy[i] = ans;
            moveByK[i] = new long[K+1][K+1];
            for (int j = 0; j <= K; j++)
                moveByK[i][j][j] = 1;
            for (int j = 0; j < K-1; j++)
                moveByK[i] = multiply(moveByK[i], moveBy[i]);
        }
        /*p("moveBy[2]");
        for (int i = 0; i <= K; i++)
            p(moveBy[2][i]);*/

        long at = 0;
        long[][] f = new long[K+1][K+1];
        for (int i = 0; i < f.length; i++)
            f[i][i] = 1;
        //f = multiply(f, M[2]);
        //f = multiply(f, M[3]);
        long temp = N / K;
        for (int i = 1; temp > 0; i++) {
            for (int j = 0; j < temp % K; j++) {
                //p("mult by", i);
                f = multiply(moveBy[i], f);
            }
            temp /= K;
        }
        /*p("f");
        for (int i = 0; i < K+1; i++)
            p(f[i]);*/
        long[] start = new long[K+1];
        for (int i = 0; i < start.length; i++)
            start[i] = (1L<<(i)) % MOD;
        start[K] = 1;

        int position = (int)(N % K);
        //p("taking: ", position);
        long ans = 0;
        for (int i = 0; i < start.length; i++)
            ans += (start[i] * f[i][position]) % MOD;
        ans %= MOD;

        /*long a2 = slow((int)N, K);
        if (ans != a2) {
            p(ans, a2);
            throw new RuntimeException();
        }*/
        System.out.println(ans);
    }
    static long[][] makeMatrix(int K, int a) {
        long[][] res = new long[K+1][K+1];

        int[] v = new int[2*K];
        v[2*K-1] = 0;
        for (int i = 2*K-2; i >= 0; i--) {
            if (i == K-1) {
                v[i] = (K + (K-a + v[i+1]) % K) % K;
            } else {
                v[i] = (K + (K-1 + v[i+1]) % K) % K;
            }
        }
        /*if (a == 2 || a == 3) {
            p(a, v);
        }*/
        for (int i = 0; i <= K; i++)
            res[K][i]++;
        for (int c = 0; c < K; c++) {
            for (int i = 0; i < K; i++) {
                boolean found = false;
                for (int j = c - 1 + K; j >= 0; j--) {
                    if (v[j] == i) {
                        found = true;
                        if (j < K) {
                            res[j][c] += 1;
                        } else {
                            for (int b = 0; b <= K; b++)
                                res[b][c] += res[b][j-K];
                        }
                        break;
                    }
                }
                if (!found) {
                    p(c, i, v);
                    throw new RuntimeException();
                }
            }
        }
        return res;
    }
    static long[][] multiply(long[][] A, long[][] B) {
        long[][] res = new long[A.length][A.length];
        for (int r = 0; r < A.length; r++)
            for (int c = 0; c < A.length; c++) {
                for (int i = 0; i < A.length; i++)
                    res[r][c] += (A[r][i] * B[i][c]) % MOD;
                res[r][c] %= MOD;
            }
        return res;
    }
 }


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

import static java.lang.Math.*;

public class Main extends PrintWriter {
    BufferedReader in;
    StringTokenizer stok;
    final Random rand = new Random(31);
    final int inf = (int) 1e9;
    final long linf = (long) 1e18;

    public void solve() throws IOException {
        int n = nextInt();
        char[][] a = new char[n][];
        for (int i = 0; i < n; i++) {
            a[i] = next().toCharArray();
        }
        int m = a[0].length;
        long[] d1 = new long[1 << m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i != j) {
                    int x = 0;
                    for (int k = 0; k < m; k++) {
                        if (a[i][k] == a[j][k]) {
                            x |= (1 << k);
                        }
                    }
                    d1[x] |= (1 << i);
                    d1[x] |= (1 << j);
                }
            }
        }
        for (int i = (1 << m) - 1; i >= 0; i--) {
            for (int j = 0; j < m; j++) {
                d1[i] |= d1[i | (1 << j)];
            }
        }
        double[] d = new double[1 << m];
        d[0] = 1;
        for (int mask = 0; mask < (1 << m); mask++) {
            double bc = Integer.bitCount(mask);
            int bc1 = Long.bitCount(d1[mask]);
            if (bc1 == 0) {
                continue;
            }
            for (int i = 0; i < m; i++) {
                if ((mask & (1 << i)) == 0) {
                    int nmask = mask | (1 << i);
                    double nbc1 = Long.bitCount(d1[nmask]);
                    d[nmask] += d[mask] * (nbc1 / bc1) / (m - bc);
                }
            }
        }
        double ans = 0;
        for (int mask = 0; mask < (1 << m); mask++) {
            double finish = 0;
            int bc1 = Long.bitCount(d1[mask]);
            int bc = Long.bitCount(mask);
            for (int i = 0; i < m; i++) {
                if ((mask & (1 << i)) > 0) {
                    int nmask = mask & ~(1 << i);
                    int nbc1 = Long.bitCount(d1[nmask]);
                    if (nbc1 == 0) {
                        continue;
                    }
                    int nbc = Long.bitCount(nmask);
                    finish += d[nmask] * (nbc1 - bc1) / nbc1 / (m - nbc);
                }
            }
            ans += bc * finish;
        }
        printf("%.11f", ans);
    }

    public void run() {
        try {
            solve();
            close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(abs(-1));
        }
    }

    Main() throws IOException {
        super(System.out);
        in = new BufferedReader(new InputStreamReader(System.in));
    }

    Main(String s) throws IOException {
        super("".equals(s) ? "output.txt" : (s + ".out"));
        in = new BufferedReader(new FileReader("".equals(s) ? "input.txt" : (s + ".in")));
    }

    public static void main(String[] args) throws IOException {
        try {
            Locale.setDefault(Locale.US);
        } catch (Exception ignored) {
        }
        new Main().run();
    }

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

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

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

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

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

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

    boolean nextPerm(int[] p) {
        for (int a = p.length - 2; a >= 0; --a)
            if (p[a] < p[a + 1])
                for (int b = p.length - 1; ; --b)
                    if (p[b] > p[a]) {
                        int t = p[a];
                        p[a] = p[b];
                        p[b] = t;
                        for (++a, b = p.length - 1; a < b; ++a, --b) {
                            t = p[a];
                            p[a] = p[b];
                            p[b] = t;
                        }
                        return true;
                    }
        return false;
    }

    <T> List<T>[] createAdjacencyList(int countVertex) {
        List<T>[] res = new List[countVertex];
        for (int i = 0; i < countVertex; i++) {
            res[i] = new ArrayList<T>();
        }
        return res;
    }
}


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

public class B {

    long n, c0, c1;

    public void solve() {
        n = in.nextInt() - 1;
        c0 = in.nextInt();
        c1 = in.nextInt();
        if (c0 > c1) {
            long tmp = c0;
            c0 = c1;
            c1 = tmp;
        }

        if (c0 == 0) {
            out.println(1L * n * (c0 + c1));
            return;
        }

        long left = 0, right = (long) 5e17;

        while (left < right - 1) {
            long mid = (left + right) >>> 1;

            long[] calc = calc(mid);
            if (calc[0] < n) {
                left = mid;
            } else {
                right = mid;
            }
        }
        System.err.println(left);
        long[] calc2 = calc(left);

        long result = calc2[1] + (n - calc2[0]) * (left + 1);
        result += 1L * n * (c0 + c1);
        out.println(result);
    }

    long[] calc(long x) {
        long count = 0, sum = 0;
        for (long j = 0; c1 * j <= x; j++) {
            long maxI = (x - c1 * j) / c0;
            if (j == 0) {
                count += (maxI + 1);
                sum += c0 * maxI * (maxI + 1) / 2;
            } else {
                long curChoose = 1;
                for (long i = 0; i * c0 + j * c1 <= x; i++) {
                    if (i > 0) {
                        curChoose *= (i + j);
                        curChoose /= i;
                    }
                    count += curChoose;
                    sum += curChoose * (i * c0 + j * c1);
                    if (count >= n) {
                        return new long[]{count, sum};
                    }
                }
            }
        }
        return new long[]{count, sum};
    }

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

    FastScanner in;
    PrintWriter out;

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(String fileName) {
            try {
                br = new BufferedReader(new FileReader(fileName));
            } catch (FileNotFoundException e) {
            }
        }

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

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

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

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

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

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


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

public class D {
	InputStream is;
	PrintWriter out;
	String INPUT = "";
	boolean[][] g = new boolean[101][101];
	boolean[][] d = new boolean[101][101];

	void solve()
	{
		int n = ni(), m = ni(), k = ni();
		int two = 0;
		int three = 0;
		boolean f1 = false;
		boolean f2 = false;
		for(int i = 0;i < n;i++){
			char[] str = ns(m);
			int r = -1, g = -1;
			for(int j = 0;j < m;j++){
				if(str[j] == 'R')r = j;
				if(str[j] == 'G')g = j;
			}
			if(r == -1 && g >= 0 && m > 1)f1 = true;
			if(g == -1 && r >= 0 && m > 1)f2 = true;
			if(r >= 0 && g >= 0){
				int dist = Math.abs(r-g);
				if(dist == 2){
					two++;
				}else if(dist >= 3){
					three++;
				}
			}
		}
		if(f1 && f2){
			out.println("Draw");
		}else if(f1){
			out.println("First");
		}else if(f2){
			out.println("Second");
		}else{
			boolean jud = rec(two, three, k);
			if(jud){
				out.println("First");
			}else{
				out.println("Second");
			}
		}
	}

	boolean rec(int b, int c, int k)
	{
		if(d[b][c])return g[b][c];
		d[b][c] = true;
		if(b == 0 && c == 0){
			return g[b][c] = false;
		}
		for(int i = 0;i <= k;i++){
			for(int j = 0;i+j <= k;j++){
				for(int l = 0;i+j+l <= k;l++){
					if(i == 0 && j == 0 && l == 0)continue;
					if(b-i >= 0 && c-j-l >= 0 && !rec(b-i+j, c-j-l, k)){
						return g[b][c] = true;
					}
				}
			}
		}
		return g[b][c] = false;
	}

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

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

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

	public int ni()
	{
		try {
			int num = 0;
			boolean minus = false;
			while((num = is.read()) != -1 && !((num >= '0' && num <= '9') || num == '-'));
			if(num == '-'){
				num = 0;
				minus = true;
			}else{
				num -= '0';
			}

			while(true){
				int b = is.read();
				if(b >= '0' && b <= '9'){
					num = num * 10 + (b - '0');
				}else{
					return minus ? -num : num;
				}
			}
		} catch (IOException e) {
		}
		return -1;
	}

	public long nl()
	{
		try {
			long num = 0;
			boolean minus = false;
			while((num = is.read()) != -1 && !((num >= '0' && num <= '9') || num == '-'));
			if(num == '-'){
				num = 0;
				minus = true;
			}else{
				num -= '0';
			}

			while(true){
				int b = is.read();
				if(b >= '0' && b <= '9'){
					num = num * 10 + (b - '0');
				}else{
					return minus ? -num : num;
				}
			}
		} catch (IOException e) {
		}
		return -1;
	}

	public String ns()
	{
		try{
			int b = 0;
			StringBuilder sb = new StringBuilder();
			while((b = is.read()) != -1 && (b == '\r' || b == '\n' || b == ' '));
			if(b == -1)return "";
			sb.append((char)b);
			while(true){
				b = is.read();
				if(b == -1)return sb.toString();
				if(b == '\r' || b == '\n' || b == ' ')return sb.toString();
				sb.append((char)b);
			}
		} catch (IOException e) {
		}
		return "";
	}

	public char[] ns(int n)
	{
		char[] buf = new char[n];
		try{
			int b = 0, p = 0;
			while((b = is.read()) != -1 && (b == ' ' || b == '\r' || b == '\n'));
			if(b == -1)return null;
			buf[p++] = (char)b;
			while(p < n){
				b = is.read();
				if(b == -1 || b == ' ' || b == '\r' || b == '\n')break;
				buf[p++] = (char)b;
			}
			return Arrays.copyOf(buf, p);
		} catch (IOException e) {
		}
		return null;
	}

	double nd() { return Double.parseDouble(ns()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Collections;
import java.io.InputStream;

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

    static final class TaskF {
        public void solve(int __, InputReader in, PrintWriter out) {
            String s = in.next();
            String t = in.next();
            int[][] result = solve(s.toCharArray(), t.toCharArray());
            out.println(result.length);
            for (int[] pair : result) {
                out.print(pair[0]);
                out.print(' ');
                out.println(pair[1]);
            }
        }

        private int[][] solve(char[] s, char[] t) {
            int[][] result = solveInternal(s, t);
            int[][] anotherResult = solveInternal(t, s);
            if (anotherResult.length < result.length) {
                result = anotherResult;
                for (int[] pair : result) {
                    ArrayUtils.swap(pair, 0, 1);
                }
            }
            return result;
        }

        private int[][] solveInternal(char[] s, char[] t) {
            List<Integer> sChangings = getChangings(s, 0, s.length, s, 0, 0, 'a');
            List<Integer> tChangings = getChangings(t, 0, t.length, t, 0, 0, 'b');
            int[][] result = solveGreedy(s, 0, s.length, s, 0, 0, t, 0, t.length, t, 0, 0, 0, Integer.MAX_VALUE);
            assert result != null;
            int balance = (sChangings.size() - tChangings.size()) / 2;
            for (int i = 0; i < 3; ++i) {
                for (int j = 0; j < 3; ++j) {
                    int sp = (balance > 0 ? balance : 0) + i;
                    int tp = (balance < 0 ? -balance : 0) + j;
                    if ((sp != 0 && sp >= sChangings.size()) || (tp != 0 && tp >= tChangings.size())) continue;
                    int sSep = sp < sChangings.size() ? sChangings.get(sp) : 0;
                    int tSep = tp < tChangings.size() ? tChangings.get(tp) : 0;
                    int[][] current = solveGreedy(t, 0, tSep, s, sSep, s.length, s, 0, sSep, t, tSep, t.length, 1, result.length);
                    if (current != null) {
                        result = current;
                        current[0][0] = sSep;
                        current[0][1] = tSep;
                    }
                }
            }
            return result;
        }

        private int[][] solveGreedy(char[] s1, int s1from, int s1to,
                                    char[] s2, int s2from, int s2to,
                                    char[] t1, int t1from, int t1to,
                                    char[] t2, int t2from, int t2to,
                                    int offset, int limit) {
            List<Integer> ss = getChangings(s1, s1from, s1to, s2, s2from, s2to, 'a');
            List<Integer> tt = getChangings(t1, t1from, t1to, t2, t2from, t2to, 'b');
            int length = Math.max(ss.size(), tt.size());
            if (offset + length >= limit) {
                return null;
            }
            int[][] result = new int[offset + length][2];
            for (int i = 0; i < length; ++i) {
                result[offset + i][0] = pop(ss);
                result[offset + i][1] = pop(tt);
                List<Integer> tmp = ss;
                ss = tt;
                tt = tmp;
            }
            return result;
        }

        private List<Integer> getChangings(char[] s1, int s1from, int s1to, char[] s2, int s2from, int s2to, char target) {
            List<Integer> changings = new ArrayList<>();
            for (int i = s2to; i-- > s2from; ) {
                char current = s2[i];
                if (current != target) {
                    changings.add(s1to - s1from + i - s2from + 1);
                    target = current;
                }
            }
            for (int i = s1to; i-- > s1from; ) {
                char current = s1[i];
                if (current != target) {
                    changings.add(i - s1from + 1);
                    target = current;
                }
            }
            Collections.reverse(changings);
            return changings;
        }

        private static int pop(List<Integer> stack) {
            return stack.isEmpty() ? 0 : stack.remove(stack.size() - 1);
        }

    }

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

        public InputReader(InputStream in) {
            reader = new BufferedReader(new InputStreamReader(in));
        }

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

        public String readLine() {
            String line;
            try {
                line = reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return line;
        }

    }

    static class ArrayUtils {
        private ArrayUtils() {
        }

        public static void swap(int[] array, int i, int j) {
            int tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
        }

    }
}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class Solution implements Runnable {

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

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

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

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

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

	String s;
	int q;

	int f(int q, int t) {
		if (t == 0 || q > 1) return q;
		return 1 - q;
	}

	int token() {
		if (s.charAt(q) == '(') {
			q++;
			int t1 = token();
			char op = s.charAt(q++);
			int t2 = token();
			q++;
			switch (op) {
			case '&':
				if (t1 == 0 || t2 == 0) return 0;
				if (t1 == 1) return t2;
				if (t2 == 1) return t1;
				if (t1 == 2 && t2 == 2) return 2;
				return 3;
			case '|':
				if (t1 == 1 || t2 == 1) return 1;
				if (t1 == 0) return t2;
				if (t2 == 0) return t1;
				if (t1 == 2 && t2 == 2) return 2;
				return 3;
			case '^':
				if (t1 < 2) return f(t2, t1);
				if (t2 < 2) return f(t1, t2);
				if (t1 == t2) return 2;
				return 3;
			}
			return -1;
		} else {
			if (s.charAt(q) == '?') {
				q++;
				return 3;
			}
			return s.charAt(q++) - '0';
		}
	}

	void solve() throws Exception {
		int n = nextInt();
		s = nextToken();
		q = 0;
		int res = token();
		out.println(res != 3? "NO" : "YES");
	}

	public void run() {
		try {
			// Locale.setDefault(Locale.UK);
			in = new BufferedReader(new InputStreamReader(System.in));
			// in = new BufferedReader(new FileReader("input.txt"));
			out = new PrintWriter(System.out);
			// out = new PrintWriter("output.txt");
			solve();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		} finally {
			out.close();
		}
	}

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

}


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

public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int N = cin.nextInt();
        int K = cin.nextInt();
        long ans = (new Solver(N, K)).solve();
        System.out.println(ans);
    }
}

class Solver {
    int N, K;
    long[][][] big, small;
    static long[][] comb;
    static final int Mod = 1000000000 + 7;
    static {
        comb = new long[13][13];
        for (int i = 0; i <= 12; ++i) {
            for (int j = 0; j <= i; ++j) {
                if (j == 0 || j == i) {
                    comb[i][j] = 1;
                }
                else {
                    comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % Mod;
                }
            }
        }
    }
    Solver(int N, int K) {
        this.N = N;
        this.K = K;
        big = new long[N + 1][K + 1][1 << 4];
        small = new long[N + 1][K + 1][1 << 4];
        for (int i = 0; i <= N; ++i) {
            for (int j = 0; j <= K; ++j) {
                for (int k = 0; k < 16; ++k) {
                    big[i][j][k] = small[i][j][k] = -1;
                }
            }
        }
    }
    long solve() {
        long res = calcBig(N, K, 15);
        for (int i = K; i >= 1; --i) {
            res = res * i % Mod;
        }
        return res;
    }
    long calcBig(int size, int count, int mask) {
        if (count < 0) {
            return 0;
        }
        if (big[size][count][mask] != -1) {
            return big[size][count][mask];
        }
        long res = 0;
        if (mask == 15) {
            res += 2 * calcBig(0, count - 2, 0);
        }
        for (int i = 0; i < 4; ++i) {
            int j = (i + 1) & 3;
            if ((mask >> i & 1) == 1 && (mask >> j & 1) == 1) {
                int nxt = mask ^ (1 << i) ^ (1 << j);
                for (int k = nxt; ; k = (k - 1) & nxt) {
                    res += calcSmall(size, count - 1 - Integer.bitCount(k), nxt - k);
                    if (k == 0) {
                        break;
                    }
                }
            }
        }
        int nxt = mask;
        for (int k = nxt; ; k = (k - 1) & nxt) {
            res += calcSmall(size, count - Integer.bitCount(k), nxt - k);
            if (k == 0) {
                break;
            }
        }
        return big[size][count][mask] = res % Mod;
    }
    long calcSmall(int size, int count, int mask) {
        if (count < 0) {
            return 0;
        }
        if (small[size][count][mask] != -1) {
            return small[size][count][mask];
        }
        if (size == 0) {
            return count == 0 ? 1 : 0;
        }
        long res = 0;
        int maxCount = Integer.bitCount(mask) * 3;
        int pairCount = 0;
        for (int i = 0; i < 4; ++i) {
            int j = (i + 1) & 3;
            if ((mask >> i & 1) == 1 && (mask >> j & 1) == 1) {
                pairCount++;
            }
        }
        for (int i = 0; i <= pairCount; ++i) {
            for (int j = 0; j <= maxCount - i * 2; ++j) {
                res += calcBig(size - 1, count - i - j, mask) * comb[pairCount][i] % Mod * comb[maxCount - i * 2][j] % Mod;
            }
        }
        return small[size][count][mask] = res % Mod;
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.io.OutputStreamWriter;
import java.util.NoSuchElementException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.io.InputStream;

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

    static class FLongNumber {
        final int MOD = MiscUtils.MOD7;

        long parse(char[] str, int mod) {
            long res = 0;
            for (char c : str) {
                res = (10 * res + c - '0') % mod;
            }
            return res;
        }

        char[] subArray(char[] str, int begin, int end) {
            return (new String(str, begin, end - begin)).toCharArray();
        }

        long magic(long a, long len, long n7, long n6) {
            long q = IntegerUtils.power(10, len, MOD);
            if (q == 1) {
                throw new ArithmeticException();
            }
            long q2n = IntegerUtils.power(q, n6, MOD);
            long num = a * q2n % MOD * q % MOD + (1 - a) * q2n % MOD - (a + n7) * q % MOD + a + n7 - 1;
            num = IntegerUtils.trueMod(num, MOD);
            long den = IntegerUtils.trueMod((q - 1) * (q - 1), MOD);
            return num * IntegerUtils.reverse(den, MOD) % MOD;
        }

        Number interval(char[] A, char[] B) {
            long value = 0, pow10 = 1;
            for (int len = A.length; len <= B.length; len++) {
                long a7 = len == A.length ? parse(A, MOD) : IntegerUtils.power(10, len - 1, MOD);
                long a6 = len == A.length ? parse(A, MOD - 1) : IntegerUtils.power(10, len - 1, MOD - 1);
                long b7 = len == B.length ? parse(B, MOD) : (IntegerUtils.power(10, len, MOD) - 1 + MOD) % MOD;
                long b6 = len == B.length ? parse(B, MOD - 1) : (IntegerUtils.power(10, len, MOD - 1) + MOD - 2) % (MOD - 1);
                long n7 = (b7 - a7 + 1 + MOD) % MOD, n6 = (b6 - a6 + MOD) % (MOD - 1);
                long mult = IntegerUtils.power(10, len * n6, MOD);
                value = (value * mult % MOD + magic(a7, len, n7, n6)) % MOD;
                pow10 = pow10 * mult % MOD;
            }
            return new Number(value, pow10);
        }

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            char[] str = in.readString().toCharArray();
            IntList[] plus = new IntList[str.length + 1];
            Arrays.setAll(plus, i -> new IntArrayList());
            int deep = 0;
            for (int i = 0; i < str.length; i++) {
                if (str[i] == '(') {
                    deep++;
                } else if (str[i] == ')') {
                    deep--;
                } else if (str[i] == '+') {
                    plus[deep].add(i);
                }
            }
            long res = parseExpression(str, 0, str.length, plus, 0).value;
            out.printLine(res);
        }

        Number parseExpression(char[] str, int begin, int end, IntList[] plus, int height) {
            int idx = MiscUtils.binarySearchInt(0, plus[height].size(), i -> i == plus[height].size() || plus[height].get(i) >= begin);
            if (idx < plus[height].size() && plus[height].get(idx) < end) {
                int pos = plus[height].get(idx);
                return parseTerm(str, begin, pos, plus, height).concat(parseExpression(str, pos + 1, end, plus, height));
            }
            return parseTerm(str, begin, end, plus, height);
        }

        Number parseTerm(char[] str, int begin, int end, IntList[] plus, int height) {
            for (int i = begin; i < end; i++) {
                if (str[i] == '(') {
                    return parseExpression(str, i + 1, end - 1, plus, height + 1).exp(subArray(str, begin, i));
                }
            }
            for (int i = begin; i < end; i++) {
                if (str[i] == '-') {
                    return interval(subArray(str, begin, i), subArray(str, i + 1, end));
                }
            }
            return new Number(parse(subArray(str, begin, end), MOD), IntegerUtils.power(10, end - begin, MOD));
        }

        class Number {
            long value;
            long pow10;

            Number(char ch) {
                value = ch - '0';
                pow10 = 10;
            }

            Number(long value, long pow10) {
                this.value = value;
                this.pow10 = pow10;
            }

            Number concat(Number other) {
                return new Number((value * other.pow10 + other.value) % MOD, pow10 * other.pow10 % MOD);
            }

            Number exp(char[] n) {
                long ratio = pow10;
                long ratio2n = IntegerUtils.power(ratio, parse(n, MOD - 1), MOD);
                long ratio_1 = (ratio + MOD - 1) % MOD;
                if (ratio == 1) {
                    return new Number(value * parse(n, MOD), ratio2n);
                }
                long inv = IntegerUtils.reverse(ratio_1, MOD);
                return new Number(value * (ratio2n + MOD - 1) % MOD * inv % MOD, ratio2n);
            }

        }

    }

    static abstract class IntAbstractStream implements IntStream {
        public String toString() {
            StringBuilder builder = new StringBuilder();
            boolean first = true;
            for (IntIterator it = intIterator(); it.isValid(); it.advance()) {
                if (first) {
                    first = false;
                } else {
                    builder.append(' ');
                }
                builder.append(it.value());
            }
            return builder.toString();
        }

        public boolean equals(Object o) {
            if (!(o instanceof IntStream)) {
                return false;
            }
            IntStream c = (IntStream) o;
            IntIterator it = intIterator();
            IntIterator jt = c.intIterator();
            while (it.isValid() && jt.isValid()) {
                if (it.value() != jt.value()) {
                    return false;
                }
                it.advance();
                jt.advance();
            }
            return !it.isValid() && !jt.isValid();
        }

        public int hashCode() {
            int result = 0;
            for (IntIterator it = intIterator(); it.isValid(); it.advance()) {
                result *= 31;
                result += it.value();
            }
            return result;
        }

    }

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

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

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

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

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

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

        public interface SpaceCharFilter {
            boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

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

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

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

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

    }

    static interface IntStream extends Iterable<Integer>, Comparable<IntStream> {
        IntIterator intIterator();

        default Iterator<Integer> iterator() {
            return new Iterator<Integer>() {
                private IntIterator it = intIterator();

                public boolean hasNext() {
                    return it.isValid();
                }

                public Integer next() {
                    int result = it.value();
                    it.advance();
                    return result;
                }
            };
        }

        default int compareTo(IntStream c) {
            IntIterator it = intIterator();
            IntIterator jt = c.intIterator();
            while (it.isValid() && jt.isValid()) {
                int i = it.value();
                int j = jt.value();
                if (i < j) {
                    return -1;
                } else if (i > j) {
                    return 1;
                }
                it.advance();
                jt.advance();
            }
            if (it.isValid()) {
                return 1;
            }
            if (jt.isValid()) {
                return -1;
            }
            return 0;
        }

    }

    static interface IntFilter {
        public boolean accept(int value);

    }

    static interface IntReversableCollection extends IntCollection {
    }

    static interface IntList extends IntReversableCollection {
        public abstract int get(int index);

        public abstract void addAt(int index, int value);

        public abstract void removeAt(int index);

        default public IntIterator intIterator() {
            return new IntIterator() {
                private int at;
                private boolean removed;

                public int value() {
                    if (removed) {
                        throw new IllegalStateException();
                    }
                    return get(at);
                }

                public boolean advance() {
                    at++;
                    removed = false;
                    return isValid();
                }

                public boolean isValid() {
                    return !removed && at < size();
                }

                public void remove() {
                    removeAt(at);
                    at--;
                    removed = true;
                }
            };
        }

        default public void add(int value) {
            addAt(size(), value);
        }

    }

    static final class PrimitiveHashCalculator {
        private PrimitiveHashCalculator() {
        }

        public static int getHash(long x) {
            return (int) x ^ (int) (x >>> 32);
        }

    }

    static class IntArrayList extends IntAbstractStream implements IntList {
        private int size;
        private int[] data;

        public IntArrayList() {
            this(3);
        }

        public IntArrayList(int capacity) {
            data = new int[capacity];
        }

        public IntArrayList(IntCollection c) {
            this(c.size());
            addAll(c);
        }

        public IntArrayList(IntStream c) {
            this();
            if (c instanceof IntCollection) {
                ensureCapacity(((IntCollection) c).size());
            }
            addAll(c);
        }

        public IntArrayList(IntArrayList c) {
            size = c.size();
            data = c.data.clone();
        }

        public IntArrayList(int[] arr) {
            size = arr.length;
            data = arr.clone();
        }

        public int size() {
            return size;
        }

        public int get(int at) {
            if (at >= size) {
                throw new IndexOutOfBoundsException("at = " + at + ", size = " + size);
            }
            return data[at];
        }

        private void ensureCapacity(int capacity) {
            if (data.length >= capacity) {
                return;
            }
            capacity = Math.max(2 * data.length, capacity);
            data = Arrays.copyOf(data, capacity);
        }

        public void addAt(int index, int value) {
            ensureCapacity(size + 1);
            if (index > size || index < 0) {
                throw new IndexOutOfBoundsException("at = " + index + ", size = " + size);
            }
            if (index != size) {
                System.arraycopy(data, index, data, index + 1, size - index);
            }
            data[index] = value;
            size++;
        }

        public void removeAt(int index) {
            if (index >= size || index < 0) {
                throw new IndexOutOfBoundsException("at = " + index + ", size = " + size);
            }
            if (index != size - 1) {
                System.arraycopy(data, index + 1, data, index, size - index - 1);
            }
            size--;
        }

    }

    static class IntegerUtils {
        public static long trueMod(long a, long b) {
            a %= b;
            a += b;
            a %= b;
            return a;
        }

        public static long power(long base, long exponent, long mod) {
            if (base >= mod) {
                base %= mod;
            }
            if (exponent == 0) {
                return 1 % mod;
            }
            long result = power(base, exponent >> 1, mod);
            result = result * result % mod;
            if ((exponent & 1) != 0) {
                result = result * base % mod;
            }
            return result;
        }

        public static long reverse(long number, long modulo) {
            return trueMod(extGcd(number, modulo).first, modulo);
        }

        public static EzLongLongLongTriple extGcd(long a, long b) {
            long x2 = 1, y2 = 0, x1 = 0, y1 = 1, x, y, r2, r1, q, r;
            for (r2 = a, r1 = b; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y) {
                q = r2 / r1;
                r = r2 % r1;
                x = x2 - q * x1;
                y = y2 - q * y1;
            }
            return new EzLongLongLongTriple(x2, y2, r2);
        }

    }

    static class MiscUtils {
        public static final int MOD7 = (int) (1e9 + 7);

        public static int binarySearchInt(int from, int to, IntFilter function) {
            while (from < to) {
                int argument = from + ((to - from) >> 1);
                if (function.accept(argument)) {
                    to = argument;
                } else {
                    from = argument + 1;
                }
            }
            return from;
        }

    }

    static class EzLongLongLongTriple implements Comparable<EzLongLongLongTriple> {
        private static final int HASHCODE_INITIAL_VALUE = 0x811c9dc5;
        private static final int HASHCODE_MULTIPLIER = 0x01000193;
        public long first;
        public long second;
        public long third;

        public EzLongLongLongTriple(long first, long second, long third) {
            this.first = first;
            this.second = second;
            this.third = third;
        }

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

            return first == that.first && second == that.second && third == that.third;
        }

        public int hashCode() {
            int hash = HASHCODE_INITIAL_VALUE;
            hash = (hash ^ PrimitiveHashCalculator.getHash(first)) * HASHCODE_MULTIPLIER;
            hash = (hash ^ PrimitiveHashCalculator.getHash(second)) * HASHCODE_MULTIPLIER;
            hash = (hash ^ PrimitiveHashCalculator.getHash(third)) * HASHCODE_MULTIPLIER;
            return hash;
        }

        public int compareTo(EzLongLongLongTriple o) {
            int res = Long.compare(first, o.first);
            if (res == 0) {
                res = Long.compare(second, o.second);
                if (res == 0) {
                    res = Long.compare(third, o.third);
                }
            }
            return res;
        }

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

    }

    static interface IntIterator {
        public int value() throws NoSuchElementException;

        public boolean advance();

        public boolean isValid();

    }

    static interface IntCollection extends IntStream {
        public int size();

        default public void add(int value) {
            throw new UnsupportedOperationException();
        }

        default public IntCollection addAll(IntStream values) {
            for (IntIterator it = values.intIterator(); it.isValid(); it.advance()) {
                add(it.value());
            }
            return this;
        }

    }
}


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 = 10000000000.0;
        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;
        }
    }

}