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

public class E {

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

	int ansVal = -1;
	long ansCnt = 0;

	void updateAns(int val, long count) {
		if (count == 0) {
			return;
		}
		if (val > ansVal) {
			ansVal = val;
			ansCnt = count;
		} else if (val == ansVal) {
			ansCnt += count;
		}
	}

	static class Group {
		int val;
		int rep;

		public Group(int val, int rep) {
			this.val = val;
			this.rep = rep;
		}
	}

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

		List<Integer> aList = new ArrayList<>();
		List<Integer> bList = new ArrayList<>();

		int na, nb;

		for (int i = 0; i < m; i++) {
			int type = nextInt();
			int val = nextInt();
			(type == 0 ? aList : bList).add(val);
		}

		na = aList.size();
		nb = bList.size();

		Group[] a = makeGroups(aList);
		Group[] b = makeGroups(bList);

		solve1(a, na);
		solve1(b, nb);
		solve2(a, b, n, na, nb);
		solve2(b, a, n, na, nb);

		out.println(ansCnt);
	}

	Group[] makeGroups(List<Integer> a) {
		Collections.sort(a);
		List<Group> b = new ArrayList<>();
		for (int i = 0, j = -1; i < a.size(); i = j) {
			j = i;
			int st = a.get(i);
			while (j < a.size() && a.get(j).intValue() == st) {
				j++;
			}
			b.add(new Group(st, j - i));
		}
		return b.toArray(new Group[b.size()]);
	}

	void solve1(Group[] a, int realLen) {
		if (a.length == 0) {
			return;
		}
		int n = a.length;
		int val = a[n - 1].val - a[0].val;
		long count;
		if (a.length == 1) {
			count = (long) realLen * (realLen - 1) * (realLen - 2) / 6;
		} else {
			int pref = a[0].rep;
			int suff = a[n - 1].rep;

			count = (long) pref * (realLen - pref - suff) * suff + (long) pref
					* (pref - 1) / 2 * suff + (long) pref * suff * (suff - 1)
					/ 2;
		}
		updateAns(val, count);
	}

	long C2(int x) {
		return (long) x * (x - 1) / 2;
	}

	void solve2(Group[] a, Group[] b, int n, int realLenA, int realLenB) {
		int na = a.length;
		int nb = b.length;

		if (na == 0 || nb == 0) {
			return;
		}
		// j is last in b <= a[i]

		int totBNotMore = 0;
		int totBMore = realLenB;

		for (int i = 0, j = -1; i < na; i++) {
			while (j < nb - 1 && b[j + 1].val <= a[i].val) {
				j++;
				totBNotMore += b[j].rep;
				totBMore -= b[j].rep;
			}
			// both <=
			if (j >= 0) {
				int val = 2 * (b[j].val + n - a[i].val);
				long count = (long) a[i].rep
						* (C2(totBNotMore) - C2(totBNotMore - b[j].rep));
				updateAns(val, count);
			}

			// <= and >
			if (j >= 0 && j < nb - 1) {
				int val = 2 * n;
				long count = (long) a[i].rep * totBNotMore * totBMore;
				updateAns(val, count);
			}

			// both >
			if (j < nb - 1) {
				// System.err.println("?");
				int val = 2 * (-b[j + 1].val + n + a[i].val);
				long count = (long) a[i].rep
						* (C2(totBMore) - C2(totBMore - b[j + 1].rep));
				updateAns(val, count);
			}
		}
	}

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

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

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

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

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

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

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


import java.io.*;

public class Codeforces832E {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] sp = br.readLine().split(" ");
		int n = Integer.parseInt(sp[0]);
		int m = Integer.parseInt(sp[1]);
		int[][] matrix = new int[n][m];
		for (int i = 0; i < n; i++) {
			sp = br.readLine().split(" ");
			String s = sp[0];
			for (int j = 0; j < m; j++) {
				matrix[i][j] = (int) s.charAt(j) - 97;
			}
		}

		int counter = 0;
		int i = 0;
		while ((i < n) && (counter < m)) {
			if (matrix[i][counter] == 0) {
				int counter2 = -1;
				for (int j = i+1; j < n; j++) {
					if (matrix[j][counter] != 0) {
						counter2 = j;
					}
				}
				if (counter2 == -1)
					counter++;
				else {
					for (int k = counter; k < m; k++) {
						int temp = matrix[i][k];
						matrix[i][k] = matrix[counter2][k];
						matrix[counter2][k] = temp;
					}
				}
			}
			if ((counter < m) && (matrix[i][counter] != 0)) {
				for (int j = i+1; j < n; j++) {
					int z = matrix[j][counter];
					for (int k = counter; k < m; k++) {
						matrix[j][k] -= z*matrix[i][k]*matrix[i][counter]*matrix[i][counter]*matrix[i][counter];
						matrix[j][k] = (matrix[j][k]+2000)%5;
					}
				}
				i++;
				counter++;
			}
		}
		int asdf = i;

		int[] firstnonzero = new int[n];
		int counter2 = 0;
		for (i = 0; i < asdf; i++) {
			while (matrix[i][counter2] == 0)
				counter2++;
			firstnonzero[i] = counter2;
		}

		int val = 1;
		if (n > asdf)
			val = fivepower(n-asdf, 1000000007);
		sp = br.readLine().split(" ");
		int q = Integer.parseInt(sp[0]);
		for (i = 0; i < q; i++)	{
			sp = br.readLine().split(" ");
			String t = sp[0];
			int[] result = new int[m];
			for (int j = 0; j < m; j++) {
				result[j] = (int) t.charAt(j) - 97;
			}
			for (int k = 0; k < asdf; k++) {
				int u = result[firstnonzero[k]];
				for (int l = firstnonzero[k]; l < m; l++) {
					result[l] -= u*matrix[k][l]*matrix[k][firstnonzero[k]]*matrix[k][firstnonzero[k]]*matrix[k][firstnonzero[k]];
					result[l] = (result[l]+2000)%5;
				}
			}
			boolean bool = true;
			for (int j = 0; j < m; j++) {
				if (result[j] != 0)
					bool = false;
			}
			if (bool)
				System.out.println(val);
			else
				System.out.println(0);
		}

	}

	public static int fivepower(int n, int mod) {
		long a = 1;
		while (n > 0) {
			a *= 5;
			n --;
			a %= mod;
		}
		return (int) a;
	}
}


import java.io.*;

public class Codeforces832E {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] sp = br.readLine().split(" ");
		int n = Integer.parseInt(sp[0]);
		int m = Integer.parseInt(sp[1]);
		int[][] matrix = new int[n][m];
		for (int i = 0; i < n; i++) {
			sp = br.readLine().split(" ");
			String s = sp[0];
			for (int j = 0; j < m; j++) {
				matrix[i][j] = (int) s.charAt(j) - 97;
			}
		}

		int counter = 0;
		int i = 0;
		while ((i < n) && (counter < m)) {
			if (matrix[i][counter] == 0) {
				int counter2 = -1;
				for (int j = i+1; j < n; j++) {
					if (matrix[j][counter] != 0) {
						counter2 = j;
					}
				}
				if (counter2 == -1)
					counter++;
				else {
					for (int k = counter; k < m; k++) {
						int temp = matrix[i][k];
						matrix[i][k] = matrix[counter2][k];
						matrix[counter2][k] = temp;
					}
				}
			}
			if (matrix[i][counter] != 0) {
				for (int j = i+1; j < n; j++) {
					int z = matrix[j][counter];
					for (int k = counter; k < m; k++) {
						matrix[j][k] -= z*matrix[i][k]*matrix[i][counter]*matrix[i][counter]*matrix[i][counter];
						matrix[j][k] = (matrix[j][k]+2000)%5;
					}
				}
				i++;
				counter++;
			}
		}
		int asdf = i;
		for (i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				System.out.print(matrix[i][j] + " ");
			}
			System.out.println();
		}

		int[] firstnonzero = new int[n];
		int counter2 = 0;
		for (i = 0; i < asdf; i++) {
			while (matrix[i][counter2] == 0)
				counter2++;
			firstnonzero[i] = counter2;
		}

		int val = 1;
		if (n > asdf)
			val = fivepower(n-asdf, 1000000007);
		sp = br.readLine().split(" ");
		int q = Integer.parseInt(sp[0]);
		for (i = 0; i < q; i++)	{
			sp = br.readLine().split(" ");
			String t = sp[0];
			int[] result = new int[m];
			for (int j = 0; j < m; j++) {
				result[j] = (int) t.charAt(j) - 97;
			}
			for (int k = 0; k < asdf; k++) {
				int u = result[firstnonzero[k]];
				for (int l = firstnonzero[k]; l < m; l++) {
					result[l] -= u*matrix[k][l]*matrix[k][firstnonzero[k]]*matrix[k][firstnonzero[k]]*matrix[k][firstnonzero[k]];
					result[l] = (result[l]+2000)%5;
				}
			}
			boolean bool = true;
			for (int j = 0; j < m; j++) {
				if (result[j] != 0)
					bool = false;
			}
			if (bool)
				System.out.println(val);
			else
				System.out.println(0);
		}

	}

	public static int fivepower(int n, int mod) {
		long a = 5;
		while (n > 0) {
			if (n%2 == 1) {
				n /= 2;
				a = (5*a*a)%mod;
			}
			else {
				n /= 2;
				a = (a*a)%mod;
			}
		}
		return (int) a;
	}
}


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

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

	void solve()
	{
		int n = ni();
		int m = ni();
		char[][] ss = nm(n,m);
		int[][] M = new int[m][n];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < m;j++){
				M[j][i] = ss[i][j]-'a';
			}
		}
		Result res = rank(M, 5);
		int[][] o = res.v;
		int rank = res.rank;
		outer:
		for(int Q = ni();Q > 0;Q--){
			char[] ys = ns(m);
			int[] y = new int[m];
			for(int i = 0;i < m;i++)y[i] = ys[i]-'a';
			y = mul(o, y, 5);
			for(int i = rank;i < m;i++){
				if(y[i] != 0){
					out.println(0);
					continue outer;
				}
			}
			out.println(pow(5, n-rank, 1000000007));
		}
	}

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

	public static Result rank(int[][] M, int p)
	{
//		if(M.length == 0)return 0;
		int n = M.length, m = M[0].length;
		int[][] v = new int[n][n];
		for(int i = 0;i < n;i++)v[i][i] = 1;

		// Forward Elimination
		for(int i = 0;i < n;i++){
			// select pivot
			boolean pivotFound = false;
			out:
			for(int pi = i;pi < n;pi++){
				for(int pj = i;pj < m;pj++){
					if(M[pi][pj] != 0){
						// pivot found
						if(pj != i){
							// swap columns
							for(int k = 0;k < n;k++){
								int d = M[k][pj]; M[k][pj] = M[k][i]; M[k][i] = d;
							}
						}
						if(pi != i){
							// swap rows
							{int[] d = M[pi]; M[pi] = M[i]; M[i] = d;}
							{int[] d = v[pi]; v[pi] = v[i]; v[i] = d;}
						}
						pivotFound = true;
						break out;
					}
				}
			}
			if(!pivotFound){
				Result res = new Result();
				res.v = v;
				res.rank = i;
				return res;
			}

			long ID = invl(M[i][i], p);
			M[i][i] = 1;
			for(int j = i+1;j < m;j++){
				M[i][j] = (int)(M[i][j] * ID % p);
			}
			for(int j = 0;j < n;j++){
				v[i][j] = (int)(v[i][j] * ID % p);
			}

			for(int j = i+1;j < n;j++){
				long B = p-M[j][i];
				M[j][i] = 0;
				for(int k = i+1;k < m;k++){
					M[j][k] = (int)((M[j][k] + M[i][k] * B) % p);
				}
				for(int k = 0;k < n;k++){
					v[j][k] = (int)((v[j][k] + v[i][k] * B) % p);
				}
			}
		}
		Result res = new Result();
		res.v = v;
		res.rank = n;
		return res;
	}

	public static int[] mul(int[][] A, int[] v, int mod)
	{
		int m = A.length;
		int n = v.length;
		int[] w = new int[m];
		for(int i = 0;i < m;i++){
			long sum = 0;
			for(int k = 0;k < n;k++){
				sum += (long)A[i][k] * v[k];
				sum %= mod;
			}
			w[i] = (int)sum;
		}
		return w;
	}

	public static long invl(long a, long mod) {
		long b = mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}

	static class Result
	{
		public int[][] v;
		public int rank;
	};

	public static Result operateElementarily(int[][] M, int mod)
	{
		int n = M.length, m = M[0].length;
		int rank = n-1;
		int[][] v = new int[n][n];
		for(int i = 0;i < n;i++)v[i][i] = 1;

		// Forward Elimination
		for(int i = 0;i < n;i++){
			// select pivot
			int maxj = -1;
			for(int j = i;j < n;j++){
				if(M[j][i] != 0){
					maxj = j;
					break;
				}
			}
			if(maxj == -1){
				rank = i-1;
				break;
			}
			if(maxj != i){
				int[] dum = M[i]; M[i] = M[maxj]; M[maxj] = dum;
				int[] du = v[i]; v[i] = v[maxj]; v[maxj] = du;
			}

			long ID = invl(M[i][i], mod);
			M[i][i] = 1;
			for(int j = i+1;j < m;j++){
				M[i][j] = (int)(M[i][j] * ID % mod);
			}
			for(int j = 0;j < n;j++){
				v[i][j] = (int)(v[i][j] * ID % mod);
			}

			for(int j = i+1;j < n;j++){
				long B = mod-M[j][i];
				M[j][i] = 0;
				for(int k = i+1;k < m;k++){
					M[j][k] = (int)((M[j][k] + M[i][k] * B) % mod);
				}
				for(int k = 0;k < n;k++){
					v[j][k] = (int)((v[j][k] + v[i][k] * B) % mod);
				}
			}
		}

		// Back Substitution
		for(int i = rank;i >= 0;i--){
			for(int j = rank;j >= i+1;j--){
				long B = mod-M[i][j];
				M[i][j] = 0;
				for(int k = rank+1;k < m;k++){
					M[i][k] = (int)((M[i][k] + M[j][k] * B) % mod);
				}
				for(int k = 0;k < n;k++){
					v[i][k] = (int)((v[i][k] + v[j][k] * B) % mod);
				}
			}
		}

		Result ret = new Result();
		ret.v = v;
		ret.rank = rank+1;
		return ret;
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;

public class Codeforces832E {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] sp = br.readLine().split(" ");
		int n = Integer.parseInt(sp[0]);
		int m = Integer.parseInt(sp[1]);
		int[][] matrix = new int[n][m];
		for (int i = 0; i < n; i++) {
			sp = br.readLine().split(" ");
			String s = sp[0];
			for (int j = 0; j < m; j++) {
				matrix[i][j] = (int) s.charAt(j) - 97;
			}
		}

		int counter = 0;
		int i = 0;
		while ((i < n) && (counter < m)) {
			if (matrix[i][counter] == 0) {
				int counter2 = -1;
				for (int j = i+1; j < n; j++) {
					if (matrix[j][counter] != 0) {
						counter2 = j;
					}
				}
				if (counter2 == -1)
					counter++;
				else {
					for (int k = counter; k < m; k++) {
						int temp = matrix[i][k];
						matrix[i][k] = matrix[counter2][k];
						matrix[counter2][k] = temp;
					}
				}
			}
			if (matrix[i][counter] != 0) {
				for (int j = i+1; j < n; j++) {
					int z = matrix[j][counter];
					for (int k = counter; k < m; k++) {
						matrix[j][k] -= z*matrix[i][k]*matrix[i][counter]*matrix[i][counter]*matrix[i][counter];
						matrix[j][k] = (matrix[j][k]+2000)%5;
					}
				}
				i++;
				counter++;
			}
		}
		int asdf = i;

		int[] firstnonzero = new int[n];
		int counter2 = 0;
		for (i = 0; i < asdf; i++) {
			while (matrix[i][counter2] == 0)
				counter2++;
			firstnonzero[i] = counter2;
		}

		int val = 1;
		if (n > asdf)
			val = fivepower(n-asdf, 1000000007);
		sp = br.readLine().split(" ");
		int q = Integer.parseInt(sp[0]);
		for (i = 0; i < q; i++)	{
			sp = br.readLine().split(" ");
			String t = sp[0];
			int[] result = new int[m];
			for (int j = 0; j < m; j++) {
				result[j] = (int) t.charAt(j) - 97;
			}
			for (int k = 0; k < asdf; k++) {
				int u = result[firstnonzero[k]];
				for (int l = firstnonzero[k]; l < m; l++) {
					result[l] -= u*matrix[k][l]*matrix[k][firstnonzero[k]]*matrix[k][firstnonzero[k]]*matrix[k][firstnonzero[k]];
					result[l] = (result[l]+2000)%5;
				}
			}
			boolean bool = true;
			for (int j = 0; j < m; j++) {
				if (result[j] != 0)
					bool = false;
			}
			if (bool)
				System.out.println(val);
			else
				System.out.println(0);
		}

	}

	public static int fivepower(int n, int mod) {
		long a = 5;
		while (n > 0) {
			if (n%2 == 1) {
				n /= 2;
				a = (5*a*a)%mod;
			}
			else {
				n /= 2;
				a = (a*a)%mod;
			}
		}
		return (int) a;
	}
}


import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;

/**
 *
 * @author Darkhan
 */
public class task4 {
    static int[] a, b, ar;
    static int n, d;
    static long x;
    static ArrayList<Integer> bset = new ArrayList<>();
    static TreeSet<Integer> aset = new TreeSet<>();
    public static void main (String[] args){
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n = in.nextInt();
        d = in.nextInt();
        x = in.nextLong();
        a = new int[n];
        b = new int[n];
        ar = new int[n+1];
        initAB();
        Iterator<Integer> it;
        long t;
        if (d < 3000){
            for (int i=0;i<n;i++){
                if (b[i] == 1) bset.add(i);
                t = 0;
                for (Integer bset1 : bset) {
                    t = Math.max(t, a[i - bset1]);
                }
                out.println(t);
            }
        }
        else{
            int val;
            for (int i=0;i<n;i++){
                t = 0;
                aset.add(a[i]);
                it = aset.descendingIterator();
                while(it.hasNext()){
                    val = it.next();
                    if (b[i-ar[val]] == 0) continue;
                    t = val;
                    break;
                }
                out.println(t);
            }
        }
        out.close();
    }
    public static long getNextX() {
        x = (x * 37 + 10007) % 1000000007;
        return x;
    }
    public static void initAB() {
        for(int i = 0; i < n; i = i + 1){
            a[i] = i + 1;
            ar[i+1] = i;
        }
        for(int i = 0; i < n; i = i + 1){
            int t = (int)(getNextX() % (i + 1));
            ar[a[i]] = t;
            ar[a[t]] = i;
            swap(a, i, t);
        }
        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, (int)(getNextX() % (i + 1)));
        }
    }
    public static void swap(int[] a, int i, int j){
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;

/**
 *
 * @author Darkhan
 */
public class task4 {
    static int[] a, b, ar;
    static int n, d;
    static long x;
    static ArrayList<Integer> bset = new ArrayList<>();
    static TreeSet<Integer> aset = new TreeSet<>();
    public static void main (String[] args){
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n = in.nextInt();
        d = in.nextInt();
        x = in.nextLong();
        a = new int[n];
        b = new int[n];
        ar = new int[n+1];
        initAB();
        Iterator<Integer> it;
        long t;
        if (d < 3000){
            for (int i=0;i<n;i++){
                if (b[i] == 1) bset.add(i);
                t = 0;
                for (Integer bset1 : bset) {
                    t = Math.max(t, a[i - bset1]);
                }
                out.println(t);
            }
        }
        else{
            int val;
            for (int i=0;i<n;i++){
                t = 0;
                aset.add(a[i]);
                it = aset.descendingIterator();
                while(it.hasNext()){
                    val = it.next();
                    if (b[i-ar[val]] == 0) continue;
                    t = val;
                    break;
                }
                out.println(t);
            }
        }
    }
    public static long getNextX() {
        x = (x * 37 + 10007) % 1000000007;
        return x;
    }
    public static void initAB() {
        for(int i = 0; i < n; i = i + 1){
            a[i] = i + 1;
            ar[i+1] = i;
        }
        for(int i = 0; i < n; i = i + 1){
            int t = (int)(getNextX() % (i + 1));
            ar[a[i]] = t;
            ar[a[t]] = i;
            swap(a, i, t);
        }
        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, (int)(getNextX() % (i + 1)));
        }
    }
    public static void swap(int[] a, int i, int j){
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.util.Scanner;

/**
 *
 * @author Darkhan
 */
public class task4 {
    static int[] a, b, br = new int[100000];
    static int n, d;
    static long x;
    public static void main (String[] args){
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        d = in.nextInt();
        x = in.nextLong();
        a = new int[n];
        b = new int[n];
        initAB();
        long t;
        for (int i=0;i<n;i++){
            t = 0;
            for (int j=1;j<=br[0];j++){
                if (br[j] > i) break;
                t = Math.max(t, a[i-br[j]]);
            }
            System.out.println(t);
        }
    }
    public static long getNextX() {
        x = (x * 37 + 10007) % 1000000007;
        return x;
    }
    public static 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, (int)(getNextX() % (i + 1)));
        }
        for(int i = 0; i < n; i = i + 1){
            if (i < d){
                b[i] = 1;
                br[++br[0]] = i;
            }
            else
                b[i] = 0;
        }
        for(int i = 0; i < n; i = i + 1){
            swap(b, i, (int)(getNextX() % (i + 1)));
        }
    }
    public static void swap(int[] a, int i, int j){
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}


import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.TreeSet;

public class Snippet {
    static long x;
    static int n, d;
    static int[] a;
    static int[] b;
    static long  getNextX() {
        x = (x * 37 + 10007) % 1000000007;
        return x;
    }
    static void  initAB() {
        int i;
        for(i = 0; i < n; i = i + 1){
            a[i] = i+1;
        }
        for(i = 0; i < n; i = i + 1){
            swap(a, i,  (int)getNextX() % (i + 1) );
        }
        for(i = 0; i < n; i = i + 1){
            if (i < d)
                b[i] = 1;
            else
                b[i] = 0;
        }
        for(i = 0; i < n; i = i + 1){
            swap(b, i,  (int)getNextX() % (i + 1) );
        }
    }
    static void  swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n = sc.nextInt();
        d = sc.nextInt();
        x = sc.nextLong();

        a = new int[n];
        b = new int[n];
        initAB();

        List<Integer> b1 = new ArrayList<Integer>();
        if (d < 1000) {
            for (int i =0; i < n; ++i) {
                int c = 0;
                if (b[i] == 1) b1.add(i);
                for (int j = 0;  j < b1.size(); ++j) {
                    c = Math.max(c, a[i - b1.get(j)]);
                }
                out.println(c);
            }
        } else {
            int[] arr = new int[n + 1];
            for (int i = 0; i < n; ++i) arr[a[i]] = i;
            TreeSet<Integer> set = new TreeSet<Integer>();
            label:
                for (int i = 0; i < n; ++i) {
                    set.add(-a[i]);
                    for (int k : set) {
                        int j = arr[-k];
                        if (b[i - j] == 1) {
                            out.println(-k);
                            continue label;
                        }
                    }
                    out.println(0);
                }
        }

    }
    public static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;

public class Div2_287 {
	public static int n,k,m;
	public static long[] possibilties ;
	public static long[] tens;
	public static long[][][] memo;

	public static long rec(int i,long mod,int l){
		if(mod==0 && l>0){
			return memo[i][(int) mod][l]= possibilties[i]%m;
		}
		if(i==0 ){
			return 0;
		}

//
		if( memo[i][(int) mod][l]!=-1 )
			return memo[i][(int) mod][l]%m;
//
		long ways=0;

		for(int j=0;j<10;j++){

			long curr = ( (j)%k * (tens[n-i])%k )%k;
			ways = (ways%m + rec(i-1 , (mod %k+ curr%k) %k , j)%m)%m;

		}

		return memo[i][(int) mod][l]=ways%m;
	}

	public static void main(String[] args)throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] in=br.readLine().split(" ");
		n=Integer.parseInt(in[0]);
		k=Integer.parseInt(in[1]);
		m=Integer.parseInt(in[2]);
		possibilties = new long[n+5];
		tens = new long[n+5];

		possibilties[0]=1;

		for(int i=1;i<=n;i++){
			possibilties[i]=9;
			for(int j=1;j<i;j++){
				possibilties[i]=( possibilties[i]%m * 10%m )%m;
			}
		}

		tens[0]=1;
		for(int i=1;i<=n;i++){
			tens[i]=(tens[i-1]%k*10%k)%k;
		}

		memo = new long[n+10][k+10][10];

		for(int i=0;i<n+10;i++)
			for(int j=0;j<k+10;j++)
				for(int k=0;k<10;k++)
					memo[i][j][k]=-1;

		System.out.println(rec(n,0,0));
	}
}


package Div2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

public class Sketch {
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int k = input.nextInt();
		int m = input.nextInt();
		input.close();

		int[][] counts = new int[n][k];
		int[] mods = new int[n];

		int x = 1;
		for(int i=0; i<n; i++){
			mods[i] = x % k;
			x *= 10;
			x %= k;
		}

		for(int i=0; i<n; i++){
			for(int j=1; j<10; j++)
				counts[i][j*mods[i]%k]++;
		}

		int[][] sums = new int[n][k];
		for(int j=0; j<10; j++)
			sums[0][j%k] = counts[0][j%k];

		for(int i=1; i<n; i++){
			for(int j=1; j<k; j++){
				for(int l=1; l<10; l++){
					counts[i][(j+l*mods[i])%k] = (sums[i-1][j] + counts[i][(j+l*mods[i])%k]) % m;
				}
			}
			for(int j=0; j<k; j++){
				sums[i][j] = (sums[i-1][j] + counts[i][j]) % m;
			}
		}

		long total = 0;
		long[] multi = new long[n];
		long y = 1;
		for(int i=0; i<n; i++){
			multi[i] = y % m;
			y *= 10;
			y %= m;
		}

		total = counts[n-1][0] % m;
		for(int i=0; i<n-1; i++){
			total += ((long)counts[i][0] * 9 * multi[n-2-i]) % m;
			total = total % m;
		}

		System.out.println(total);
	}
}


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

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

    static class TaskD {
        static int N;
        static int K;
        static int MOD;
        static int memo;
        static int[] pow10;

        static int dp(int reached, int modSoFar, int idx) {
            if (idx == N) return reached;
            if (memo[reached][modSoFar][idx] != -1)
                return memo[reached][modSoFar][idx];

            int res = 0;
            for (int put = idx == N - 1 ? 1 : 0; put <= 9; put++) {
                int nxtMod = (pow10[idx] * put + modSoFar) % K;
                int nxtReached = reached == 1 || (put != 0 && nxtMod == 0) ? 1 : 0;
                res += dp(nxtReached, nxtMod, idx + 1);
                if (res >= MOD) res -= MOD;
            }
            return memo[reached][modSoFar][idx] = res;
        }

        public void solve(int testNumber, Scanner sc, PrintWriter out) {
            N = sc.nextInt();
            K = sc.nextInt();
            MOD = sc.nextInt();
            pow10 = new int[N];
            pow10[0] = 1;
            for (int i = 1; i < N; i++)
                pow10[i] = (int) (10L * pow10[i - 1] % K);
            memo = new int[2][K + 1][N + 1];
            for (int[][] mm : memo) for (int[] m : mm) Arrays.fill(m, -1);
            out.println(dp(0, 0, 0));
        }

    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

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

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

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

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

    }
}


import java.util.*;
import java.util.Map.Entry;

public class D {

	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);

		long n = scan.nextInt();
		long k = scan.nextInt();
		long m = scan.nextInt();

		//long n = 5;
		//long k = 3;
		//long m = 1103;

		long[][] dp = new long[(int)m][(int)k];

		for (int i = 1; i<10; i++) {
			int ind = (int)(i%k);
			dp[0][ind] += 1;
			dp[0][ind] %= m;
		}

		long mult = 1;
		for (int i = 1; i<n; i++) {
			mult *= 10;
			mult %= k;
			for (int j = 1; j<10; j++) {
				long add = j*mult;
				add %= k;
				for (int a = 1; a<k; a++) {
					int ind = (int)((a+add)%k);
					dp[i][ind] += dp[i-1][a];
					dp[i][ind] %= m;
					for (int b = 2; b<=i; b++) {
						dp[i][ind] += dp[i-b][a];
						dp[i][ind] %= m;
					}
				}

				dp[i][(int)add]++;
			}
			//dp[i][0] += 9*dp[i-1][0];
			//long mult2 = 1;
			//for (int j = 1; j<=i; j++) {
			//	dp[i][0] += 9*mult2*dp[i-j][0];
			//	mult2*=10;
			//}
			//System.out.println(dp[i][0] + " " + dp[i][1] + " " + dp[i][2]);
		}
		//System.out.println();
		long tot = 0;
		long mult2 = 9;
		for (int i = (int)n-2; i>=0; i--) {
			//System.out.println(i + " " + dp[i][0] + " " + dp[i][0]%m);
			tot += dp[i][0]*mult2;
			tot %= m;
			mult2 *= 10;
			mult2 %= m;
		}
		tot += dp[(int)n-1][0];
		tot %= m;
		//System.out.println("\n" + tot);
		System.out.println(tot);
		//System.out.println();
		//test(5,3,1103);

		scan.close();
	}

	public static void test(int n, int k, int m) {

		int s = 1;
		int e = 10;
		for (int i = 1; i<n; i++) {
			s*=10;
			e*=10;
		}

		long tot = 0;

		int ten = e;
		for (int x = s; x<e; x++) {
			ten = e;
			int xx = x;
			//System.out.print(x + " ");
			boolean good = false;
			for (int i = 0; i<n; i++) {
				ten/=10;
				if (xx%k == 0) {
					good = true;
					break;
					//System.out.print(xx);
				} else {
					//for (int j = 0; j<n-i; j++)
						//System.out.print("-");
				}
				//System.out.print(" ");
				xx%=ten;
				if (xx == 0)
					break;
			}
			if (good) {
				//System.out.println(x);
				tot++;
			}

			//System.out.println();
		}
		System.out.println(tot);
	}
}


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

public class Main implements Runnable {

	public void _main() throws IOException {
		int n = nextInt();
		char[] s = (next() + '#').toCharArray();
		BigInteger[][] d = new BigInteger[n + 1][n + 1];
		for (BigInteger[] arr : d)
			Arrays.fill(arr, BigInteger.ZERO);
		char[][] move = new char[n + 1][n + 1];
		for (int i = 0; i <= n; i++)
			for (int j = 0; j <= n; j++) {
				BigInteger digit = BigInteger.valueOf(s[i + j] - '0');
				if (i < n) {
					BigInteger z = d[i][j].add(BigInteger.TEN.pow(n - i - 1).multiply(digit));
					if (d[i + 1][j].compareTo(z) < 0) {
						d[i + 1][j] = z;
						move[i + 1][j] = 'H';
					}
				}
				if (j < n) {
					BigInteger z = d[i][j].add(BigInteger.TEN.pow(n - j - 1).multiply(digit));
					if (d[i][j + 1].compareTo(z) < 0) {
						d[i][j + 1] = z;
						move[i][j + 1] = 'M';
					}
				}
			}
		StringBuilder res = new StringBuilder();
		int i = n, j = n;
		while (i > 0 || j > 0) {
			res.append(move[i][j]);
			if (move[i][j] == 'H')
				--i;
			else
				--j;
		}
		out.print(res.reverse());
	}

	private BufferedReader in;
	private PrintWriter out;
	private StringTokenizer st;

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

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

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

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

	public static void main(String[] args) {
		Locale.setDefault(Locale.UK);
		new Thread(new Main()).start();
	}

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

			_main();

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

}


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

import static java.lang.Math.*;

public class Solution {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer st;

    int n;
    int[] v;

    long[][] dp;
    long[] pow;

    String[][] pred;

    void solve() throws IOException {
        pow = new long[18];
        pow[0] = 1;
        for (int i = 1; i < pow.length; ++i)
            pow[i] = pow[i - 1] * 10L;
        n = ni();
        v = new int[2 * n];
        dp = new long[2 * n + 1][n + 1];
        pred = new String[2 * n + 1][n + 1];
        for (int i = 0; i < pred.length; i++) {
            Arrays.fill(pred[i], "");
        }
        int p = 0;
        for (char c : ns().toCharArray())
            v[p++] = c - '0';
        for (int i = 0; i < 2 * n; ++i)
            for (int j = 0; j <= n; ++j) {
                if (j < n) {
                    long a = dp[i][j] + pow[n - j - 1] * v[i];
                    if (a > dp[i + 1][j + 1]) {
                        dp[i + 1][j + 1] = a;
                        pred[i + 1][j + 1] = pred[i][j] + "H";
                    }
                }
                if (i - j < n && i - j >= 0) {
                    long a = dp[i][j] + pow[n - (i - j) - 1] * v[i];
                    if (a > dp[i + 1][j]) {
                        dp[i + 1][j] = a;
                        pred[i + 1][j] = pred[i][j] + "M";
                    }

                }
            }
        out.println(pred[2 * n][n]);
    }

    public Solution() throws IOException {
        Locale.setDefault(Locale.US);
        in = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        solve();
        in.close();
        out.close();
    }

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

    int ni() throws IOException {
        return Integer.valueOf(ns());
    }

    long nl() throws IOException {
        return Long.valueOf(ns());
    }

    double nd() throws IOException {
        return Double.valueOf(ns());
    }

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


import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class Solution implements Runnable {

	public static void main(String[] args) {
		(new Thread(new Solution())).start();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

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

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

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

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

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

	void solve() throws Exception {
		int n = nextInt();
		String s = nextToken();
		long[][] d = new long[n + 1][n + 1];
		int[][] r = new int[n + 1][n + 1];
		long[] pw = new long[n + 1];
		pw[0] = 1;
		for (int i = 1; i <= n; i++) pw[i] = pw[i - 1] * 10;
		for (int i = 0; i <= n; i++) {
			for (int j = 0; j <= n; j++) {
				if (i > 0 && d[i][j] < d[i - 1][j] + (s.charAt(i + j - 1) - '0') * pw[n - i]) {
					d[i][j] = d[i - 1][j] + (s.charAt(i + j - 1) - '0') * pw[n - i];
					r[i][j] = 1;
				}
				if (j > 0 && d[i][j] < d[i][j - 1] + (s.charAt(i + j - 1) - '0') * pw[n - j]) {
					d[i][j] = d[i][j - 1] + (s.charAt(i + j - 1) - '0') * pw[n - j];
					r[i][j] = 2;
				}
			}
		}
		String ans = "";
		int i = n;
		int j = n;
		while (i != 0 || j != 0) {
			if (r[i][j] == 1) {
				ans = 'H' + ans;
				i--;
			} else {
				ans = 'M' + ans;
				j--;
			}
		}
		out.println(ans);
	}

	public void run() {
		try {
			Locale.setDefault(Locale.US);
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
//			in = new BufferedReader(new FileReader(new File("input.txt")));
//			out = new PrintWriter("output.txt");
			solve();
		} catch (Exception e) {
			e.printStackTrace();
		}
		out.flush();
	}

}


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

import com.google.common.base.Joiner;

public class E_TVGame {

    /**
     * 3:03
     */
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); sc.nextLine();
        String line = sc.nextLine();

        int[] nums = new int[n*2];
        for (int i = 0; i < n*2; i++) {
            nums[i] = Integer.parseInt(line.substring(i, i+1));
        }

        long[][] d = new long[n+1][n+1];
        d[0][0] = 0;

        boolean[][] ups = new boolean[n+1][n+1];

        for (int i = 0; i < n+1; i++) {
            for (int j = 0; j < n+1; j++) {
                if(i==0&&j==0) continue;
                int p = nums[n*2-(i+j)];
                boolean up = true;
                if(i>0) d[i][j] = Math.max(d[i-1][j]+p*pow10(i-1), d[i][j]);
                if(j>0){
                    if(d[i][j-1]+p*pow10(j-1) > d[i][j]) up = false;
                    d[i][j] = Math.max(d[i][j-1]+p*pow10(j-1), d[i][j]);
                }
                ups[i][j] = up;
            }
        }

//      for (int i = 0; i < n+1; i++) {
//          StringBuilder sb = new StringBuilder();
//          for (int j = 0; j < n+1; j++) {
//              sb.append(d[i][j]);
//              if(j < n) sb.append('\t');
//          }
//          System.out.println(sb.toString());
//      }

        int curi = n, curj = n;
        String ret = "";
        for (int i = 0; i < n*2; i++) {
            if(curj == 0 || ups[curi][curj]){
                ret += 'H';
                curi--;
            }else{
                ret += 'M';
                curj--;
            }
        }

        System.out.println(ret);

    }

    private static long pow10(int a){
        if(a == 0) return 1;
        return 10L * pow10(a-1);

    }

}


import java.util.Scanner;

public class Main {
    static boolean f = false, flag = false;

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

        String s = scan.next();
        char[] sArray = s.toCharArray();
        if (sArray.length <= 100) {

            if (sArray.length % 2 != 0) {
                for (int i = sArray.length / 2; i < sArray.length; i++) {
                    for (int y = 0; y < i + 1; y++) {
                        a = a + sArray[y];
                    }
                    for (int y = sArray.length - i - 1; y < sArray.length; y++) {
                        c = c + sArray[y];
                    }
                    if (a.equals(c)) {
                        f = true;
                        break;
                    }
                    a = "";
                    c = "";
                }
            }
            if (sArray.length % 2 == 0) {
                for (int i = sArray.length / 2; i < sArray.length - 1; i++) {
                    for (int y = 0; y < i; y++) {
                        c = c + sArray[y];
                        a = sArray[sArray.length - 1 - y] + a;
                        if (a.equals(c)) {
                            f = true;
                            break;
                        }
                        a = "";
                        c = "";

                    }
                }
                }

                {
                    String m = c;
                    c = "";
                    a = "";
                    for (int y = sArray.length / 2; y < sArray.length; y++) {
                        c = c + sArray[y];
                        a = sArray[sArray.length - 1 - y] + a;

                    }
                    if (a.equals(c)) {
                        flag = true;

                    }
                    if ((!f && !flag) || (!f && flag)) {
                        System.out.print("NO");
                    }
                    if ((f) || (f && !flag)) {
                        System.out.print("YES\n" + m);

                    }
                }

        }
    }
}

/*
                        }*/


import java.util.Scanner;

public class Main {
   static boolean f = false;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String a = "", c = "";

        String s = scan.next();
        char[] sArray = s.toCharArray();
        if (sArray.length < 100) {

                if (sArray.length % 2 != 0) {
                    for (int i = sArray.length / 2 + 1; i < sArray.length; i++) {
                        for (int y = 0; y < i; y++) {
                            c = c + sArray[y];
                            a = sArray[sArray.length - 1 - y] + a;
                        }
                        if (a.equals(c)) {
                            f = true;
                            System.out.print("YES\n" + c);
                            break;
                        }
                    }
                }
                if (sArray.length % 2 == 0) {
                    for (int i = sArray.length / 2; i < sArray.length; i++) {
                        for (int y = 0; y < i; y++) {
                            c = c + sArray[y];
                            a = sArray[sArray.length - 1 - y] + a;
                        }
                        if (a.equals(c)) {
                            f = true;
                            System.out.print("YES\n" + c);
                            break;
                        }
                    }

                }
                if (!f) {
                    c = "";
                    a = "";
                    for (int y = sArray.length / 2; y < sArray.length; y++) {
                        c = c + sArray[y];
                        a = sArray[sArray.length - 1 - y] + a;

                    }
                    if (a.equals(c)) {
                        f = true;
                        System.out.print("NO");
                    }

                    System.out.print("NO");
                }
            }
        }
    }


import java.util.Scanner;

public class Main {
   static boolean f = false,flag = false;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String a = "", c = "";

        String s = scan.next();
        char[] sArray = s.toCharArray();
        if (sArray.length <= 100) {

                if (sArray.length % 2 != 0) {
                    for (int i = sArray.length / 2 ; i < sArray.length; i++) {
                        for (int y = 0; y < i + 1; y++) {
                            a = a + sArray[y];
                        }
                        for (int y = sArray.length - i - 1; y < sArray.length ;y++){
                            c = c + sArray[y];
                        }
                        if (a.equals(c)) {
                            f = true;
                            break;
                        }
                        a ="";
                        c = "";
                    }
                }
                if (sArray.length % 2 == 0) {
                    for (int i = sArray.length / 2 ; i < sArray.length - 1 ; i++) {
                            for (int y = 0; y < i + 1; y++) {
                                a = a + sArray[y];
                            }
                            for (int y = sArray.length - i - 1; y < sArray.length ;y++){
                                c = c + sArray[y];
                            }
                        if (a.equals(c)) {
                            f = true;break;
                        }
                        a = "";
                        c = "";

                    }

                }

                 {
                  String m = c;
                    c = "";
                    a = "";
                    for (int y = sArray.length / 2; y < sArray.length; y++) {
                        c = c + sArray[y];
                        a = sArray[sArray.length - 1 - y] + a;

                    }
                    if (a.equals(c)) {
                        flag = true;

                    }
                    if ((!f && !flag) || (!f && flag)){
                        System.out.print("NO");
                    }
                     if ((f) || (f && !flag)){
                         System.out.print("YES\n" + m);

                     }
                }
            }
        }
    }

/*  for (int y = 0; y < i; y++) {
                            c = c + sArray[y];
                            a = sArray[sArray.length - 1 - y] + a;
                        }*/


import java.util.Scanner;

public class Main {
   static boolean f = false,flag = false;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String a = "", c = "";

        String s = scan.next();
        char[] sArray = s.toCharArray();
        if (sArray.length < 100) {

                if (sArray.length % 2 != 0) {
                    for (int i = sArray.length / 2 + 1; i < sArray.length; i++) {
                        for (int y = 0; y < i; y++) {
                            c = c + sArray[y];
                            a = sArray[sArray.length - 1 - y] + a;
                        }
                        if (a.equals(c)) {
                            f = true;
                            break;
                        }
                    }
                }
                if (sArray.length % 2 == 0) {
                    for (int i = sArray.length / 2 ; i < sArray.length; i++) {
                        for (int y = 0; y < i; y++) {
                            a = sArray[sArray.length - 1 - y] + a;
                            c = c + sArray[y];

                        }
                        if (a.equals(c)) {
                            f = true;break;
                        }

                    }

                }

                 {
                  String m = c;
                    c = "";
                    a = "";
                    for (int y = sArray.length / 2; y < sArray.length; y++) {
                        c = c + sArray[y];
                        a = sArray[sArray.length - 1 - y] + a;

                    }
                    if (a.equals(c)) {
                        flag = true;

                    }
                    if ((!f && !flag) || (!f && flag)){
                        System.out.print("NO");
                    }
                     if ((f) || (f && !flag)){
                         System.out.print("YES\n" + m);

                     }
                }
            }
        }
    }


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

// you can compare with output.txt and expected out
public class Round803G {
	MyPrintWriter out;
	MyScanner in;

//	final static long FIXED_RANDOM;
//	static {
//		FIXED_RANDOM = System.currentTimeMillis();
//	}
	final static String IMPOSSIBLE = "IMPOSSIBLE";
	final static String POSSIBLE = "POSSIBLE";
	final static String YES = "YES";
	final static String NO = "NO";

    private void initIO(boolean isFileIO) {
        if (System.getProperty("ONLINE_JUDGE") == null && isFileIO) {
        	try{
	            in = new MyScanner(new FileInputStream("input.txt"));
	            out = new MyPrintWriter(new FileOutputStream("output.txt"));
        	}
        	catch(FileNotFoundException e){
        		e.printStackTrace();
        	}
        }
        else{
    		in = new MyScanner(System.in);
    	    out = new MyPrintWriter(new BufferedOutputStream(System.out));
        }
    }

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

		Round803G sol = new Round803G();
		sol.run();
    }

	private void run() {
		boolean isDebug = false;
		boolean isFileIO = true;
		boolean hasMultipleTests = false;

		initIO(isFileIO);

		// test();

		int t = hasMultipleTests? in.nextInt() : 1;

	    for (int i = 1; i <= t; ++i) {
	    	String s = in.next();

	    	if(isDebug){
		    	out.printf("Test %d\n", i);
	    	}

			long[] ans = solve(s);
			out.printlnAns(ans);

			if(isDebug)
				out.flush();
	    }

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

	private void test() {

		long mod = 1<<32;
		long temp;
		long temp2;

		temp = divide(9, 3); // x^3+1, x+1
		temp2 = multiply(3, temp, mod); // (x^2+x+1)(x+1) = x^3+1
		temp = divide(26, 25); // x^4 + x^3 + x, x^4 + x^3 + 1
		temp2 = multiply(25, temp, mod);
		temp = divide(52, 17); // x^5 + x^4 + x^2, x^4 + 1
		temp2 = multiply(17, temp, mod);

		// https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example_2
		mod = (1<<8) + (1<<4) + (1<<3) + (1<<1) + 1;
		long a = (1<<6) + (1<<4) + (1<<1) + 1;

		long[] res = extendedEuclid(a, mod, mod);
		long ainv = res[0];
		if(Long.highestOneBit(ainv) == Long.highestOneBit(mod))
			ainv ^= mod;

		temp = multiply(a, ainv, mod); // checked

	}

	private int[] bruteForce(String s) {
		BigInteger n = new BigInteger(reverse(s), 2);
		BigInteger base = new BigInteger(reverse(s), 2);

		int p = n.getLowestSetBit();
		if(p == -1) // or |t| > 10^100
			return new int[] {-1};

		n = n.flipBit(p);
		if(n.equals(BigInteger.valueOf(0)))
			return new int[] {p+1, p+2};

		while(n.getLowestSetBit() != n.bitLength()-1) {
			n = n.xor(base.shiftLeft(n.getLowestSetBit()-p));
		}
		int q = n.getLowestSetBit();

		return new int[] {p+1, q+1};
	}

	String reverse(String s) {
		StringBuilder sb = new StringBuilder();
		for(int i=s.length()-1; i>=0; i--)
			sb.append(s.charAt(i));
		return sb.toString();
	}

	private long[] solve(String s) {
		// first xor(s, t[0..n-1])
		// if there are more than 2 setBits,
		// align s so that first setBit of s is aligned with second setBig of t
		// then make xor

		// xor is + over Z2

		// s(x) = s as coefficient of polynomial over Z2
		// x^p + x^q
		// = x^p (1+x^(q-p))
		// = s(x) (1+P(x))
		// = (x^p + s'(x))(1+P(x))
		// = x^p + s'(x) + s(x)P(x)

		// p is known, find minimum q s.t.
		// s(x) | (x^p + x^q)

		// x^p(1+x^t) = s(x)P(x)
		// s(x) = x^p*s'(x)
		// 1+x^t = s'(x)P(x)

		// remove leading zeros and trailing zeros in s then reverse it
		// wlog s(x) = 1 + ..... + x^(|s|-1), |s| >= 2
		// want R(x) = 1
		// x^t = s(x)P(x)+R(x) (deg R(x) < deg s(x))

		// suppose we have R_t(x) = x^t % s(x)
		// then R_(t+1)(x) = x^(t+1) % s(x) = xR_t(x) % s(x)
		// there are 2^(|s|-1) different R(x) so enumerating all R(x) takes O(|s|*2^|s|)
		//

		// to put it differently,
		// we are asking for the order of x mod s(x)
		// i.e., x^t = 1 mod s(x)

		// this particular meet-in-the-middle technique is called the baby-step giant-step!
		// let m = 2^(|s|/2)
		// we precompute all x^j up to j <= m
		// if x^j = 1 then we are already good
		// otherwise, x^j's are all distinct

		// then for i = 1 to m
		// x^(im+j) = 1 -> x^j = (x^-m)^i
		// how to find x^-m?
		// extended euclid

		int numLeadingZeros;
		for(numLeadingZeros=0; numLeadingZeros<s.length(); numLeadingZeros++)
			if(s.charAt(numLeadingZeros) == '1')
				break;

		if(numLeadingZeros == s.length())
			return new long[] {-1};

		long mod = 0;
		for(int i=s.length()-1; i>=numLeadingZeros; i--) {
			mod <<= 1;
			mod += s.charAt(i)-'0';
		}

		if(mod == 1)
			return new long[] {numLeadingZeros+1, numLeadingZeros+2};

		final int N = 63-Long.numberOfLeadingZeros(mod);
		final int M = N/2;
		HashMap<Long, Long> dp = new HashMap<>();

		long a = 1;
		dp.put(a, 0L);
		for(long j=1; j<(1L<<M); j++) {
			a = multiplyX(a, mod);
			if(a == 1)
				return new long[] {numLeadingZeros+1, j+numLeadingZeros+1};
			dp.put(a, j);
		}
		// after loop, a = x^(2^M)
		final long invM = extendedEuclid(a, mod, mod)[0];
		{
			long temp = multiply(a, invM, mod);
			assert(temp == 1);
		}
		// x^3 = x^2 + x + 1
		// 1<<N = 8
		// x^6 = (x^2+x+1)^2 = x^4+x^3+x^2 + x^3+x^2+x + x^2+x+1 = x^4+x^2+1
		// = x(x^2+x+1) + x^2+1
		// = x^2+x+1 + x^2+x + x^2+1
		// = x^2
		// so x^6 = x^-1?
		// (x^2+x+1)*x = x^3+x^2+x^1 = 1 ok
		// so a = 2
		// a^-1 = 1+2+4 = 7

		a = invM;
		for(long i=1; i<(1L << (N-M)); i++){
			if(dp.containsKey(a)) {
				long j = dp.get(a);
				return new long[] {numLeadingZeros+1, i*((1L<<M)-1)+j+numLeadingZeros+1};
			}
			a = multiply(a, invM, mod);
		}
		return null;
	}

	long[] extendedEuclid(long a1, long a2, long mod) {
		long x1 = 1;
		long x2 = 0;
		long y1 = 0;
		long y2 = 1;
		while(a2 > 0) {
			long q = divide(a1, a2);
			long temp = a2;
			a2 = a1 ^ multiply(q, a2, mod);
			if(Long.highestOneBit(a2) == Long.highestOneBit(mod))
				a2 ^= mod;
			a1 = temp;
			temp = x2;
			x2 = x1 ^ multiply(q, x2, mod);
			if(Long.highestOneBit(x2) == Long.highestOneBit(mod))
				x2 ^= mod;
			x1 = temp;
			temp = y2;
			y2 = y1 ^ multiply(q, y2, mod);
			if(Long.highestOneBit(y2) == Long.highestOneBit(mod))
				y2 ^= mod;
			y1 = temp;
		}
		return new long[] {x1, y1, a1};
	}

	long divide(long a, long b) {
		long res = 0;
		int base = 63-Long.numberOfLeadingZeros(b);
 		for(int i=63-Long.numberOfLeadingZeros(a); i>=base; i--) {
			if((a & (1<<i)) > 0) {
				res += 1<<(i-base);
				a ^= b<<(i-base);
			}
		}
		return res;
	}

	long multiplyX(long a, long mod) {
		a <<= 1;
		if(Long.highestOneBit(a) == Long.highestOneBit(mod))
			a ^= mod;
		return a;
	}

	long pow(long a, long k, long mod) {
		long res = 1;
		long base = a;
		while(k > 0) {
			if((k & 1) > 0)
				res = multiply(res, base, mod);
			base = multiply(base, base, mod);
			k >>= 1;
		}
		return res;
	}

	long multiply(long a, long b, long mod) {
		// a0 + a1x + a2x^2 + ... + akx^k
		// = a0 + x(a1 + a2x + ....)
		// = a0 + x(a1 + x (a2 + .....)
		long res = 0;
		for(int i=63-Long.numberOfLeadingZeros(a); i>=0; i--) {
			res <<= 1;
			if((a & (1<<i)) > 0)
				res ^= b;
			if(Long.highestOneBit(res) == Long.highestOneBit(mod))
				res ^= mod;
		}
		// x^2 = 4
		// x^3 = x^2+x+1  = 7
		// x(x^2+x+1) = x^3+x^2+x = 1
		return res;
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		// 32768?
		public MyScanner(InputStream is, int bufferSize) {
			br = new BufferedReader(new InputStreamReader(is), bufferSize);
		}

		public MyScanner(InputStream is) {
			br = new BufferedReader(new InputStreamReader(is));
			// br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
		}

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

		}

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

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

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

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

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

		int[][] nextTreeEdges(int n, int offset){
			int[][] e = new int[n-1][2];
			for(int i=0; i<n-1; i++){
				e[i][0] = nextInt()+offset;
				e[i][1] = nextInt()+offset;
			}
			return e;
		}

		int[][] nextMatrix(int n, int m) {
			return nextMatrix(n, m, 0);
		}

		int[][] nextMatrix(int n, int m, int offset) {
			int[][] mat = new int[n][m];
			for(int i=0; i<n; i++) {
				for(int j=0; j<m; j++) {
					mat[i][j] = nextInt()+offset;
				}
			}
			return mat;
		}

		int[][] nextPairs(int n){
			return nextPairs(n, 0);
		}

		int[][] nextPairs(int n, int offset) {
			int[][] xy = new int[2][n];
			for(int i=0; i<n; i++) {
				xy[0][i] = nextInt() + offset;
				xy[1][i] = nextInt() + offset;
			}
			return xy;
		}

		int[][] nextGraphEdges(){
			return nextGraphEdges(0);
		}

		int[][] nextGraphEdges(int offset) {
			int m = nextInt();
			int[][] e = new int[m][2];
			for(int i=0; i<m; i++){
				e[i][0] = nextInt()+offset;
				e[i][1] = nextInt()+offset;
			}
			return e;
		}

		int[] nextIntArray(int len) {
			return nextIntArray(len, 0);
		}
		int[] nextIntArray(int len, int offset){
	    	int[] a = new int[len];
			for(int j=0; j<len; j++)
	    		a[j] = nextInt()+offset;
	    	return a;
		}

		long[] nextLongArray(int len) {
			return nextLongArray(len, 0);
		}
		long[] nextLongArray(int len, int offset){
	    	long[] a = new long[len];
			for(int j=0; j<len; j++)
	    		a[j] = nextLong()+offset;
	    	return a;
		}
	}

	public static class MyPrintWriter extends PrintWriter{
		public MyPrintWriter(OutputStream os) {
			super(os);
		}

		public void printlnAns(long ans) {
			println(ans);
		}

		public void printlnAns(int ans) {
			println(ans);
		}

		public void printlnAns(boolean ans) {
			if(ans)
				println(YES);
			else
				println(NO);
		}

		public void printAns(long[] arr){
			if(arr != null && arr.length > 0){
				print(arr[0]);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]);
				}
			}
		}
		public void printlnAns(long[] arr){
			printAns(arr);
			println();
		}

		public void printAns(int[] arr){
			if(arr != null && arr.length > 0){
				print(arr[0]);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]);
				}
			}
		}
		public void printlnAns(int[] arr){
			printAns(arr);
			println();
		}

		public <T> void printAns(ArrayList<T> arr){
			if(arr != null && arr.size() > 0){
				print(arr.get(0));
				for(int i=1; i<arr.size(); i++){
					print(" ");
					print(arr.get(i));
				}
			}
		}
		public <T> void printlnAns(ArrayList<T> arr){
			printAns(arr);
			println();
		}

		public void printAns(int[] arr, int add){
			if(arr != null && arr.length > 0){
				print(arr[0]+add);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]+add);
				}
			}
		}
		public void printlnAns(int[] arr, int add){
			printAns(arr, add);
			println();
		}

		public void printAns(ArrayList<Integer> arr, int add) {
			if(arr != null && arr.size() > 0){
				print(arr.get(0)+add);
				for(int i=1; i<arr.size(); i++){
					print(" ");
					print(arr.get(i)+add);
				}
			}
		}

		public void printlnAns(ArrayList<Integer> arr, int add){
			printAns(arr, add);
			println();
		}

		public void printlnAnsSplit(long[] arr, int split){
			if(arr != null){
				for(int i=0; i<arr.length; i+=split){
					print(arr[i]);
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr[j]);
					}
					println();
				}
			}
		}

		public void printlnAnsSplit(int[] arr, int split){
			if(arr != null){
				for(int i=0; i<arr.length; i+=split){
					print(arr[i]);
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr[j]);
					}
					println();
				}
			}
		}

		public <T> void printlnAnsSplit(ArrayList<T> arr, int split){
			if(arr != null && !arr.isEmpty()){
				for(int i=0; i<arr.size(); i+=split){
					print(arr.get(i));
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr.get(j));
					}
					println();
				}
			}
		}
	}

	static private void permutateAndSort(int[] a) {
		int n = a.length;
		Random R = new Random(System.currentTimeMillis());
		for(int i=0; i<n; i++) {
			int t = R.nextInt(n-i);
			int temp = a[n-1-i];
			a[n-1-i] = a[t];
			a[t] = temp;
		}
		Arrays.sort(a);
	}

	static private int[][] constructChildren(int n, int[] parent, int parentRoot){
		int[][] childrens = new int[n][];

		int[] numChildren = new int[n];
		for(int i=0; i<parent.length; i++) {
			if(parent[i] != parentRoot)
				numChildren[parent[i]]++;
		}

		for(int i=0; i<n; i++) {
			childrens[i] = new int[numChildren[i]];
		}

		int[] idx = new int[n];
		for(int i=0; i<parent.length; i++) {
			if(parent[i] != parentRoot)
				childrens[parent[i]][idx[parent[i]]++] = i;
		}

		return childrens;
	}

	static private int[][][] constructDirectedNeighborhood(int n, int[][] e){
		int[] inDegree = new int[n];
		int[] outDegree = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			outDegree[u]++;
			inDegree[v]++;
		}

		int[][] inNeighbors = new int[n][];
		int[][] outNeighbors = new int[n][];
		for(int i=0; i<n; i++) {
			inNeighbors[i] = new int[inDegree[i]];
			outNeighbors[i] = new int[outDegree[i]];
		}

		int[] inIdx = new int[n];
		int[] outIdx = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			outNeighbors[u][outIdx[u]++] = v;
			inNeighbors[v][inIdx[v]++] = u;
		}

		return new int[][][] {inNeighbors, outNeighbors};
	}

	static private int[][] constructNeighborhood(int n, int[][] e) {
		int[] degree = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			degree[u]++;
			degree[v]++;
		}

		int[][] neighbors = new int[n][];
		for(int i=0; i<n; i++)
			neighbors[i] = new int[degree[i]];

		int[] idx = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			neighbors[u][idx[u]++] = v;
			neighbors[v][idx[v]++] = u;
		}

		return neighbors;
	}

	static private void drawGraph(int[][] e) {
		makeDotUndirected(e);
		try {
			final Process process = new ProcessBuilder("dot", "-Tpng", "graph.dot")
					.redirectOutput(new File("graph.png"))
					.start();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	static private void makeDotUndirected(int[][] e) {
		MyPrintWriter out2 = null;
		 try {
			out2 = new MyPrintWriter(new FileOutputStream("graph.dot"));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		out2.println("strict graph {");
		for(int i=0; i<e.length; i++){
			out2.println(e[i][0] + "--" + e[i][1] + ";");
		}
		out2.println("}");
		out2.close();
	}

	static private void makeDotDirected(int[][] e) {
		MyPrintWriter out2 = null;
		 try {
			out2 = new MyPrintWriter(new FileOutputStream("graph.dot"));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		out2.println("strict digraph {");
		for(int i=0; i<e.length; i++){
			out2.println(e[i][0] + "->" + e[i][1] + ";");
		}
		out2.println("}");
		out2.close();
	}

}


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

// you can compare with output.txt and expected out
public class Round803G {
	MyPrintWriter out;
	MyScanner in;

//	final static long FIXED_RANDOM;
//	static {
//		FIXED_RANDOM = System.currentTimeMillis();
//	}
	final static String IMPOSSIBLE = "IMPOSSIBLE";
	final static String POSSIBLE = "POSSIBLE";
	final static String YES = "YES";
	final static String NO = "NO";

    private void initIO(boolean isFileIO) {
        if (System.getProperty("ONLINE_JUDGE") == null && isFileIO) {
        	try{
	            in = new MyScanner(new FileInputStream("input.txt"));
	            out = new MyPrintWriter(new FileOutputStream("output.txt"));
        	}
        	catch(FileNotFoundException e){
        		e.printStackTrace();
        	}
        }
        else{
    		in = new MyScanner(System.in);
    	    out = new MyPrintWriter(new BufferedOutputStream(System.out));
        }
    }

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

		Round803G sol = new Round803G();
		sol.run();
    }

	private void run() {
		boolean isDebug = false;
		boolean isFileIO = true;
		boolean hasMultipleTests = false;

		initIO(isFileIO);

		// test();

		int t = hasMultipleTests? in.nextInt() : 1;

	    for (int i = 1; i <= t; ++i) {
	    	String s = in.next();

	    	if(isDebug){
		    	out.printf("Test %d\n", i);
	    	}

			long[] ans = solve(s);
			out.printlnAns(ans);

			if(isDebug)
				out.flush();
	    }

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

	private void test() {

		long mod = 1L<<32;
		long temp;
		long temp2;

		temp2 = multiply((1L<<31)-23, 1, mod);

		mod = 34359738337L;
		//  = 9461547882L
		temp2 = multiply(2, 1, mod);
		temp2 = multiply(1000, 1, mod);
		temp2 = multiply((1L<<31)-23, 1, mod);
		temp2 = multiply(946154788L, 1, mod);
		temp2 = multiply(3336154788L, 1, mod);
		temp2 = multiply(9461547882L, 1, mod);

		temp = divide(9, 3); // x^3+1, x+1
		temp2 = multiply(3, temp, mod); // (x^2+x+1)(x+1) = x^3+1
		temp = divide(26, 25); // x^4 + x^3 + x, x^4 + x^3 + 1
		temp2 = multiply(25, temp, mod);
		temp = divide(52, 17); // x^5 + x^4 + x^2, x^4 + 1
		temp2 = multiply(17, temp, mod);

		// https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example_2
		mod = (1<<8) + (1<<4) + (1<<3) + (1<<1) + 1;
		long a = (1<<6) + (1<<4) + (1<<1) + 1;

		long[] res = extendedEuclid(a, mod, mod);
		long ainv = res[0];
		if(Long.highestOneBit(ainv) == Long.highestOneBit(mod))
			ainv ^= mod;

		temp = multiply(a, ainv, mod); // checked

	}

	private int[] bruteForce(String s) {
		BigInteger n = new BigInteger(reverse(s), 2);
		BigInteger base = new BigInteger(reverse(s), 2);

		int p = n.getLowestSetBit();
		if(p == -1) // or |t| > 10^100
			return new int[] {-1};

		n = n.flipBit(p);
		if(n.equals(BigInteger.valueOf(0)))
			return new int[] {p+1, p+2};

		while(n.getLowestSetBit() != n.bitLength()-1) {
			n = n.xor(base.shiftLeft(n.getLowestSetBit()-p));
		}
		int q = n.getLowestSetBit();

		return new int[] {p+1, q+1};
	}

	String reverse(String s) {
		StringBuilder sb = new StringBuilder();
		for(int i=s.length()-1; i>=0; i--)
			sb.append(s.charAt(i));
		return sb.toString();
	}

	private long[] solve(String s) {
		// first xor(s, t[0..n-1])
		// if there are more than 2 setBits,
		// align s so that first setBit of s is aligned with second setBig of t
		// then make xor

		// xor is + over Z2

		// s(x) = s as coefficient of polynomial over Z2
		// x^p + x^q
		// = x^p (1+x^(q-p))
		// = s(x) (1+P(x))
		// = (x^p + s'(x))(1+P(x))
		// = x^p + s'(x) + s(x)P(x)

		// p is known, find minimum q s.t.
		// s(x) | (x^p + x^q)

		// x^p(1+x^t) = s(x)P(x)
		// s(x) = x^p*s'(x)
		// 1+x^t = s'(x)P(x)

		// remove leading zeros and trailing zeros in s then reverse it
		// wlog s(x) = 1 + ..... + x^(|s|-1), |s| >= 2
		// want R(x) = 1
		// x^t = s(x)P(x)+R(x) (deg R(x) < deg s(x))

		// suppose we have R_t(x) = x^t % s(x)
		// then R_(t+1)(x) = x^(t+1) % s(x) = xR_t(x) % s(x)
		// there are 2^(|s|-1) different R(x) so enumerating all R(x) takes O(|s|*2^|s|)
		//

		// to put it differently,
		// we are asking for the order of x mod s(x)
		// i.e., x^t = 1 mod s(x)

		// this particular meet-in-the-middle technique is called the baby-step giant-step!
		// let m = 2^(|s|/2)
		// we precompute all x^j up to j <= m
		// if x^j = 1 then we are already good
		// otherwise, x^j's are all distinct

		// then for i = 1 to m
		// x^(im+j) = 1 -> x^j = (x^-m)^i
		// how to find x^-m?
		// extended euclid

		int numLeadingZeros;
		for(numLeadingZeros=0; numLeadingZeros<s.length(); numLeadingZeros++)
			if(s.charAt(numLeadingZeros) == '1')
				break;

		if(numLeadingZeros == s.length())
			return new long[] {-1};

		long mod = 0;
		for(int i=s.length()-1; i>=numLeadingZeros; i--) {
			mod <<= 1;
			mod += s.charAt(i)-'0';
		}

		if(mod == 1)
			return new long[] {numLeadingZeros+1, numLeadingZeros+2};

		final int N = 63-Long.numberOfLeadingZeros(mod);
		final int M = N/2;
		HashMap<Long, Long> dp = new HashMap<>();

		long a = 1;
		dp.put(a, 0L);
		for(long j=1; j<(1L<<M); j++) {
			a = multiplyX(a, mod);
			if(a == 1)
				return new long[] {numLeadingZeros+1, j+numLeadingZeros+1};
			dp.put(a, j);
		}
		// after loop, a = x^(2^M)
		final long invM = extendedEuclid(a, mod, mod)[0];
		{
			long temp = multiply(a, invM, mod);
			assert(temp == 1);
		}
		// x^3 = x^2 + x + 1
		// 1<<N = 8
		// x^6 = (x^2+x+1)^2 = x^4+x^3+x^2 + x^3+x^2+x + x^2+x+1 = x^4+x^2+1
		// = x(x^2+x+1) + x^2+1
		// = x^2+x+1 + x^2+x + x^2+1
		// = x^2
		// so x^6 = x^-1?
		// (x^2+x+1)*x = x^3+x^2+x^1 = 1 ok
		// so a = 2
		// a^-1 = 1+2+4 = 7

		a = invM;
		for(long i=1; i<=(1L << (N-M)); i++){
			if(dp.containsKey(a)) {
				long j = dp.get(a);
				return new long[] {numLeadingZeros+1, i*((1L<<M)-1)+j+numLeadingZeros+1};
			}
			a = multiply(a, invM, mod);
		}
		return null;
	}

	long[] extendedEuclid(long a1, long a2, long mod) {
		long x1 = 1;
		long x2 = 0;
		long y1 = 0;
		long y2 = 1;
		while(a2 > 0) {
			long q = divide(a1, a2);
			long temp = a2;
			a2 = a1 ^ multiply(q, a2, mod);
			if(Long.highestOneBit(a2) == Long.highestOneBit(mod))
				a2 ^= mod;
			a1 = temp;
			temp = x2;
			x2 = x1 ^ multiply(q, x2, mod);
			if(Long.highestOneBit(x2) == Long.highestOneBit(mod))
				x2 ^= mod;
			x1 = temp;
			temp = y2;
			y2 = y1 ^ multiply(q, y2, mod);
			if(Long.highestOneBit(y2) == Long.highestOneBit(mod))
				y2 ^= mod;
			y1 = temp;
		}
		return new long[] {x1, y1, a1};
	}

	long divide(long a, long b) {
		long res = 0;
		int base = 63-Long.numberOfLeadingZeros(b);
 		for(int i=63-Long.numberOfLeadingZeros(a); i>=base; i--) {
			if((a & (1L<<i)) > 0) {
				res += 1L<<(i-base);
				a ^= b<<(i-base);
			}
		}
		return res;
	}

	long multiplyX(long a, long mod) {
		a <<= 1;
		if(Long.highestOneBit(a) == Long.highestOneBit(mod))
			a ^= mod;
		return a;
	}

	long pow(long a, long k, long mod) {
		long res = 1;
		long base = a;
		while(k > 0) {
			if((k & 1) > 0)
				res = multiply(res, base, mod);
			base = multiply(base, base, mod);
			k >>= 1;
		}
		return res;
	}

	long multiply(long a, long b, long mod) {
		// a0 + a1x + a2x^2 + ... + akx^k
		// = a0 + x(a1 + a2x + ....)
		// = a0 + x(a1 + x (a2 + .....)
		long res = 0;
		for(int i=63-Long.numberOfLeadingZeros(a); i>=0; i--) {
			res <<= 1;
			if((a & (1L<<i)) > 0)
				res ^= b;
			if(Long.highestOneBit(res) == Long.highestOneBit(mod))
				res ^= mod;
		}
		// x^2 = 4
		// x^3 = x^2+x+1  = 7
		// x(x^2+x+1) = x^3+x^2+x = 1
		return res;
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		// 32768?
		public MyScanner(InputStream is, int bufferSize) {
			br = new BufferedReader(new InputStreamReader(is), bufferSize);
		}

		public MyScanner(InputStream is) {
			br = new BufferedReader(new InputStreamReader(is));
			// br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
		}

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

		}

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

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

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

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

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

		int[][] nextTreeEdges(int n, int offset){
			int[][] e = new int[n-1][2];
			for(int i=0; i<n-1; i++){
				e[i][0] = nextInt()+offset;
				e[i][1] = nextInt()+offset;
			}
			return e;
		}

		int[][] nextMatrix(int n, int m) {
			return nextMatrix(n, m, 0);
		}

		int[][] nextMatrix(int n, int m, int offset) {
			int[][] mat = new int[n][m];
			for(int i=0; i<n; i++) {
				for(int j=0; j<m; j++) {
					mat[i][j] = nextInt()+offset;
				}
			}
			return mat;
		}

		int[][] nextPairs(int n){
			return nextPairs(n, 0);
		}

		int[][] nextPairs(int n, int offset) {
			int[][] xy = new int[2][n];
			for(int i=0; i<n; i++) {
				xy[0][i] = nextInt() + offset;
				xy[1][i] = nextInt() + offset;
			}
			return xy;
		}

		int[][] nextGraphEdges(){
			return nextGraphEdges(0);
		}

		int[][] nextGraphEdges(int offset) {
			int m = nextInt();
			int[][] e = new int[m][2];
			for(int i=0; i<m; i++){
				e[i][0] = nextInt()+offset;
				e[i][1] = nextInt()+offset;
			}
			return e;
		}

		int[] nextIntArray(int len) {
			return nextIntArray(len, 0);
		}
		int[] nextIntArray(int len, int offset){
	    	int[] a = new int[len];
			for(int j=0; j<len; j++)
	    		a[j] = nextInt()+offset;
	    	return a;
		}

		long[] nextLongArray(int len) {
			return nextLongArray(len, 0);
		}
		long[] nextLongArray(int len, int offset){
	    	long[] a = new long[len];
			for(int j=0; j<len; j++)
	    		a[j] = nextLong()+offset;
	    	return a;
		}
	}

	public static class MyPrintWriter extends PrintWriter{
		public MyPrintWriter(OutputStream os) {
			super(os);
		}

		public void printlnAns(long ans) {
			println(ans);
		}

		public void printlnAns(int ans) {
			println(ans);
		}

		public void printlnAns(boolean ans) {
			if(ans)
				println(YES);
			else
				println(NO);
		}

		public void printAns(long[] arr){
			if(arr != null && arr.length > 0){
				print(arr[0]);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]);
				}
			}
		}
		public void printlnAns(long[] arr){
			printAns(arr);
			println();
		}

		public void printAns(int[] arr){
			if(arr != null && arr.length > 0){
				print(arr[0]);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]);
				}
			}
		}
		public void printlnAns(int[] arr){
			printAns(arr);
			println();
		}

		public <T> void printAns(ArrayList<T> arr){
			if(arr != null && arr.size() > 0){
				print(arr.get(0));
				for(int i=1; i<arr.size(); i++){
					print(" ");
					print(arr.get(i));
				}
			}
		}
		public <T> void printlnAns(ArrayList<T> arr){
			printAns(arr);
			println();
		}

		public void printAns(int[] arr, int add){
			if(arr != null && arr.length > 0){
				print(arr[0]+add);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]+add);
				}
			}
		}
		public void printlnAns(int[] arr, int add){
			printAns(arr, add);
			println();
		}

		public void printAns(ArrayList<Integer> arr, int add) {
			if(arr != null && arr.size() > 0){
				print(arr.get(0)+add);
				for(int i=1; i<arr.size(); i++){
					print(" ");
					print(arr.get(i)+add);
				}
			}
		}

		public void printlnAns(ArrayList<Integer> arr, int add){
			printAns(arr, add);
			println();
		}

		public void printlnAnsSplit(long[] arr, int split){
			if(arr != null){
				for(int i=0; i<arr.length; i+=split){
					print(arr[i]);
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr[j]);
					}
					println();
				}
			}
		}

		public void printlnAnsSplit(int[] arr, int split){
			if(arr != null){
				for(int i=0; i<arr.length; i+=split){
					print(arr[i]);
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr[j]);
					}
					println();
				}
			}
		}

		public <T> void printlnAnsSplit(ArrayList<T> arr, int split){
			if(arr != null && !arr.isEmpty()){
				for(int i=0; i<arr.size(); i+=split){
					print(arr.get(i));
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr.get(j));
					}
					println();
				}
			}
		}
	}

	static private void permutateAndSort(int[] a) {
		int n = a.length;
		Random R = new Random(System.currentTimeMillis());
		for(int i=0; i<n; i++) {
			int t = R.nextInt(n-i);
			int temp = a[n-1-i];
			a[n-1-i] = a[t];
			a[t] = temp;
		}
		Arrays.sort(a);
	}

	static private int[][] constructChildren(int n, int[] parent, int parentRoot){
		int[][] childrens = new int[n][];

		int[] numChildren = new int[n];
		for(int i=0; i<parent.length; i++) {
			if(parent[i] != parentRoot)
				numChildren[parent[i]]++;
		}

		for(int i=0; i<n; i++) {
			childrens[i] = new int[numChildren[i]];
		}

		int[] idx = new int[n];
		for(int i=0; i<parent.length; i++) {
			if(parent[i] != parentRoot)
				childrens[parent[i]][idx[parent[i]]++] = i;
		}

		return childrens;
	}

	static private int[][][] constructDirectedNeighborhood(int n, int[][] e){
		int[] inDegree = new int[n];
		int[] outDegree = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			outDegree[u]++;
			inDegree[v]++;
		}

		int[][] inNeighbors = new int[n][];
		int[][] outNeighbors = new int[n][];
		for(int i=0; i<n; i++) {
			inNeighbors[i] = new int[inDegree[i]];
			outNeighbors[i] = new int[outDegree[i]];
		}

		int[] inIdx = new int[n];
		int[] outIdx = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			outNeighbors[u][outIdx[u]++] = v;
			inNeighbors[v][inIdx[v]++] = u;
		}

		return new int[][][] {inNeighbors, outNeighbors};
	}

	static private int[][] constructNeighborhood(int n, int[][] e) {
		int[] degree = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			degree[u]++;
			degree[v]++;
		}

		int[][] neighbors = new int[n][];
		for(int i=0; i<n; i++)
			neighbors[i] = new int[degree[i]];

		int[] idx = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			neighbors[u][idx[u]++] = v;
			neighbors[v][idx[v]++] = u;
		}

		return neighbors;
	}

	static private void drawGraph(int[][] e) {
		makeDotUndirected(e);
		try {
			final Process process = new ProcessBuilder("dot", "-Tpng", "graph.dot")
					.redirectOutput(new File("graph.png"))
					.start();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	static private void makeDotUndirected(int[][] e) {
		MyPrintWriter out2 = null;
		 try {
			out2 = new MyPrintWriter(new FileOutputStream("graph.dot"));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		out2.println("strict graph {");
		for(int i=0; i<e.length; i++){
			out2.println(e[i][0] + "--" + e[i][1] + ";");
		}
		out2.println("}");
		out2.close();
	}

	static private void makeDotDirected(int[][] e) {
		MyPrintWriter out2 = null;
		 try {
			out2 = new MyPrintWriter(new FileOutputStream("graph.dot"));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		out2.println("strict digraph {");
		for(int i=0; i<e.length; i++){
			out2.println(e[i][0] + "->" + e[i][1] + ";");
		}
		out2.println("}");
		out2.close();
	}

}


//package com.example.practice.codeforces.sc2900.prac;

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

public class Solution1 {
    public static void main (String [] args) throws IOException {
        // Use BufferedReader rather than RandomAccessFile; it's much faster
        final BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);
        // input file name goes above
        //StringTokenizer st = new StringTokenizer(input.readLine());
        //int n = Integer.parseInt(st.nextToken()), a = Integer.parseInt(st.nextToken()), b = Integer.parseInt(st.nextToken()), k = Integer.parseInt(st.nextToken());
        long[] res = calc(input.readLine());
        if (res==null){
            out.println(-1);
        }else {
            printArray(res, out);
        }
        out.close();       // close the output file
    }

    private static long[] calc(final String s) {
        long px = 0, v = 1;
        int p = s.length()-1, tem = 0, highest = 0, first = 0, c = 0;
        while (p>=0 && s.charAt(p)=='0'){
            p--;
        }
        if (p<0)return null;
        while (p>=0){
            if (s.charAt(p)=='1'){
                px |= 1L << tem;
                highest = tem;
                first = p;
                c++;
            }
            tem++;
            p--;
        }
        if (c==1)return new long[]{first+1, first+2};
        final long m = (long) Math.sqrt(1L<<highest) + 1;
        HashMap<Long, Long> map = new HashMap<>();
        for (int i=1;i<=m;++i){
            v = v << 1;
            if ((v & (1L<<highest)) != 0){
                v = v ^ px;
            }
            if (v == 1){
                return new long[]{first+1, first+1+i};
            }
            if (i<m){
                map.put(v, (long)i);
            }
        }
        final long d = v;
        for (int i=2;i<=m;++i){
            v = multi(px, v, d, highest);
            if (v==1){
                return new long[]{first + 1, first + 1 + m * i};
            }
            Long j = map.get(v);
            if (j != null){
                return new long[]{first + 1, first + 1 + m * i - j};
            }
        }
        return null;
    }

    private static long multi(final long px, final long v, final long d, final int highest){
        long res = 0;
        for (int i=0;i<highest;++i){
            if ((d & (1L<<i)) != 0) {
                int t = i;
                long v2 = v;
                while (t > 0) {
                    v2 = v2 << 1;
                    if ((v2 & (1L<<highest)) != 0){
                        v2 = v2 ^ px;
                    }
                    t--;
                }
                res = res ^ v2;
            }
        }
        return res;
    }

    private static void printArray(long[] ns, final PrintWriter out){
        for (int i=0;i<ns.length;++i){
            out.print(ns[i]);
            if (i+1<ns.length)out.print(" ");
            else out.println();
        }
    }

    private static void printArrayInt(int[] ns, final PrintWriter out){
        for (int i=0;i<ns.length;++i){
            out.print(ns[i]);
            if (i+1<ns.length)out.print(" ");
            else out.println();
        }
    }

    private static void printArrayVertical(long[] ns, final PrintWriter out){
        for (long a : ns){
            out.println(a);
        }
    }

    private static void printArray2D(long[][] ns, final int len, final PrintWriter out){
        int cnt = 0;
        for (long[] kk : ns){
            cnt++;
            if (cnt > len)break;
            for (int i=0;i<kk.length;++i){
                out.print(kk[i]);
                if (i+1<kk.length)out.print(" ");
                else out.println();
            }
        }
    }

    private static void printArray2DInt(int[][] ns, final int len, final PrintWriter out){
        int cnt = 0;
        for (int[] kk : ns){
            cnt++;
            if (cnt > len)break;
            for (int i=0;i<kk.length;++i){
                out.print(kk[i]);
                if (i+1<kk.length)out.print(" ");
                else out.println();
            }
        }
    }

    private static long[] readArray(final int n, final BufferedReader input) throws IOException{
        long[] ns = new long[n];
        StringTokenizer st = new StringTokenizer(input.readLine());
        for (int i=0;i<n;++i){
            ns[i] = Long.parseLong(st.nextToken());
        }
        return ns;
    }

    private static int[] readArrayInt(final int n, final BufferedReader input) throws IOException{
        int[] ns = new int[n];
        StringTokenizer st = new StringTokenizer(input.readLine());
        for (int i=0;i<n;++i){
            ns[i] = Integer.parseInt(st.nextToken());
        }
        return ns;
    }

    private static long[] readArrayVertical(final int n, final BufferedReader input) throws IOException{
        long[] ns = new long[n];
        for (int i=0;i<n;++i){
            ns[i] = Long.parseLong(input.readLine());
        }
        return ns;
    }

    private static long[][] readArray2D(final int n, final int len, final BufferedReader input) throws IOException{
        long[][] ns = new long[len][];
        for (int i=0;i<n;++i){
            StringTokenizer st = new StringTokenizer(input.readLine());
            ArrayList<Long> al = new ArrayList<>();
            while (st.hasMoreTokens()){
                al.add(Long.parseLong(st.nextToken()));
            }
            long[] kk = new long[al.size()];
            for (int j=0;j<kk.length;++j){
                kk[j] = al.get(j);
            }
            ns[i] = kk;
        }
        return ns;
    }

    private static int[][] readArray2DInt(final int n, final int len, final BufferedReader input) throws IOException{
        int[][] ns = new int[len][];
        for (int i=0;i<n;++i){
            StringTokenizer st = new StringTokenizer(input.readLine());
            ArrayList<Integer> al = new ArrayList<>();
            while (st.hasMoreTokens()){
                al.add(Integer.parseInt(st.nextToken()));
            }
            int[] kk = new int[al.size()];
            for (int j=0;j<kk.length;++j){
                kk[j] = al.get(j);
            }
            ns[i] = kk;
        }
        return ns;
    }

    static class SegTree{
        int st;
        int en;
        int mid;
        int val1;
        int val2;
        SegTree left;
        SegTree right;
        public SegTree(int l, int r, int d){
            st = l;
            en = r;
            mid = (st + en) >> 1;
            val1 = val2 = d;
            if (st<en){
                left = new SegTree(st, mid, d);
                right = new SegTree(mid+1, en, d);
            }else {
                left = right = null;
            }
        }

        public SegTree(int l, int r, int[] ns){
            st = l;
            en = r;
            mid = (st + en) >> 1;
            if (st==en){
                val1 = val2 = ns[st];
            }else {
                left = new SegTree(l, mid, ns);
                right = new SegTree(mid+1, r, ns);
                val1 = Math.min(left.val1, right.val1);
                val2 = Math.max(left.val2, right.val2);
            }
        }

        void update(int idx, int v){
            if (st==en){
                val1 = val2 = v;
            }else {
                if (idx <= mid){
                    left.update(idx, v);
                }else {
                    right.update(idx, v);
                }
                val1 = Math.min(left.val1, right.val1);
                val2 = Math.max(left.val2, right.val2);
            }
        }

        int getMin(int l, int r){
            if (st==en || (l==st && r==en))return val1;
            if (r<=mid){
                return left.getMin(l, r);
            }
            if (l>mid){
                return right.getMin(l, r);
            }
            return Math.min(left.getMin(l, mid), right.getMin(mid+1, r));
        }

        int getMax(int l, int r){
            if (st==en || (l==st && r==en))return val2;
            if (r<=mid){
                return left.getMax(l, r);
            }
            if (l>mid){
                return right.getMax(l, r);
            }
            return Math.max(left.getMax(l, mid), right.getMax(mid+1, r));
        }
    }

    static class SparseTable{
        int[][] minTable;
        int[][] maxTable;
        int[] log2;
        int n;
        public SparseTable(final int[] ns){
            n = ns.length;
            int m = 0, pre = 0;
            while (1<<m < n){
                m++;
            }
            m++;
            minTable = new int[n][m];
            maxTable = new int[n][m];
            log2 = new int[n+1];
            for (int i=0;i<n;++i){
                minTable[i][0] = ns[i];
                maxTable[i][0] = ns[i];
                if ((1<<(pre+1)) == i+1){
                    pre++;
                }
                log2[i+1] = pre;
            }
            for (int i=1;i<m;++i){
                for (int j=0;j<n;++j){
                    int r = Math.min(n-1, j+(1<<i)-1);
                    if (r-(1<<(i-1))+1 <= j){
                        minTable[j][i] = minTable[j][i-1];
                        maxTable[j][i] = maxTable[j][i-1];
                    }else {
                        minTable[j][i] = Math.min(minTable[j][i-1], minTable[r-(1<<(i-1))+1][i-1]);
                        maxTable[j][i] = Math.max(maxTable[j][i-1], maxTable[r-(1<<(i-1))+1][i-1]);
                    }
                }
            }
        }

        int getMin(final int l, final int r){
            int d = log2[r-l+1];
            return Math.min(minTable[l][d], minTable[r-(1<<d)+1][d]);
        }

        int getMax(final int l, final int r){
            int d = log2[r-l+1];
            return Math.max(maxTable[l][d], maxTable[r-(1<<d)+1][d]);
        }
    }
}