/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

/**
 *
 * @author hartha
 */
public class CodeForces {

    static ArrayList<Edge> g[];

    public static void main(String[] args) throws IOException {
        Reader.init(System.in);
        //Reader.init(new FileReader("input.txt"));
        PrintWriter writer = new PrintWriter(System.out);
        int first = 2, last = 100 ,c = 0;

        while (first <= last) {
            int mid = (first + last) / 2;

            writer.println(mid);
            writer.flush();

            String s = Reader.next();

            if(s.equals("yes")){
                c++;
                first = mid + 1;
            }

            else
                last = mid - 1;

            if(c > 1)
                break;

        }

        if(c > 1)
            writer.print("composite");
        else
            writer.println("prime");

        writer.close();
    }

}

class Edge implements Comparable<Edge> {

    int dis, cost;

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

    @Override
    public int compareTo(Edge o) {
        return this.cost - o.cost;
    }

}

class Reader {

    static BufferedReader reader;
    static StringTokenizer tokenizer;

    public static int pars(String x) {
        int num = 0;
        int i = 0;
        if (x.charAt(0) == '-') {
            i = 1;
        }
        for (; i < x.length(); i++) {
            num = num * 10 + (x.charAt(i) - '0');
        }

        if (x.charAt(0) == '-') {
            return -num;
        }

        return num;
    }

    static void init(InputStream input) {
        reader = new BufferedReader(
                new InputStreamReader(input));
        tokenizer = new StringTokenizer("");
    }

    static void init(FileReader input) {
        reader = new BufferedReader(input);
        tokenizer = new StringTokenizer("");
    }

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

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

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

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


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

/**
 *
 * @author hartha
 */
public class CodeForces {

    static ArrayList<Edge> g[];

    public static void main(String[] args) throws IOException {
        Reader.init(System.in);
        //Reader.init(new FileReader("input.txt"));
        PrintWriter writer = new PrintWriter(System.out);

        int arr[] = {2, 3, 5, 7};
        boolean b[] = new boolean[101];
        int num = -1, counter = 0;

        for (int i = 0; i < 4; i++) {
            writer.println(arr[i]);
            writer.flush();

            if (Reader.next().equals("yes")) {

                int x = arr[i] * 2;
                while (x <= 100) {

                    if (!b[x]) {
                        writer.println(x);
                        writer.flush();

                        if (Reader.next().equals("yes")) {
                            writer.println("composite");
                            writer.close();
                            return;
                        }
                    }

                    int y = x * 2;
                    while(y <= 100){
                        b[y] = true;
                        y += x;
                    }
                    x += arr[i];
                }

                break;
            }
        }

        writer.println("prime");
        writer.close();
    }

}

class Edge implements Comparable<Edge> {

    int dis, cost;

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

    @Override
    public int compareTo(Edge o) {
        return this.cost - o.cost;
    }

}

class Reader {

    static BufferedReader reader;
    static StringTokenizer tokenizer;

    public static int pars(String x) {
        int num = 0;
        int i = 0;
        if (x.charAt(0) == '-') {
            i = 1;
        }
        for (; i < x.length(); i++) {
            num = num * 10 + (x.charAt(i) - '0');
        }

        if (x.charAt(0) == '-') {
            return -num;
        }

        return num;
    }

    static void init(InputStream input) {
        reader = new BufferedReader(
                new InputStreamReader(input));
        tokenizer = new StringTokenizer("");
    }

    static void init(FileReader input) {
        reader = new BufferedReader(input);
        tokenizer = new StringTokenizer("");
    }

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

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

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

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


import java.util.*;
import java.util.LinkedList;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.math.BigInteger;

public class tmp {
    public static void main(String [] args) throws Exception{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
   //     StringTokenizer st = new StringTokenizer(in.readLine());
        StringBuilder sb = new StringBuilder();

        int [] pri = new int[101];
        for(int i=2; i<=100; i++){
            if(pri[i] == 0){
                for(int j=2*i; j <= 100; j+=i)
                    pri[j]++;
            }
        }
        int zz = 0;
        for(int i=2; i<=100; i++){
            if(pri[i] >= 1)
                zz++;
        }

        String s;
        int tmp, yes = 0, cnt=0;
        int lim = 100;
        for(int i = 2; i<=lim; i++){
            if(pri[i] == 0){
                tmp = i;
                while(tmp <= 100 && pri[tmp] <= 1){
                    cnt++;
                    System.out.println(tmp);
                    System.out.flush();
                    s = in.readLine();
                    if(s.equals("yes")){
                        yes++;
                        if(yes >= 2){
                            System.out.println("composite");
                            System.out.flush();
                            System.exit(0);
                        }
                        lim /= tmp;
                        tmp *= i;
                    }else{
                        break;
                    }
                }

            }
        }
        System.out.println("prime");
        System.out.flush();

    }

}

class P implements Comparable<P>{
    int val, idx;
    public P(int val, int idx){
        this.val = val;
        this.idx = idx;
    }

    public int compareTo(P other){
        if (this.val != other.val) return -this.val + other.val;
        return this.idx - other.idx;
    }
}


import java.util.*;
import java.util.LinkedList;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.math.BigInteger;

public class tmp {
    public static void main(String [] args) throws Exception{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
   //     StringTokenizer st = new StringTokenizer(in.readLine());
        StringBuilder sb = new StringBuilder();

        int [] pri = new int[101];
        for(int i=2; i<=100; i++){
            if(pri[i] == 0){
                for(int j=2*i; j <= 100; j+=i)
                    pri[j]++;
            }
        }
        int zz = 0;
        for(int i=2; i<=100; i++){
            if(pri[i] >= 1)
                zz++;
        }

        String s;
        int tmp, yes = 0, cnt=0;
        int lim = 100;
        for(int i = 2; i<=lim; i++){
            if(pri[i] == 0){
                tmp = i;
                while(tmp <= lim && pri[tmp] <= 1){
                    cnt++;
                    System.out.println(tmp);
                    System.out.flush();
                    s = in.readLine();
                    if(s.equals("yes")){
                        yes++;
                        if(yes >= 2){
                            System.out.println("composite");
                            System.out.flush();
                            System.exit(0);
                        }
                        lim /= tmp;
                        tmp *= i;
                    }else{
                        break;
                    }
                }

            }
        }
        System.out.println("prime");
        System.out.flush();

    }

}

class P implements Comparable<P>{
    int val, idx;
    public P(int val, int idx){
        this.val = val;
        this.idx = idx;
    }

    public int compareTo(P other){
        if (this.val != other.val) return -this.val + other.val;
        return this.idx - other.idx;
    }
}


import java.util.*;
import java.util.LinkedList;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.math.BigInteger;

public class tmp {
    public static void main(String [] args) throws Exception{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
   //     StringTokenizer st = new StringTokenizer(in.readLine());
        StringBuilder sb = new StringBuilder();

        int [] pri = new int[101];
        for(int i=2; i<=100; i++){
            if(pri[i] == 0){
                for(int j=2*i; j <= 100; j+=i)
                    pri[j]++;
            }
        }
        int zz = 0;
        for(int i=2; i<=100; i++){
            if(pri[i] >= 1)
                zz++;
        }

        String s;
        int tmp, yes = 0, cnt=0;
        int lim = 100;
        for(int i = 2; i<=50; i++){
            if(pri[i] == 0){
                tmp = i;
                while(tmp <= 100 && pri[tmp] <= 1){
                    cnt++;
                    System.out.println(tmp);
                    System.out.flush();
                    s = in.readLine();
                    if(s.equals("yes")){
                        yes++;
                        if(yes >= 2){
                            System.out.println("composite");
                            System.out.flush();
                            System.exit(0);
                        }
                        lim /= tmp;
                        tmp *= i;
         //               System.out.println(tmp + " -- " + pri[tmp]);
                    }else{
                        break;
                    }
                }

            }
        }
        System.out.println("prime");
        System.out.flush();

    }

}

class P implements Comparable<P>{
    int val, idx;
    public P(int val, int idx){
        this.val = val;
        this.idx = idx;
    }

    public int compareTo(P other){
        if (this.val != other.val) return -this.val + other.val;
        return this.idx - other.idx;
    }
}


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

import static java.lang.System.out;

public class Tasks {

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

        new Tasks().runMain();
    }

    void runMain() {
        Scanner sc = new Scanner(System.in);

        int a[] = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
        int b[] = new int[] {53, 59, 61, 67, 71, 73, 79, 83, 89, 97};

        System.out.println(2);
        String cumul = "";

        String ans = sc.nextLine();
        cumul += ans;
        if(ans.equals("yes")) {

        } else {
            System.out.println(3);
            ans = sc.nextLine();
            cumul += ans;
        }

        System.out.print("prime");
        System.exit(0);
        sc.nextLine();

    }

}


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

import static java.lang.System.out;

public class Tasks {

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

        new Tasks().runMain();
    }

    void runMain() {
        Scanner sc = new Scanner(System.in);

        int for2[] = new int[] {3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
        int for3[] = new int[] {5, 7, 9, 11, 13, 17, 19, 23, 29, 31}; //{53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
        int for5[] = new int[] {25, 35, 55, 65, 85, 95};
        int for7[] = new int[] {49, 77, 91};

        int divide = 0;

        System.out.println(2);
        String ans = sc.nextLine();
        if(ans.equals("yes")) {
            divide++;
            for(int test : for2) {
                System.out.println(test);
                ans = sc.nextLine();
                if(ans.equals("yes")) {
                    divide++;
                }
                if(divide == 2) {
                    System.out.print("composite");
                    System.exit(0);
                }
            }
            if(divide == 1) {
                System.out.print("prime");
                System.exit(0);
            }
        }

        System.out.println(3);
        ans = sc.nextLine();
        if(ans.equals("yes")) {
            divide++;
            for(int test : for3) {
                System.out.println(test);
                ans = sc.nextLine();
                if(ans.equals("yes")) {
                    divide++;
                }
                if(divide == 2) {
                    System.out.print("composite");
                    System.exit(0);
                }
            }
            if(divide == 1) {
                System.out.print("prime");
                System.exit(0);
            }
        }

        System.out.println(5);
        ans = sc.nextLine();
        if(ans.equals("yes")) {
            divide++;
            for(int test : for5) {
                System.out.println(test);
                ans = sc.nextLine();
                if(ans.equals("yes")) {
                    divide++;
                }
                if(divide == 2) {
                    System.out.print("composite");
                    System.exit(0);
                }
            }
            if(divide == 1) {
                System.out.print("prime");
                System.exit(0);
            }
        }

        System.out.println(7);
        ans = sc.nextLine();
        if(ans.equals("yes")) {
            divide++;
            for(int test : for7) {
                System.out.println(test);
                ans = sc.nextLine();
                if(ans.equals("yes")) {
                    divide++;
                }
                if(divide == 2) {
                    System.out.print("composite");
                    System.exit(0);
                }
            }
            if(divide == 1) {
                System.out.print("prime");
                System.exit(0);
            }
        }

        if(divide == 0) {
            System.out.print("prime");
            System.exit(0);
        }

        sc.nextLine();

    }

}


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

import static java.lang.System.out;

public class Tasks {

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

        new Tasks().runMain();
    }

    void runMain() {
        Scanner sc = new Scanner(System.in);

        int for2[] = new int[] {3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
        int for3[] = new int[] {5, 7, 9, 11}; //{53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
        int for5[] = new int[] {25, 35, 55, 65, 85, 95};
        int for7[] = new int[] {49, 77, 91};

        int divide = 0;

        System.out.println(2);
        String ans = sc.nextLine();
        if(ans.equals("yes")) {
            divide++;
            for(int test : for2) {
                System.out.println(test);
                ans = sc.nextLine();
                if(ans.equals("yes")) {
                    divide++;
                }
                if(divide == 2) {
                    System.out.print("composite");
                    System.exit(0);
                }
            }
            if(divide == 1) {
                System.out.print("prime");
                System.exit(0);
            }
        }

        System.out.println(3);
        ans = sc.nextLine();
        if(ans.equals("yes")) {
            divide++;
            for(int test : for3) {
                System.out.println(test);
                ans = sc.nextLine();
                if(ans.equals("yes")) {
                    divide++;
                }
                if(divide == 2) {
                    System.out.print("composite");
                    System.exit(0);
                }
            }
            if(divide == 1) {
                System.out.print("prime");
                System.exit(0);
            }
        }

        System.out.println(5);
        ans = sc.nextLine();
        if(ans.equals("yes")) {
            divide++;
            for(int test : for5) {
                System.out.println(test);
                ans = sc.nextLine();
                if(ans.equals("yes")) {
                    divide++;
                }
                if(divide == 2) {
                    System.out.print("composite");
                    System.exit(0);
                }
            }
            if(divide == 1) {
                System.out.print("prime");
                System.exit(0);
            }
        }

        System.out.println(7);
        ans = sc.nextLine();
        if(ans.equals("yes")) {
            divide++;
            for(int test : for7) {
                System.out.println(test);
                ans = sc.nextLine();
                if(ans.equals("yes")) {
                    divide++;
                }
                if(divide == 2) {
                    System.out.print("composite");
                    System.exit(0);
                }
            }
            if(divide == 1) {
                System.out.print("prime");
                System.exit(0);
            }
        }

        if(divide == 0) {
            System.out.print("prime");
            System.exit(0);
        }

        sc.nextLine();

    }

}


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

import static java.lang.System.out;

public class Tasks {

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

        new Tasks().runMain();
    }

    void runMain() {
        Scanner sc = new Scanner(System.in);

        int a[] = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
        int b[] = new int[] {53, 59, 61, 67, 71, 73, 79, 83, 89, 97};

        System.out.println(2);
        String cumul = "";

        String ans = sc.nextLine();
        cumul += ans;
        if(ans.equals("yes")) {

        } else {
            System.out.println(3);
            ans = sc.nextLine();
            cumul += ans;
        }

        System.out.print("composite");
        //System.exit(0);
        sc.nextLine();

    }

}


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

import static java.lang.System.out;

public class Tasks {

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

        new Tasks().runMain();
    }

    void runMain() {
        Scanner sc = new Scanner(System.in);

        int a[] = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
        int b[] = new int[] {53, 59, 61, 67, 71, 73, 79, 83, 89, 97};

        System.out.println(2);
        String cumul = "";

        String ans = sc.nextLine();
        cumul += ans;
        if(ans.equals("yes")) {

        } else {
            System.out.println(3);
            ans = sc.nextLine();
            cumul += ans;
        }

        System.out.println("composite");
        System.exit(0);
        sc.nextLine();

    }

}


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

import static java.lang.System.out;

public class Tasks {

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

        new Tasks().runMain();
    }

    void runMain() {
        Scanner sc = new Scanner(System.in);

        int a[] = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
        int b[] = new int[] {53, 59, 61, 67, 71, 73, 79, 83, 89, 97};

        System.out.println(2);
        String cumul = "";

        String ans = sc.nextLine();
        cumul += ans;
        if(ans.equals("yes")) {

        } else {
            System.out.println(3);
            ans = sc.nextLine();
            cumul += ans;
        }

        System.out.println("composite");
        System.exit(1);
        sc.nextLine();

    }

}


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

public class Tasks {

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

        new Tasks().runMain();
    }

    void runMain() {
        Scanner sc = new Scanner(System.in);

        Integer for2[] = new Integer[] {3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
        Integer for3[] = new Integer[] {5, 7, 9, 11, 13, 17, 19, 23, 29, 31}; //{53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
        Integer for5[] = new Integer[] {25, 35, 55, 65, 85, 95};
        Integer for7[] = new Integer[] {49, 77, 91};

        List<Integer[]> ff = new ArrayList<Integer[]>();
        ff.add(for2);
        ff.add(for3);
        ff.add(for5);
        ff.add(for7);

        int divide = 0;
        int primes[] = new int[] {2,3,5,7};

        for(int i = 0; i < primes.length; i++) {
            System.out.println(primes[i]);
            String ans = sc.nextLine();
            if(ans.equals("yes")) {
                divide++;
                for(int test : ff.get(i)) {
                    System.out.println(test);
                    ans = sc.nextLine();
                    if(ans.equals("yes")) {
                        divide++;
                    }
                    if(divide == 2) {
                        System.out.print("composite");
                        System.exit(0);
                    }
                }
                if(divide == 1) {
                    System.out.print("prime");
                    System.exit(0);
                }
            }
        }

        if(divide == 0) {
            System.out.print("prime");
            System.exit(0);
        }

        sc.nextLine();

    }

}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.security.interfaces.DSAKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class a {

	public static class in {
		static BufferedReader reader;
		static StringTokenizer tokenizer;

		static void init(InputStream input) throws FileNotFoundException {
			// reader = new BufferedReader(new
			// FileReader("B-small-attempt4.in"));
			reader = new BufferedReader(new InputStreamReader(input));
			tokenizer = new StringTokenizer("");
		}

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

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

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

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

	public static long comp(int n, int r) {
		r = Math.min(r, n - r);
		long ans = 1;
		for (int i = 1; i <= r; i++) {
			ans = ans * (long) (n - r + i) / (long) i;
		}
		return ans;

	}

	public static class node {

		int st;
		int end;
		int p;

		node(int st, int end, int p) {
			this.st = st;
			this.end = end;
			this.p = p;

		}

	}

	public static long gcd(int x, int y) {
		if (y == 0)
			return x;
		return gcd(y, x % y);
	}

	public static int tree[];

	public static void add(int idx, long val, int n, int tree[]) {

		while (idx <= n) {
			tree[idx] += val;
			idx += (idx & -idx);
		}
	}

	public static int get(int idx) {
		int g = 0;
		while (idx > 0) {

			g += tree[idx];
			idx -= (idx & -idx);
		}

		return g;
	}

	public static class point implements Comparable<point> {
		int min;
		int a;
		int b;

		point(int min, int a, int b) {
			this.min = min;
			this.a = a;
			this.b = b;
		}

		@Override
		public int compareTo(point o) {
			if (o.min > min)
				return 1;
			else if (o.min < min)
				return -1;
			return 0;
		}
	}

	// for bad input
	static String ReadLn(int maxLg) {
		byte lin[] = new byte[maxLg];
		int lg = 0, car = -1;
		String line = "";

		try {
			while (lg < maxLg) {
				car = System.in.read();
				if ((car < 0) || (car == '\n'))
					break;
				lin[lg++] += car;
			}
		} catch (IOException e) {
			return (null);
		}

		if ((car < 0) && (lg == 0))
			return (null);
		return (new String(lin, 0, lg));
	}

	// IMPORT LIBRARY PACKAGES NEEDED BY YOUR PROGRAM
	// SOME CLASSES WITHIN A PACKAGE MAY BE RESTRICTED
	// DEFINE ANY CLASS AND METHOD NEEDED
	// LNode CLASS IS DEFINED BY DEFAULT
	// CLASS BEGINS, THIS CLASS IS REQUIRED

	public class LNode {
		public int value;
		public LNode next;

	}

	public static class ReverseLinkedList {
		// METHOD SIGNATURE BEGINS, THIS METHOD IS REQUIRED
		public static LNode reverseLinkedList(LNode list) {
			// INSERT YOUR CODE HERE
			int n = 0;
			LNode pointer = list;
			while (pointer != null) {
				n++;
				pointer = pointer.next;
			}

			int mid = (n + 1) / 2;
			if (n % 2 == 1)
				mid--;
			LNode arr[] = new LNode[n - mid];
			pointer = list;
			int p = 0;
			int c = 0;
			while (pointer != null) {

				if (c >= mid) {
					arr[p++] = pointer;
				}
				c++;
				pointer = pointer.next;
			}
			LNode swap = null;
			for (int i = 0; i < (n - mid) / 2; i++) {
				swap = arr[i];
				arr[i] = arr[n - mid - 1 - i];
				arr[n - mid - 1 - i] = swap;
			}

			pointer = list;
			p = 0;
			c = 0;
			while (pointer != null) {

				if (c >= mid - 1) {
					pointer.next = arr[p++];
				}
				c++;
				pointer = pointer.next;
			}

			return list;
		}
		// METHOD SIGNATURE ENDS
	}

	public static class points implements Comparable<points> {

		int dur;
		int idx;

		points(int d, int i) {
			dur = d;
			idx = i;
		}

		@Override
		public int compareTo(points o) {
			if (o.dur < dur)
				return 1;
			else if (o.dur > dur)
				return -1;
			else if (o.idx < idx)
				return 1;
			else
				return -1;

		}
	}

	public static ArrayList<Integer> prime;

	public static void prime(int x) {
		prime = new ArrayList();
		boolean vis[] = new boolean[x + 1];
		for (int i = 2; i * i <= x; i++) {
			if (!vis[i]) {
				for (long j = (long) i * (long) i; j <= x; j += i) {
					vis[(int) j] = true;
				}
			}
		}
		int c = 0;
		for (int i = 2; i <= x; i++) {
			if (!vis[i]) {
				prime.add(i);
				c++;
			}
			if (c == 20)
				break;
		}
	}

	public static void main(String[] args) throws IOException {
		// StringBuilder qq = new StringBuilder();
		in.init(System.in);
		PrintWriter out = new PrintWriter(System.out);
		BufferedReader inp = new BufferedReader(
				new InputStreamReader(System.in));
		prime(100);
		String x;
		int c = 0;
		int p = 0;
		while (p < 20) {
			x = in.next();
			if (x.charAt(0) == 'y')
				c++;
			System.out.println(prime.get(p++));
			System.out.flush();
		}
		if (c > 1)
			System.out.println("composite");

		else
			System.out.println("prime");
		System.out.flush();
		out.close();

	}
}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.security.interfaces.DSAKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class a {

	public static class in {
		static BufferedReader reader;
		static StringTokenizer tokenizer;

		static void init(InputStream input) throws FileNotFoundException {
			// reader = new BufferedReader(new
			// FileReader("B-small-attempt4.in"));
			reader = new BufferedReader(new InputStreamReader(input));
			tokenizer = new StringTokenizer("");
		}

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

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

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

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

	public static long comp(int n, int r) {
		r = Math.min(r, n - r);
		long ans = 1;
		for (int i = 1; i <= r; i++) {
			ans = ans * (long) (n - r + i) / (long) i;
		}
		return ans;

	}

	public static class node {

		int st;
		int end;
		int p;

		node(int st, int end, int p) {
			this.st = st;
			this.end = end;
			this.p = p;

		}

	}

	public static long gcd(int x, int y) {
		if (y == 0)
			return x;
		return gcd(y, x % y);
	}

	public static int tree[];

	public static void add(int idx, long val, int n, int tree[]) {

		while (idx <= n) {
			tree[idx] += val;
			idx += (idx & -idx);
		}
	}

	public static int get(int idx) {
		int g = 0;
		while (idx > 0) {

			g += tree[idx];
			idx -= (idx & -idx);
		}

		return g;
	}

	public static class point implements Comparable<point> {
		int min;
		int a;
		int b;

		point(int min, int a, int b) {
			this.min = min;
			this.a = a;
			this.b = b;
		}

		@Override
		public int compareTo(point o) {
			if (o.min > min)
				return 1;
			else if (o.min < min)
				return -1;
			return 0;
		}
	}

	// for bad input
	static String ReadLn(int maxLg) {
		byte lin[] = new byte[maxLg];
		int lg = 0, car = -1;
		String line = "";

		try {
			while (lg < maxLg) {
				car = System.in.read();
				if ((car < 0) || (car == '\n'))
					break;
				lin[lg++] += car;
			}
		} catch (IOException e) {
			return (null);
		}

		if ((car < 0) && (lg == 0))
			return (null);
		return (new String(lin, 0, lg));
	}

	// IMPORT LIBRARY PACKAGES NEEDED BY YOUR PROGRAM
	// SOME CLASSES WITHIN A PACKAGE MAY BE RESTRICTED
	// DEFINE ANY CLASS AND METHOD NEEDED
	// LNode CLASS IS DEFINED BY DEFAULT
	// CLASS BEGINS, THIS CLASS IS REQUIRED

	public class LNode {
		public int value;
		public LNode next;

	}

	public static class ReverseLinkedList {
		// METHOD SIGNATURE BEGINS, THIS METHOD IS REQUIRED
		public static LNode reverseLinkedList(LNode list) {
			// INSERT YOUR CODE HERE
			int n = 0;
			LNode pointer = list;
			while (pointer != null) {
				n++;
				pointer = pointer.next;
			}

			int mid = (n + 1) / 2;
			if (n % 2 == 1)
				mid--;
			LNode arr[] = new LNode[n - mid];
			pointer = list;
			int p = 0;
			int c = 0;
			while (pointer != null) {

				if (c >= mid) {
					arr[p++] = pointer;
				}
				c++;
				pointer = pointer.next;
			}
			LNode swap = null;
			for (int i = 0; i < (n - mid) / 2; i++) {
				swap = arr[i];
				arr[i] = arr[n - mid - 1 - i];
				arr[n - mid - 1 - i] = swap;
			}

			pointer = list;
			p = 0;
			c = 0;
			while (pointer != null) {

				if (c >= mid - 1) {
					pointer.next = arr[p++];
				}
				c++;
				pointer = pointer.next;
			}

			return list;
		}
		// METHOD SIGNATURE ENDS
	}

	public static class points implements Comparable<points> {

		int dur;
		int idx;

		points(int d, int i) {
			dur = d;
			idx = i;
		}

		@Override
		public int compareTo(points o) {
			if (o.dur < dur)
				return 1;
			else if (o.dur > dur)
				return -1;
			else if (o.idx < idx)
				return 1;
			else
				return -1;

		}
	}

	public static ArrayList<Integer> prime;

	public static void prime(int x) {
		prime = new ArrayList();
		boolean vis[] = new boolean[x+1];
		for (int i = 2; i * i <= x; i++) {
			if (!vis[i]) {
				for (long j = (long) i * (long) i; j <= x; j += i) {
					vis[(int) j] = true;
				}
			}
		}
		int c = 0;
		for (int i = 2; i <= x; i++) {
			if (!vis[i]) {
				prime.add(i);
				c++;
			}
			if (c == 20)
				break;
		}
	}

	public static void main(String[] args) throws IOException {
		// StringBuilder qq = new StringBuilder();
		in.init(System.in);
		PrintWriter out = new PrintWriter(System.out);
		BufferedReader inp = new BufferedReader(
				new InputStreamReader(System.in));
		prime(100);
		String x;
		int c = 0;
		int p = 0;
		while ((x = inp.readLine()) != null) {
			if (x.charAt(0) == 'y')
				c++;
			out.println(prime.get(p++));
			out.flush();
		}
		if (c > 1)
			out.println("composite");

		else
			out.println("prime");
		out.flush();
		out.close();

	}
}


// InterestingLSY
// codeforces&github: interestingLSY, qq: 2659723130
// 《幽灵公主》是真的好看！
#ifdef intLSY
#include <intlsy/stdc++.h>
#else
#include <bits/stdc++.h>
#endif
#include <bits/c++0x_warning.h>
using namespace std;
#define il inline
#define elif else if

// Type
#define ld double
#define ll long long
#define ull unsigned ll

// Vector
#define vc vector
#define Pb push_back
#define Pf push_front
#define Eb emplace_back
#define All(x) x.begin(),x.end()
#define AllRev(x) x.rbegin(),x.rend()

// Memory
#define Ms(_data) memset(_data,0,sizeof(_data))
#define Msn(_data,_num) memset(_data,_num,sizeof(_data))

// Pair
#define F first
#define S second
#define pii pair<int,int>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define pll pair<ll,ll>

// Loop
#define For(i,j) for( int (i) = 1 ; (i) <= (j) ; ++(i) )
#define For0(i,j) for( int (i) = 0 ; (i) < (j) ; ++(i) )
#define Forx(i,j,k) for( int (i) = (j) ; (i) <= (k) ; ++(i) )
#define Forstep(i,j,k,st) for( int (i) = (j) ; (i) <= (k) ; (i) += (st) )
#define fOR(i,j) for( int (i) = (j) ; (i) >= 1 ; --(i) )
#define fOR0(i,j) for( int (i) = (j)-1 ; (i) >= 0 ; --(i) )
#define fORx(i,j,k) for( int (i) = (k) ; (i) >= (j) ; --(i) )

// Read
struct InputReader{
	static constexpr int MAXSZ = 1048576;
	char buf[MAXSZ]; int p, ed;
	bool detectedEOF = false;
	il InputReader(){ p = MAXSZ; }
	il void Flush(){ p = 0; ed = fread(buf,1,MAXSZ,stdin); }
	il void GetChar( char &c ){
		if(p >= MAXSZ) Flush();
		if( p == ed ){ detectedEOF = true; }
		c = buf[p++];
	}
	il void ReadNum( char &c ){ GetChar(c); while( !isdigit(c) && c != '-' && !detectedEOF ) GetChar(c); }
	il void ReadAlpha( char &c ){ GetChar(c); while( !isalpha(c) && !detectedEOF ) GetChar(c); }
	il void ReadInt( int &ans ){
		ans = 0; int nega = 1;
		char c; ReadNum(c); if(detectedEOF) return;
		if( c == '-' ){
			nega = -1;
			GetChar(c);
		}
		while( isdigit(c) && !detectedEOF ){
			ans = ans*10 + c-'0';
			GetChar(c);
		}
		ans *= nega;
	}
	il void Readll( ll &ans ){
		ans = 0; int nega = 1;
		char c; ReadNum(c); if(detectedEOF) return;
		if( c == '-' ){
			nega = -1;
			GetChar(c);
		}
		while( isdigit(c) && !detectedEOF ){
			ans = ans*10 + c-'0';
			GetChar(c);
		}
		ans *= nega;
	}
	il void ReadString( string &x ){
		x.clear(); char ch; GetChar(ch);
		while( !isdigit(ch) && !isalpha(ch) && ch != '#' && ch != '.' && !detectedEOF ) GetChar(ch); if(detectedEOF) return;
		while( (isdigit(ch) || isalpha(ch) || ch == '#' || ch == '.') && !detectedEOF ){
			x += ch;
			GetChar(ch);
		}
	}
	il void ReadCString( char s[] ){
		int len = 0; char ch; GetChar(ch);
		while( !isdigit(ch) && !isalpha(ch) && ch != '#' && ch != '.' && !detectedEOF ) GetChar(ch); if(detectedEOF) return;
		while( (isdigit(ch) || isalpha(ch) || ch == '#' || ch == '.') && !detectedEOF ){
			s[len++] = ch;
			GetChar(ch);
		}
		s[len] = '\0';
	}
	il void SpecialRead( char &c ){
		GetChar(c); if(detectedEOF) return;
		while( !isdigit(c) && !isalpha(c) && c != '#' && c != '.' && c != '=' && c != 'B' && !detectedEOF ) GetChar(c);
	}
}In;
il void Read( int &x ){ In.ReadInt(x); }
il void Read( int &x, int &y ){ In.ReadInt(x); In.ReadInt(y); }
il void Read( int &x1 , int &x2 , int &x3 ){ In.ReadInt(x1); In.ReadInt(x2); In.ReadInt(x3); }
il void Read( int &x1 , int &x2 , int &x3 , int &x4 ){ In.ReadInt(x1); In.ReadInt(x2); In.ReadInt(x3); In.ReadInt(x4); }
il void Read( ll &x ){ In.Readll(x); }
il void Read( ll &x, ll &y ){ In.Readll(x); In.Readll(y); }
il void Read( ll &x1 , ll &x2 , ll &x3 ){ In.Readll(x1); In.Readll(x2); In.Readll(x3); }
il void Read( ll &x1 , ll &x2 , ll &x3 , ll &x4 ){ In.Readll(x1); In.Readll(x2); In.Readll(x3); In.Readll(x4); }
template<typename T> void Read( T a[] , int st , int ed ){ Forx(i,st,ed) Read(a[i]); }
#define iRead(k) int k; Read(k);
#define iRead2(a,b) iRead(a); iRead(b);
#define iRead3(a,b,c) iRead2(a,b); iRead(c);
#define iRead4(a,b,c,d) iRead2(a,b); iRead2(c,d);
#define lRead(k) ll k; Read(k);
#define lRead2(a,b) lRead(a); lRead(b);
#define lRead3(a,b,c) lRead2(a,b); lRead(c);
#define lRead4(a,b,c,d) lRead2(a,b); lRead2(c,d);

// File
#define Fin(a) freopen(a,"r",stdin)
#define Fout(a) freopen(a,"w",stdout)
il void FILEIO(){
	#ifdef intLSY
		Fin("in.in");
	#endif
}
il void FILEIO( string pname ){
	#ifndef intLSY
		Fin((pname+".in").c_str());
		Fout((pname+".out").c_str());
	#else
		Fin("in.in");
	#endif
}
il void FILEIO_OICONTEST( string pname ){
	Fin((pname+".in").c_str());
	#ifndef intLSY
		Fout((pname+".out").c_str());
	#endif
}
void Printtime(){
	#ifdef intLSY
		double _timeuse = clock()* 1000.0 / CLOCKS_PER_SEC;
		fprintf(stderr,"\n\nTime usage:\n%.0lf ms\n",_timeuse);
	#endif
}
void END(){ Printtime(); exit(0); }
template<typename T>void END( T mes ){ cout << mes << endl; END(); }

// Debug
#define B cerr << "BreakPoint" << endl;
#define O(x) cerr << #x << " " << (x) << endl;
#define o(x) cerr << #x << " " << (x) << "  ";
template<typename T0>
void P( T0 t0 ){
	cerr << t0 << endl;
}
template<typename T0, typename... Ts>
void P( T0 t0 , Ts... ts ){
	cerr << t0 << " ";
	P(ts...);
}
#define Msz(x) cerr << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
template<typename T>void Print( T a[] , int s , int t , char sp = ' ' , char ed = '\n' ){
	if( s > t ) return;
	for( int i = s ; i < t ; i++ )
		cout << a[i] << sp;
	cout << a[t] << ed;
	cout.flush();
}
template<typename T>void Print( T a , int s = 0 , int t = -1 , char sp = ' ' , char ed = '\n' ){
	if( t == -1 ) t = a.size()-1;
	for( int i = s ; i <= t ; i++ )
		cout << a[i] << sp;
	cout << ed;
	cout.flush();
}

// Optimize
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define Mymax(a,b) (a) = max((a),(b))
#define Mymin(a,b) (a) = min((a),(b))
#define MyMax(a,b) (a) = Max((a),(b))
#define MyMin(a,b) (a) = Min((a),(b))
#define INF (0x3f3f3f3f)
#define LINF ((long long)(0x3f3f3f3f3f3f3f3f))
#define Sqr(x) ((x)*(x))
#define Lowbit(a) ((a)&(-(a)))
constexpr int MOD = 1'000'000'007;
#define Rmoi(a,b) (((a)%b+b)%b)
#define Rmo(a) (((a)%MOD+MOD)%MOD)
#define Rmod(a) a = ((a%MOD+MOD)%MOD)
#define Rmodi(a,b) a = ((a%(b)+(b))%(b))
#define Mymoi(a,b) ((a)>=b?((a)-b):(a))
#define Mymodi(a,b) a = ((a)>=(b))?((a)-(b)):(a)
template<typename T>
il T Mymo( const T &x ){ return x >= MOD ? x-MOD : x; }
template<typename T>
il void Mymod( T &x ){ x = x >= MOD ? x-MOD : x; }
template<typename T1, typename T2>
il void Addi( T1 &x , const T2 &y ){ x = Mymo(x+y); }
template<typename T1, typename T2>
il void Deci( T1 &x , const T2 &y ){ x = Mymo(x-y+MOD); }
template<typename T1, typename T2>
il void Muli( T1 &x , const T2 &y ){ x = 1LL*x*y%MOD; }
il ll Pow( ll a , ll b , const ll p = MOD ){
	ll ret = 1;
	for( ; b ; a = a*a%p, b >>= 1 )
		if(b&1) ret = ret*a%p;
	return ret;
}
il ll Inv( ll a , const ll p = MOD ){ return Pow(a,p-2LL,p); }
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
constexpr int MAXN = 1048576;

int n;
string s;

struct PAM{
	struct Node{
		int to[26];
		int fa;
		int len;
		int nextArith;
		int arithDiff;
		int arithSum;
	};
	#define To(pos,c) t[pos].to[c]
	#define Fa(pos) t[pos].fa
	#define Len(pos) t[pos].len
	#define NextArith(pos) t[pos].nextArith
	#define ArithDiff(pos) t[pos].arithDiff
	#define ArithSum(pos) t[pos].arithSum
	Node t[MAXN];
	int nowNode = 0;
	int lastNode = 1;

	void Init(){
		Len(1) = -1;
		Len(2) = 0;
		Fa(2) = 1;
		nowNode = 2;
	}

	void AppendChar( int i ){
		const char c = s[i];
		int p = lastNode;
		while( s[i-Len(p)-1] != c ) p = Fa(p);
		if(!To(p,c)){
			To(p,c) = ++nowNode;
			Len(To(p,c)) = Len(p) + 2;
		}
		int cur = To(p,c);
		lastNode = cur;

		if( p == 1 ) Fa(cur) = 2;
		else{
			p = Fa(p);
			while( s[i-Len(p)-1] != c ) p = Fa(p);
			assert(To(p,c));
			Fa(cur) = To(p,c);
		}

		ArithDiff(cur) = Len(cur) - Len(Fa(cur));
		if( ArithDiff(cur) == ArithDiff(Fa(cur)) )
			NextArith(cur) = NextArith(Fa(cur));
		else
			NextArith(cur) = Fa(cur);
	}

	ll Solve(){
		static ll dp[MAXN];
		dp[0] = 1;
		For(i,n){
			AppendChar(i);
			static vc<int> tmp; tmp.clear();
			for( int p = lastNode ; Len(p) > 0 ; p = NextArith(p) )
				tmp.Eb(p);
			for_each(AllRev(tmp),[&]( int p ){
				ArithSum(p) = dp[i-Len(NextArith(p))-ArithDiff(p)];
				if( ArithDiff(Fa(p)) == ArithDiff(p) ){
					Addi( ArithSum(p) , ArithSum(Fa(p)) );
				}
				if(i&1^1) Addi(dp[i],ArithSum(p));
			});
		}
		return dp[n];
	}
};
PAM pam;

void Readin(){
	static string t;
	In.ReadString(t);
	n = t.length();
	s = " ";
	int lp = 0, rp = n-1;
	For(i,n){
		if(i&1){ s += t[lp]; ++lp; }
		else{ s += t[rp]; --rp; }
	}
	// O(s);
	for( auto &c : s ) if( c != ' ' ) c -= 'a';
}

int main(){
	FILEIO();

	Readin();

	pam.Init();
	ll ans = pam.Solve();
	cout << ans << endl;

	END();
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1000005 ;
const int N = 26 ;
ll f[MAXN],g[MAXN];
const ll mod=1e9+7;
struct Palindromic_Tree {
    int next[MAXN][N] ;//next指针，next指针和字典树类似，指向的串为当前串两端加上同一个字符构成
    int fail[MAXN] ;//fail指针，失配后跳转到fail指针指向的节点
    int cnt[MAXN] ;
    int num[MAXN] ;
    int len[MAXN] ;//len[i]表示节点i表示的回文串的长度
    int S[MAXN] ;//存放添加的字符
    int last ;//指向上一个字符所在的节点，方便下一次add
    int n ;//字符数组指针
    int p ;//节点指针
    int delta[MAXN],start[MAXN];
    int newnode ( int l ) {//新建节点
        for ( int i = 0 ; i < N ; ++ i ) next[p][i] = 0 ;
        cnt[p] = 0 ;
        num[p] = 0 ;
        len[p] = l ;
        return p ++ ;
    }

    void init () {//初始化
        p = 0 ;
        newnode (  0 ) ;
        newnode ( -1 ) ;
        last = 0 ;
        n = 0 ;
        S[n] = -1 ;//开头放一个字符集中没有的字符，减少特判
        fail[0] = 1 ;
    }

    int get_fail ( int x ) {//和KMP一样，失配后找一个尽量最长的
        while ( S[n - len[x] - 1] != S[n] ) x = fail[x] ;
        return x ;
    }

    void add (int i,int c ) {
        c -= 'a' ;
        S[++ n] = c ;
        int cur = get_fail ( last ) ;//通过上一个回文串找这个回文串的匹配位置
        if ( !next[cur][c] ) {//如果这个回文串没有出现过，说明出现了一个新的本质不同的回文串
            int now = newnode ( len[cur] + 2 ) ;//新建节点
            fail[now] = next[get_fail ( fail[cur] )][c] ;//和AC自动机一样建立fail指针，以便失配后跳转
            next[cur][c] = now ;
            num[now] = num[fail[now]] + 1 ;
            delta[now]=len[now]-len[fail[now]];
            if(delta[now]==delta[fail[now]]) start[now]=start[fail[now]];
            else start[now]=now;
        }
        last = next[cur][c] ;
        for(int j=last;j>=1;j=fail[start[j]]){
            g[j]=f[i-len[start[j]]];
            if(start[j]!=j) g[j]=(g[j]+g[fail[j]])%mod;
            if(i%2==0) f[i]=(f[i]+g[j])%mod;
        }
        cnt[last] ++ ;

    }

    void count () {
        for ( int i = p - 1 ; i >= 0 ; -- i ) cnt[fail[i]] += cnt[i] ;
        //父亲累加儿子的cnt，因为如果fail[v]=u，则u一定是v的子回文串！
    }
}P;
char s[MAXN],str[MAXN];
int main(){
    scanf("%s",str);
    int n=strlen(str);
    int num=0;
    for (int i=1;i<=n;i+=2) s[i]=str[num++];
    num=n-1;
    for (int i=2;i<=n;i+=2) s[i]=str[num--];
    f[0]=1;
    P.init();
    for(int i=1;i<=n;i++){
        //printf("!\n");
        P.add(i,s[i]);

    }
    printf("%lld",f[n]);
}


// They can't break me, as long as I know who I am...

#include<bits/stdc++.h>

#define F first
#define S second
#define PB push_back
#define sz(s) int((s).size())
#define bit(n,k) (((n)>>(k))&1)

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

const int maxn = 1e6 + 10, mod = 1e9 + 7;
const int inf = 1e9;

int nxt[maxn][26];
int f[maxn], fb[maxn], ln[maxn], df[maxn], dpv[maxn], C;
int str[maxn], n;
int lst;

void mkay(int &a, int b){
    a = (a + b) %mod;
}
int loop(int tmp){
    while(tmp != -1 && str[ n - ln[tmp] -1 ] != str[n] )
	tmp = f[tmp];
    return tmp;
}
void add_char(char ch){
    int c = ch - 'a';
    str[++n] = c;
    lst = loop(lst);
    if( lst == -1){
	lst = 0;
	return;
    }
    if( nxt[lst][c] == 0 ){
	nxt[lst][c] = ++C;
	if( f[lst] == -1 || loop( f[lst] ) == -1 )
	    f[C] = 0;
	else
	    f[C] = nxt[ loop( f[lst] ) ][ c ];
	ln[C] = ln[lst] + 2;
	df[C] = ln[C] - ln[ f[C] ];
	fb[C] = df[C] == df[ f[C] ] ? fb[ f[C] ] : f[C];
    }
    lst = nxt[lst][c];
}

int dp[maxn];

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie();

    str[0] = -1;
    f[0] = -1;
    df[0] = -1;

    string ss, s; cin>>ss;
    for(int i = 0; 2 * i < sz(ss); i++){
	s+= ss[i];
	s+= ss[sz(ss)-1-i];
    }

    dp[0] = 1;
    for(int i = 1; i <= sz(s); i++){
	add_char( s[i-1] );
	dp[i] = 0;
	if(i & 1)
	    continue;
	for(int vert = lst; vert != 0; vert = fb[vert]){
	    int x = dp[ i - ln[ fb[ vert ] ] - df[vert] ];
	    if( df[vert] == df[ f[vert] ] )
		mkay(x, dpv[ f[vert] ] );
	    dpv[ vert ] = x;
	    mkay( dp[i], x );
	}
    }
    return cout << dp[n] << endl, 0;
}
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")


#include<bits/stdc++.h>
using namespace std;
const int N=1001000,mo=1e9+7;
int fa[N],ch[N][26],len[N],dif[N],anc[N],las=1,n;
int f[N],g[N],tot;
char ss[N],st[N];
int A(int x,int y){return (x+y)%mo;}
int M(int x,int y){return 1ll*x*y%mo;}
void pre()
{
    tot=1;
    len[1]=-1;
    fa[0]=fa[1]=1;
    anc[0]=1;
}
void add(int c,int id)
{
    int p = las;
    while(ss[id-len[p]-1]!=ss[id]) p=fa[p];
    if(!ch[p][c]) {
        int np = ++tot;
        len[np]=len[p]+2;
        int q=fa[p];
        while(ss[id-len[q]-1]!=ss[id]) q=fa[q];
        fa[np]=ch[q][c];
        ch[p][c]=np;
        dif[np]=len[np]-len[fa[np]];
        anc[np]=dif[np]==dif[fa[np]]?anc[fa[np]]:fa[np];
    }
    las=ch[p][c];
}
int main()
{
    scanf("%s",st+1);
    n=strlen(st+1);
    for(int i=1;i<=n;i++) {
        if(i&1) ss[i]=st[i/2+1];
        else ss[i]=st[n-i/2+1];
    }
    f[0]=1;
    pre();
    for(int i=1;i<=n;i++) {
        add(ss[i]-'a',i);
        for(int k=las;k!=1;k=anc[k]) {
            if(fa[k]!=anc[k]) g[k] = A(g[fa[k]],f[i-dif[k]-len[anc[k]]]);
            else g[k] = f[i-dif[k]-len[anc[k]]];
            if(!(i&1)) f[i]=A(f[i],g[k]);
        }
    }
    cout<<f[n]<<'\n';
}


#include<bits/stdc++.h>
using namespace std;

#define pii pair<int,int>
#define pll pair<ll,ll>
#define eb emplace_back
#define ll long long
#define nl '\n'
#define deb(x) cerr<<#x" = "<<x<<nl
#define in() ( { int a ; scanf("%d",&a); a; } )

const int N = 1e6 + 9;
const int mod = 1e9 + 7;

/*
# series link will lead from the vertex v to the vertex u corresponding
  to the maximum suffix palindrome of v which satisfies diff(v) != diff(u)
# path within series links to the root contains only O(log n) vertices
# let us consider a suffix palindrome v s.t. link(v) != slink(v).
  Then, the previous occurrence of link(v) in the string was in position i - diff(v)
*/
int ans[N], series_ans[N];
struct PalindromicTree
{
    struct node
    {
        int nxt[26], len, st, en, suflink, diff, slink;
        int cnt;            //number of palindromic suffixes of this node
        int oc;             //stores the number of occurrences of the node
    };
    string s;
    vector<node> t;
    int sz, suf;
    void init(int len)
    {
        t.clear(); t.resize(len + 9);
        sz = 2, suf = 2;
        t[1].len = -1, t[1].suflink = 1;
        t[2].len = 0, t[2].suflink = 1;
        t[1].diff = t[2].diff = 0;
        t[1].slink = 1; t[2].slink = 2;
    }
    // returns 1 if it creates a new palindrome
    int add_letter(int pos)
    {
        int cur = suf, curlen = 0;
        int ch = s[pos] - 'a';
        while(1){
            curlen = t[cur].len;
            if(pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) break;
            cur = t[cur].suflink;
        }
        if(t[cur].nxt[ch]){
            suf = t[cur].nxt[ch];
            t[suf].oc++;
            return 0;
        }
        sz++; suf = sz;
        t[sz].oc = 1;
        t[sz].len = t[cur].len + 2;
        t[cur].nxt[ch] = sz;
        t[sz].en = pos;
        t[sz].st = pos-t[sz].len+1;
        if(t[sz].len == 1){
            t[sz].suflink = 2;
            t[sz].cnt = 1;
            t[sz].diff = 1;
            t[sz].slink = 2;
            return 1;
        }
        while(1){
            cur = t[cur].suflink;
            curlen = t[cur].len;
            if(pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]){
                    t[sz].suflink = t[cur].nxt[ch];
                    break;
            }
        }
        t[sz].cnt = 1 + t[t[sz].suflink].cnt;
        t[sz].diff = t[sz].len - t[t[sz].suflink].len;
        if(t[sz].diff == t[t[sz].suflink].diff) t[sz].slink = t[t[sz].suflink].slink;
        else t[sz].slink = t[sz].suflink;
        return 1;
    }
    int build(string &p)
    {
        s = p;
        int n = p.size();
        int tot = 0;
        for(int i = 0; i < n; i++) tot += add_letter(i);
        return tot;
    }
    void calc_oc()
    {
        for(int i = sz;i >= 3; i--) t[t[i].suflink].oc += t[i].oc;
    }
    void calc_dp(int i) //call it after adding each letter s[i], i = 1 indexed
    {
        for(int v = suf; t[v].len > 0; v = t[v].slink)
        {
            series_ans[v] = ans[i - (t[t[v].slink].len + t[v].diff)];
            if(t[v].diff == t[t[v].suflink].diff) series_ans[v] = (series_ans[v] + series_ans[t[v].suflink]) % mod;
            if(i % 2 == 0) ans[i] = (ans[i] + series_ans[v]) % mod;
        }
    }
}t;

int32_t main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    string p; cin >> p;
    string s = "";
    int n = p.size();
    for(int i = 0, j = n - 1; i <= j; i++, j--) s += p[i], s += p[j];
    t.init(n); t.s = s;
    ans[0] = 1;
    for(int i = 0; i < n; i++){
        t.add_letter(i);
        t.calc_dp(i + 1);
    }
    cout << ans[n] << nl;
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
inline int read()
{
	int sum=0,p=1;char ch=getchar();
	while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
	if(ch=='-')p=-1,ch=getchar();
	while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
	return sum*p;
}

const int maxn=1e6+20;
const int mod=1e9+7;

int n;
char str[maxn],s[maxn];

struct Palineromic_Tree {
	int last,len[maxn],tot,ch[maxn][26],fail[maxn],diff[maxn],top[maxn];
	inline void init(){ len[tot=1]=-1;fail[0]=fail[1]=1;top[1]=top[0]=1;diff[1]=1;}
	inline void add(int n,char *s){
		int p=last;
		int x=s[n]-'a';
		while(s[n-len[p]-1]!=s[n])p=fail[p];
		if(!ch[p][x])
		{
			int np=++tot,q=fail[p];
			len[np]=len[p]+2;
			while(s[n-len[q]-1]!=s[n])q=fail[q];
			fail[np]=ch[q][x];ch[p][x]=np;
			diff[np]=len[np]-len[fail[np]];
			if(diff[np]==diff[fail[np]])top[np]=top[fail[np]];
			else top[np]=fail[np];
		}
		last=ch[p][x];
	}
}A;

int dp[maxn],g[maxn];

inline void init()
{
	scanf("%s",str+1);
	n=strlen(str+1);
	REP(i,1,n/2)s[i*2-1]=str[i];
	DREP(i,n,n/2+1)s[(n-i+1)*2]=str[i];
	A.init();
	dp[0]=1;
	REP(i,1,n)
	{
		A.add(i,s);
		for(int u=A.last;u;u=A.top[u])
		{
			g[u]=dp[i-A.len[A.top[u]]-A.diff[u]];
			if(A.diff[u]==A.diff[A.fail[u]])g[u]=(g[u]+g[A.fail[u]])%mod;
			dp[i]=(dp[i]+g[u])%mod;
		}
		if(i&1)dp[i]=0;
	}
	printf("%d\n",dp[n]);
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("pp.in","r",stdin);
	freopen("pp.out","w",stdout);
#endif
	init();
 	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
inline int read()
{
	int sum=0,p=1;char ch=getchar();
	while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
	if(ch=='-')p=-1,ch=getchar();
	while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
	return sum*p;
}

const int maxn=1e6+20;
const int mod=1e9+7;

int n;
char str[maxn],s[maxn];

struct Palineromic_Tree {
	int last,len[maxn],tot,ch[maxn][26],fail[maxn],diff[maxn],top[maxn];
	inline void init(){ len[tot=1]=-1;fail[0]=fail[1]=1;top[1]=top[0]=1;}
	inline void add(int n,char *s){
		int p=last;
		int x=s[n]-'a';
		while(s[n-len[p]-1]!=s[n])p=fail[p];
		if(!ch[p][x])
		{
			int np=++tot,q=fail[p];
			len[np]=len[p]+2;
			while(s[n-len[q]-1]!=s[n])q=fail[q];
			fail[np]=ch[q][x];ch[p][x]=np;
			diff[np]=len[np]-len[fail[np]];
			if(diff[np]==diff[fail[np]])top[np]=top[fail[np]];
			else top[np]=fail[np];
		}
		last=ch[p][x];
	}
}A;

int dp[maxn],g[maxn];

inline void init()
{
	scanf("%s",str+1);
	n=strlen(str+1);
	REP(i,1,n/2)s[i*2-1]=str[i];
	DREP(i,n,n/2+1)s[(n-i+1)*2]=str[i];
	A.init();
	dp[0]=1;
	REP(i,1,n)
	{
		A.add(i,s);
		for(int u=A.last;u>1;u=A.top[u])
		{
			g[u]=dp[i-A.len[A.top[u]]-A.diff[u]];
			if(A.diff[u]==A.diff[A.fail[u]])g[u]=(g[u]+g[A.fail[u]])%mod;
			dp[i]=(dp[i]+g[u])%mod;
		}
		if(i&1)dp[i]=0;
	}
	printf("%d\n",dp[n]);
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("pp.in","r",stdin);
	freopen("pp.out","w",stdout);
#endif
	init();
 	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=3e5+7;
const int M=N<<1;
ll mod=1e9+7;
//dif表示节点u和fa[u]所代表的回文串的长度差
//slink表示u所在等差数列中长度最小的那个节点
//g表示u所在等差数列的dp值之和(或最小)
struct pam{
    int t[N][26],fa[N],len[N],rs[N],cnt[N],num[N];
    int dif[N],slink[N];
    int sz,n,last;
    int _new(int l){
        len[sz]=l;cnt[sz]=num[sz]=0;
        return sz++;
    }
    void init(){
        memset(t,0,sz*sizeof(t[0]));
        rs[n=sz=0]=-1;
        last=_new(0);//even
        fa[last]=_new(-1);//odd
    }
    int get_fa(int x){
        while(rs[n-1-len[x]]!=rs[n]) x=fa[x];
        return x;
    }
    void ins(int ch){
        rs[++n]=ch;
        int p=get_fa(last);
        if(!t[p][ch]){
            int np=_new(len[p]+2);
            num[np]=num[fa[np]=t[get_fa(fa[p])][ch]]+1;
            t[p][ch]=np;
            dif[np]=len[np]-len[fa[np]];
            if(dif[np]==dif[fa[np]])
                slink[np]=slink[fa[np]];
            else slink[np]=fa[np];
        }
        ++cnt[last=t[p][ch]];
    }
}pa;
ll dp[N],g[N];
char s[N],t[N*2];
int main(){
        pa.init();
        scanf("%s",s+1);
        int len=strlen(s+1);
        for(int i=1,j=0;i<=len;i++) t[++j]=s[i],t[++j]=s[len-i+1];
        dp[0]=1;
        for(int i=1;i<=len;i++){
            pa.ins(t[i]-'a');
            for(int x=pa.last;x>1;x=pa.slink[x]){
                g[x]=dp[i-pa.len[pa.slink[x]]-pa.dif[x]];
                if(pa.dif[x]==pa.dif[pa.fa[x]])
                    g[x]=(g[x]+g[pa.fa[x]])%mod;
                if(i%2==0) dp[i]=(dp[i]+g[x])%mod;
            }
        }
        printf("%d\n",dp[len]);
}
//23
//fastcar


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=1e6+7;
const int M=N<<1;
ll mod=1e9+7;
//dif表示节点u和fa[u]所代表的回文串的长度差
//slink表示u所在等差数列中长度最小的那个节点
//g表示u所在等差数列的dp值之和(或最小)
struct pam{
    int t[N][26],fa[N],len[N],rs[N],cnt[N],num[N];
    int dif[N],slink[N];
    int sz,n,last;
    int _new(int l){
        len[sz]=l;cnt[sz]=num[sz]=0;
        return sz++;
    }
    void init(){
        memset(t,0,sz*sizeof(t[0]));
        rs[n=sz=0]=-1;
        last=_new(0);//even
        fa[last]=_new(-1);//odd
    }
    int get_fa(int x){
        while(rs[n-1-len[x]]!=rs[n]) x=fa[x];
        return x;
    }
    void ins(int ch){
        rs[++n]=ch;
        int p=get_fa(last);
        if(!t[p][ch]){
            int np=_new(len[p]+2);
            num[np]=num[fa[np]=t[get_fa(fa[p])][ch]]+1;
            t[p][ch]=np;
            dif[np]=len[np]-len[fa[np]];
            if(dif[np]==dif[fa[np]])
                slink[np]=slink[fa[np]];
            else slink[np]=fa[np];
        }
        ++cnt[last=t[p][ch]];
    }
}pa;
ll dp[N],g[N];
char s[N],t[N*2];
int main(){
        pa.init();
        scanf("%s",s+1);
        int len=strlen(s+1);
        for(int i=1,j=0;i<=len;i++) t[++j]=s[i],t[++j]=s[len-i+1];
        dp[0]=1;
        for(int i=1;i<=len;i++){
            pa.ins(t[i]-'a');
            for(int x=pa.last;x>1;x=pa.slink[x]){
                g[x]=dp[i-pa.len[pa.slink[x]]-pa.dif[x]];
                if(pa.dif[x]==pa.dif[pa.fa[x]])
                    g[x]=(g[x]+g[pa.fa[x]])%mod;
                if(i%2==0) dp[i]=(dp[i]+g[x])%mod;
            }
        }
        printf("%d\n",dp[len]);
}
//23
//fastcar


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10,sigma = 26;
int s[maxn],len[maxn],nxt[maxn][sigma],fail[maxn],cnt[maxn];
int n,last,sz,dep[maxn],diff[maxn],top[maxn];
int g[maxn],f[maxn];
//f:dp trans by [j+1~i] is a palindrome,g:sum of f[i] by fail_link
void init(){
	for(int i=0;i<sz;i++)   cnt[i]=0,memset(nxt[i],0,sizeof nxt[i]);
	last=n=0;sz=2;s[0]=len[1]=-1;fail[0]=1;;
}
int get_fail(int x){ while(s[n-len[x]-1]!=s[n])	x=fail[x];return x;}
void add(int c){
	s[++n]=c,last = get_fail(last);
	if(!nxt[last][c]){
		len[sz]=len[last]+2,fail[sz]=nxt[get_fail(fail[last])][c];
		diff[sz]=len[sz]-len[fail[sz]];
		top[sz]= diff[sz]==diff[fail[sz]]?top[fail[sz]]:fail[sz];
		dep[sz]=dep[fail[sz]]+1,nxt[last][c]=sz++;
	}
	last=nxt[last][c],cnt[last]++;
}
void total(){for(int i=sz-1;i>=0;i--)cnt[fail[i]]+=cnt[i];}
const int mod = 1e9+7;
void trans(int i){
	for(int p=last;p>1;p=top[p]){
		g[p]=f[i-len[top[p]]-diff[p]];
		if(diff[p]==diff[fail[p]])  g[p]=(g[p]+g[fail[p]])%mod;
		if(i%2==0)	f[i]=(f[i]+g[p])%mod;
	}
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	string ss;
	cin>>ss;
	string t;
	for(int i=0;i*2<ss.size();i++)
		t+=ss[i],t+=ss[ss.size()-i-1];
	init();
	f[0]=1;
	for(int i=0;i<t.size();i++){
		add(t[i]-'a');
		trans(i+1);
	}
	cout<<f[t.size()]<<endl;
}


#include<bits/stdc++.h>
using namespace std;

const int mn = 2e6+10,sigma = 26;
int s[mn],len[mn],nxt[mn][sigma],fail[mn],cnt[mn],dep[mn],diff[mn],top[mn];
int n,last,sz;
int g[mn],f[mn];
void init(){
	for(int i=0;i<sz;i++){
		cnt[i]=0;
		memset(nxt[i],0,sizeof nxt[i]);
	}
	last=n=0;sz=2;s[n]=-1;fail[0]=1;len[1]=-1;
}
int get_fail(int x){
	while(s[n-len[x]-1]!=s[n])	x=fail[x];
	return x;
}
void add(int c){
	s[++n]=c;
	last = get_fail(last);
	if(!nxt[last][c]){
		len[sz]=len[last]+2;
		fail[sz]=nxt[get_fail(fail[last])][c];
		diff[sz]=len[sz]-len[fail[sz]];
		top[sz]= diff[sz]==diff[fail[sz]]?top[fail[sz]]:fail[sz];
		dep[sz]=dep[fail[sz]]+1;
		nxt[last][c]=sz++;
	}
	last=nxt[last][c];
	cnt[last]++;
}
void total(){
	for(int i=sz-1;i>=0;i--)
		cnt[fail[i]]+=cnt[i];
}
const int mod = 1e9 + 7;
void trans(int i){
	for(int p=last;p>1;p=top[p]){
		g[p]=f[i-len[top[p]]-diff[p]];
		if(diff[p]==diff[fail[p]])
			g[p]=(g[p]+g[fail[p]])%mod;
		if(i%2==0)
			f[i]=(f[i]+g[p])%mod;
	}
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	string ss;
	cin>>ss;
	string t;
	for(int i=0;i*2<ss.size();i++)
		t+=ss[i],t+=ss[ss.size()-i-1];
	init();
	f[0]=1;
	for(int i=0;i<t.size();i++){
		add(t[i]-'a');
		trans(i+1);
	}
	cout<<f[t.size()]<<endl;
}


#include<bits/stdc++.h>
using namespace std;

const int mn = 1e6+10,sigma = 26;
int s[mn],len[mn],nxt[mn][sigma],fail[mn],diff[mn],top[mn];
int n,last,sz;
int g[mn],f[mn];
void init(){
	for(int i=0;i<sz;i++){
		memset(nxt[i],0,sizeof nxt[i]);
	}
	last=n=0;sz=2;s[n]=-1;fail[0]=1;len[1]=-1;
}
int get_fail(int x){
	while(s[n-len[x]-1]!=s[n])	x=fail[x];
	return x;
}
void add(int c){
	s[++n]=c;
	last = get_fail(last);
	if(!nxt[last][c]){
		len[sz]=len[last]+2;
		fail[sz]=nxt[get_fail(fail[last])][c];
		diff[sz]=len[sz]-len[fail[sz]];
		top[sz]= diff[sz]==diff[fail[sz]]?top[fail[sz]]:fail[sz];
		nxt[last][c]=sz++;
	}
	last=nxt[last][c];
}
const int mod = 1e9 + 7;
void trans(int i){
	for(int p=last;p>1;p=top[p]){
		g[p]=f[i-len[top[p]]-diff[p]];
		if(diff[p]==diff[fail[p]])
			g[p]=(g[p]+g[fail[p]])%mod;
		if(i%2==0)
			f[i]=(f[i]+g[p])%mod;
	}
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	string ss;
	cin>>ss;
	string t;
	for(int i=0;i*2<ss.size();i++)
		t+=ss[i],t+=ss[ss.size()-i-1];
	init();
	f[0]=1;
	for(int i=0;i<t.size();i++){
		add(t[i]-'a');
		trans(i+1);
	}
	cout<<f[t.size()]<<endl;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e6+10,sigma = 26;
int s[maxn],len[maxn],nxt[maxn][sigma],fail[maxn],cnt[maxn];
int n,last,sz,dep[maxn],diff[maxn],top[maxn];
int g[maxn],f[maxn];
//f:dp trans by [j+1~i] is a palindrome,g:sum of f[i] by fail_link
void init(){
	for(int i=0;i<sz;i++)   cnt[i]=0,memset(nxt[i],0,sizeof nxt[i]);
	last=n=0;sz=2;s[0]=len[1]=-1;fail[0]=1;;
}
int get_fail(int x){ while(s[n-len[x]-1]!=s[n])	x=fail[x];return x;}
void add(int c){
	s[++n]=c,last = get_fail(last);
	if(!nxt[last][c]){
		len[sz]=len[last]+2,fail[sz]=nxt[get_fail(fail[last])][c];
		diff[sz]=len[sz]-len[fail[sz]];
		top[sz]= diff[sz]==diff[fail[sz]]?top[fail[sz]]:fail[sz];
		dep[sz]=dep[fail[sz]]+1,nxt[last][c]=sz++;
	}
	last=nxt[last][c],cnt[last]++;
}
void total(){for(int i=sz-1;i>=0;i--)cnt[fail[i]]+=cnt[i];}
const int mod = 1e9+7;
void trans(int i){
	for(int p=last;p>1;p=top[p]){
		g[p]=f[i-len[top[p]]-diff[p]];
		if(diff[p]==diff[fail[p]])  g[p]=(g[p]+g[fail[p]])%mod;
		if(i%2==0)	f[i]=(f[i]+g[p])%mod;
	}
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	string ss;
	cin>>ss;
	string t;
	for(int i=0;i*2<ss.size();i++)
		t+=ss[i],t+=ss[ss.size()-i-1];
	init();
	f[0]=1;
	for(int i=0;i<t.size();i++){
		add(t[i]-'a');
		trans(i+1);
	}
	cout<<f[t.size()]<<endl;
}


#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1000005 ;
const int CN = 26 ;

int nxt[MAXN][CN] ;//nxt指针，nxt指针和字典树类似，指向的串为当前串两端加上同一个字符构成
int fail[MAXN] ;//fail指针，失配后跳转到fail指针指向的节点
int cnt[MAXN] ;//cnt[i]表示节点i表示的本质不同的串的个数（建树时求出的不是完全的，最后count()函数跑一遍以后才是正确的）
int num[MAXN] ;//num[i]表示以节点i表示的最长回文串的最右端点为回文串结尾的回文串个数
int len[MAXN] ;//len[i]表示节点i表示的回文串的长度
int s[MAXN] ;//存放添加的字符
int diff[MAXN] ;
int slink[MAXN] ;
int sans[MAXN] ;
int last ;//指向上一个字符所在的节点，方便下一次add
int n ;//字符数组指针
int p ;//节点指针

int newnode ( int l ) {//新建节点
    for ( int i = 0 ; i < CN ; ++ i ) nxt[p][i] = 0 ;
    cnt[p] = 0 ;
    num[p] = 0 ;
    len[p] = l ;
    return p ++ ;
}

void init () {//初始化
    p = 0 ;
    newnode (  0 ) ;
    newnode ( -1 ) ;
    last = 0 ;
    n = 0 ;
    s[n] = -1 ;//开头放一个字符集中没有的字符，减少特判
    fail[0] = 1 ;
}

int get_fail ( int x ) {//和KMP一样，失配后找一个尽量最长的
    while ( s[n - len[x] - 1] != s[n] ) x = fail[x] ;
    return x ;
}

void add ( int c ) {
    c -= 'a' ;
    s[++ n] = c ;
    int cur = get_fail ( last ) ;//通过上一个回文串找这个回文串的匹配位置
    if ( !nxt[cur][c] ) {//如果这个回文串没有出现过，说明出现了一个新的本质不同的回文串
        int now = newnode ( len[cur] + 2 ) ;//新建节点
        fail[now] = nxt[get_fail ( fail[cur] )][c] ;//和AC自动机一样建立fail指针，以便失配后跳转
        nxt[cur][c] = now ;
        num[now] = num[fail[now]] + 1 ;
        diff[now]=len[now]-len[fail[now]];
        if(diff[now] == diff[fail[now]])
            slink[now] = slink[fail[now]];
        else
            slink[now] = fail[now];
    }
    last = nxt[cur][c] ;
    cnt[last] ++ ;
}

void count () {
    for ( int i = p - 1 ; i >= 0 ; -- i )
        cnt[fail[i]] += cnt[i] ;
    //父亲累加儿子的cnt，因为如果fail[v]=u，则u一定是v的子回文串！
}

char s1[MAXN];
char s2[MAXN];

const int N=1000005,mo=1e9+7;
int f[N];
int m;
int main(){
    scanf("%s",s1+1);
    int slen=strlen(s1+1);
    for (int i=1,j=slen;i<=j;i++,j--)
    {
        s2[++m]=s1[i];
        if (j!=i) s2[++m]=s1[j];
    }
    s2[m+1]=0;
    //printf("%s\n",s2+1);
    init();
    f[0]=1;
    for (int i=1;i<=m;i++){
        add(s2[i]);
        for (int v=last;len[v]>0;v=slink[v]){
            int pos=i-(len[slink[v]]+diff[v]);
            sans[v]=f[pos];
            if (diff[v]==diff[fail[v]])
                sans[v]=(sans[v]+sans[fail[v]])%mo;
            f[i]=(f[i]+sans[v])%mo;
        }
        if (i&1) f[i]=0;
    }
    printf("%d\n",f[m]);
}


#include <bits/stdc++.h>
using namespace std;

const int N = 1E6 + 5, MOD = 1E9 + 7;

int n, f[N];
int cnt = 0, lst = 0, len[N], dif[N], lk[N], slk[N], g[N], ch[N][26];
char s[N], t[N];

int get_link(int lst, int i) {
    while (s[i - len[lst] - 1] != s[i]) {
        lst = lk[lst];
    }
    return lst;
}

void init() {
    n = strlen(t + 1);
    for (int i = 1; i <= n; i += 2) {
        s[i] = t[n / 2 + i / 2 + 1];
        s[i + 1] = t[n / 2 - i / 2];
    }
    lk[cnt++] = 1;
    len[cnt++] = -1;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> (t + 1);
    init();
    f[0] = g[0] = g[1] = 1;
    for (int i = 1; i <= n; i++) {
        lst = get_link(lst, i);
        if (ch[lst][s[i] - 'a'] == 0) {
            len[cnt] = len[lst] + 2;
            lk[cnt] = ch[get_link(lk[lst], i)][s[i] - 'a'];
            dif[cnt] = len[cnt] - len[lk[cnt]];
            slk[cnt] = (dif[cnt] == dif[lk[cnt]] ? slk[lk[cnt]] : lk[cnt]);
            ch[lst][s[i] - 'a'] = cnt++;
        }
        lst = ch[lst][s[i] - 'a'];
        for (int suf = lst; len[suf] > 0; suf = slk[suf]) {
            g[suf] = f[i - len[suf]];
            if (dif[suf] == dif[lk[suf]]) {
                (g[suf] += g[lk[suf]]) %= MOD;
            }
            (f[i] += g[suf]) %= MOD;
        }
        if (i & 1) {
            f[i] = 0;
        }
    }
    cout << f[n];
}


#include <bits/stdc++.h>
using namespace std;

const int N = 1E6 + 5, MOD = 1E9 + 7;

int n, f[N];
int cnt = 0, lst = 0, len[N], dif[N], lk[N], slk[N], g[N], ch[N][26];
char s[N], t[N];

int get_link(int lst, int i) {
    while (s[i - len[lst] - 1] != s[i]) {
        lst = lk[lst];
    }
    return lst;
}

void init() {
    n = strlen(t + 1);
    for (int i = 1; i <= n; i += 2) {
        s[i] = t[n / 2 + i / 2 + 1];
        s[i + 1] = t[n / 2 - i / 2];
    }
    lk[cnt++] = 1;
    len[cnt++] = -1;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> (t + 1);
    init();
    f[0] = g[0] = g[1] = 1;
    for (int i = 1; i <= n; i++) {
        lst = get_link(lst, i);
        if (ch[lst][s[i] - 'a'] == 0) {
            len[cnt] = len[lst] + 2;
            lk[cnt] = ch[get_link(lk[lst], i)][s[i] - 'a'];
            dif[cnt] = len[cnt] - len[lk[cnt]];
            slk[cnt] = (dif[cnt] == dif[lk[cnt]] ? slk[lk[cnt]] : lk[cnt]);
            ch[lst][s[i] - 'a'] = cnt++;
        }
        lst = ch[lst][s[i] - 'a'];
        for (int suf = lst; len[suf] > 0; suf = slk[suf]) {
            g[suf] = f[i - dif[suf] - len[slk[suf]]];
            if (dif[suf] == dif[lk[suf]]) {
                (g[suf] += g[lk[suf]]) %= MOD;
            }
            (f[i] += g[suf]) %= MOD;
        }
        if (i & 1) {
            f[i] = 0;
        }
    }
    cout << f[n];
}


#include <bits/stdc++.h>
using namespace std;

const int N = 1E6 + 5, MOD = 1E9 + 7;

int n, f[N];
int cnt = 0, lst = 0, len[N], dif[N], lk[N], slk[N], g[N], ch[N][26];
char s[N], t[N];

int get_link(int lst, int i) {
    while (s[i - len[lst] - 1] != s[i]) {
        lst = lk[lst];
    }
    return lst;
}

void init() {
    n = strlen(t + 1);
    for (int i = 1; i <= n; i += 2) {
        s[i] = t[n / 2 + i / 2 + 1];
        s[i + 1] = t[n / 2 - i / 2];
    }
    lk[cnt++] = 1;
    len[cnt++] = -1;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> (t + 1);
    init();
    f[0] = g[0] = g[1] = 1;
    for (int i = 1; i <= n; i++) {
        lst = get_link(lst, i);
        if (ch[lst][s[i] - 'a'] == 0) {
            len[cnt] = len[lst] + 2;
            lk[cnt] = ch[get_link(lk[lst], i)][s[i] - 'a'];
            dif[cnt] = len[cnt] - len[lk[cnt]];
            slk[cnt] = (dif[cnt] == dif[lk[cnt]] ? slk[lk[cnt]] : lk[cnt]);
            ch[lst][s[i] - 'a'] = cnt++;
        }
        lst = ch[lst][s[i] - 'a'];
        for (int suf = lst; len[suf] > 0; suf = slk[suf]) {
            g[suf] = f[i - dif[suf] - len[lk[suf]]];
            if (dif[suf] == dif[lk[suf]]) {
                (g[suf] += g[lk[suf]]) %= MOD;
            }
            (f[i] += g[suf]) %= MOD;
        }
        if (i & 1) {
            f[i] = 0;
        }
    }
    cout << f[n];
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair <int, int>
#define fi first
#define se second
#define N 2000010
#define ALP 26
const ll p = 1e9 + 7;
int n;
char s[N], t[N];
struct PAM{
	//每个节点代表一个本质不同的回文串
	struct node {
		int Next[ALP];
		int fail;
		//以节点i最后一个字符结尾的回文串个数
		//节点i表示的回文串的长度
		//节点i表示的回文串在整串中的出现次数
		//以节点i最后一个字符结尾的回文串的长度和
		int num, len, cnt;
		int diff, anc;
		ll f;
		node(int _len = 0) {
			memset(Next, 0, sizeof Next);
			fail = 0;
			num = cnt = 0;
			diff = anc = 0;
		   	f = 0;
			len = _len;
		}
	}t[N];
    //存放添加的字符
	int s[N];         // 存放添加的字符
    //指向添加最后一个字符后的节点
	int last;
    //已添加字符个数
	int n;
    //节点个数
	int p;

    int newnode(int len){ // 初始化节点，w=长度
        t[p] = node(len);
        return p++;
    }
    //0为长度为偶数的回文子串的根节点
    //1为长度为奇数的回文子串的根节点
    //最后节点总数是p，但是节点标号是[0, p - 1]
    void init(){
        p = 0;
        newnode(0);
        newnode(-1);
        last = 0;
        n = 0;
        s[n] = -1; 		 // 开头放一个字符集中没有的字符，减少特判
        t[0].fail = 1;
    }
    int get_fail(int x){ // 和KMP一样，失配后找一个尽量最长的
        while(s[n-t[x].len-1] != s[n]) x = t[x].fail;
        return x;
    }
    void add(int c){
		//设置偏移量
        c -= 'a';
        s[++n] = c;
		//通过上一个回文串找这个回文串的匹配位置
		int cur = get_fail(last);
		//如果这个回文串没有出现过，说明出现了一个新的本质不同的回文串
		if(!t[cur].Next[c]){
            int now = newnode(t[cur].len + 2);//新建节点
			//如果这个回文串没有出现过，说明出现了一个新的本质不同的回文串
            t[now].fail = t[get_fail(t[cur].fail)].Next[c];
            t[cur].Next[c] = now;
            t[now].num = t[t[now].fail].num + 1;
			t[now].diff = t[now].len - t[t[now].fail].len;
			t[now].anc = (t[now].diff == t[t[now].fail].diff ? t[t[now].fail].anc : t[now].fail);
		}
        last = t[cur].Next[c];
		++t[last].cnt;
        //返回的当前字符加入后是否新增了一个本质不同的回文串
		//那么此时的p - 2就表示加入这个字符后共有多少个本质不同的回文串
    }
	void gao(char *s, ll g[]) {
		g[0] = 1;
		int len = strlen(s + 1);
		for (int i = 1; i <= len; ++i) {
			add(s[i]);
			int it = last;
			while (it) {
				t[it].f = g[i - t[t[it].anc].len - t[it].diff];
				if (t[it].fail != t[it].anc) {
					(t[it].f += t[t[it].fail].f) %= p;
				}
				if (i % 2 == 0) (g[i] += t[it].f) %= p;
				it = t[it].anc;
			}
		}
		printf("%lld\n", g[len]);
	}
}pam;

ll g[N];
void run() {
	int len = strlen(s + 1);
	for (int i = 1; i <= len; i += 2) {
		t[i] = s[i / 2 + 1];
	}
	reverse(s + 1, s + 1 + len);
	for (int i = 2; i <= len; i += 2) {
		t[i] = s[i / 2];
	}
	pam.init();
	memset(g, 0, sizeof g);
	pam.gao(t, g);
}

int main() {
	while (scanf("%s", s + 1) != EOF) run();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair <int, int>
#define fi first
#define se second
#define N 1000010
#define ALP 26
const ll p = 1e9 + 7;
int n;
char s[N], t[N];
struct PAM{
	//每个节点代表一个本质不同的回文串
	struct node {
		int Next[ALP];
		int fail;
		//以节点i最后一个字符结尾的回文串个数
		//节点i表示的回文串的长度
		//节点i表示的回文串在整串中的出现次数
		//以节点i最后一个字符结尾的回文串的长度和
		int num, len, cnt;
		int diff, anc;
		ll f;
		node(int _len = 0) {
			memset(Next, 0, sizeof Next);
			fail = 0;
			num = cnt = 0;
			diff = anc = 0;
		   	f = 0;
			len = _len;
		}
	}t[N];
    //存放添加的字符
	int s[N];         // 存放添加的字符
    //指向添加最后一个字符后的节点
	int last;
    //已添加字符个数
	int n;
    //节点个数
	int p;

    int newnode(int len){ // 初始化节点，w=长度
        t[p] = node(len);
        return p++;
    }
    //0为长度为偶数的回文子串的根节点
    //1为长度为奇数的回文子串的根节点
    //最后节点总数是p，但是节点标号是[0, p - 1]
    void init(){
        p = 0;
        newnode(0);
        newnode(-1);
        last = 0;
        n = 0;
        s[n] = -1; 		 // 开头放一个字符集中没有的字符，减少特判
        t[0].fail = 1;
    }
    int get_fail(int x){ // 和KMP一样，失配后找一个尽量最长的
        while(s[n-t[x].len-1] != s[n]) x = t[x].fail;
        return x;
    }
    void add(int c){
		//设置偏移量
        c -= 'a';
        s[++n] = c;
		//通过上一个回文串找这个回文串的匹配位置
		int cur = get_fail(last);
		//如果这个回文串没有出现过，说明出现了一个新的本质不同的回文串
		if(!t[cur].Next[c]){
            int now = newnode(t[cur].len + 2);//新建节点
			//如果这个回文串没有出现过，说明出现了一个新的本质不同的回文串
            t[now].fail = t[get_fail(t[cur].fail)].Next[c];
            t[cur].Next[c] = now;
            t[now].num = t[t[now].fail].num + 1;
			t[now].diff = t[now].len - t[t[now].fail].len;
			t[now].anc = (t[now].diff == t[t[now].fail].diff ? t[t[now].fail].anc : t[now].fail);
		}
        last = t[cur].Next[c];
		++t[last].cnt;
        //返回的当前字符加入后是否新增了一个本质不同的回文串
		//那么此时的p - 2就表示加入这个字符后共有多少个本质不同的回文串
    }
	void gao(char *s, ll g[]) {
		g[0] = 1;
		int len = strlen(s + 1);
		for (int i = 1; i <= len; ++i) {
			add(s[i]);
			int it = last;
			while (it) {
				t[it].f = g[i - t[t[it].anc].len - t[it].diff];
				if (t[it].fail != t[it].anc) {
					(t[it].f += t[t[it].fail].f) %= p;
				}
				if (i % 2 == 0) (g[i] += t[it].f) %= p;
				it = t[it].anc;
			}
		}
		printf("%lld\n", g[len]);
	}
}pam;

ll g[N];
void run() {
	int len = strlen(s + 1);
	for (int i = 1; i <= len; i += 2) {
		t[i] = s[i / 2 + 1];
	}
	reverse(s + 1, s + 1 + len);
	for (int i = 2; i <= len; i += 2) {
		t[i] = s[i / 2];
	}
	pam.init();
	memset(g, 0, sizeof g);
	pam.gao(t, g);
}

int main() {
	while (scanf("%s", s + 1) != EOF) run();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair <int, int>
#define fi first
#define se second
#define N 1000010
#define ALP 26
const ll mod = 1e9 + 7;
int n;
char s[N], t[N];
struct PAM{
	//每个节点代表一个本质不同的回文串
	struct node {
		int Next[ALP];
		int fail;
		int len;
		int diff, anc;
		ll f;
		node(int _len = 0) {
			memset(Next, 0, sizeof Next);
			fail = 0;
			diff = anc = 0;
		   	f = 0;
			len = _len;
		}
	}t[N];
    //存放添加的字符
	int s[N];         // 存放添加的字符
    //指向添加最后一个字符后的节点
	int last;
    //已添加字符个数
	int n;
    //节点个数
	int p;

    int newnode(int len){ // 初始化节点，w=长度
        t[p] = node(len);
        return p++;
    }
    //0为长度为偶数的回文子串的根节点
    //1为长度为奇数的回文子串的根节点
    //最后节点总数是p，但是节点标号是[0, p - 1]
    void init(){
        p = 0;
        newnode(0);
        newnode(-1);
        last = 0;
        n = 0;
        s[n] = -1; 		 // 开头放一个字符集中没有的字符，减少特判
        t[0].fail = t[1].fail = 1;
		t[0].anc = 1;
    }
    int get_fail(int x){ // 和KMP一样，失配后找一个尽量最长的
        while(s[n-t[x].len-1] != s[n]) x = t[x].fail;
        return x;
    }
    void add(int c){
		//设置偏移量
        c -= 'a';
        s[++n] = c;
		//通过上一个回文串找这个回文串的匹配位置
		int cur = get_fail(last);
		//如果这个回文串没有出现过，说明出现了一个新的本质不同的回文串
		if(!t[cur].Next[c]){
            int now = newnode(t[cur].len + 2);//新建节点
			//如果这个回文串没有出现过，说明出现了一个新的本质不同的回文串
            t[now].fail = t[get_fail(t[cur].fail)].Next[c];
            t[cur].Next[c] = now;
			t[now].diff = t[now].len - t[t[now].fail].len;
			t[now].anc = (t[now].diff == t[t[now].fail].diff ? t[t[now].fail].anc : t[now].fail);
		}
        last = t[cur].Next[c];
        //返回的当前字符加入后是否新增了一个本质不同的回文串
		//那么此时的p - 2就表示加入这个字符后共有多少个本质不同的回文串
    }
	void gao(char *s, ll g[]) {
		init();
		g[0] = 1;
		int len = strlen(s + 1);
		for (int i = 1; i <= len; ++i) {
			add(s[i]);
			int it = last;
			while (it) {
				t[it].f = g[i - t[t[it].anc].len - t[it].diff];
				if (t[it].fail != t[it].anc) {
					(t[it].f += t[t[it].fail].f) %= mod;
				}
				if (i % 2 == 0) (g[i] += t[it].f) %= mod;
				it = t[it].anc;
			}
		}
		printf("%lld\n", g[len]);
	}
}pam;

ll g[N];
void run() {
	int len = strlen(s + 1);
	for (int i = 1; i <= len; i += 2) {
		t[i] = s[(i + 1) / 2];
	}
	reverse(s + 1, s + 1 + len);
	for (int i = 2; i <= len; i += 2) {
		t[i] = s[(i + 1) / 2];
	}
	memset(g, 0, sizeof g);
	pam.gao(t, g);
}

int main() {
	while (scanf("%s", s + 1) != EOF) run();
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long double ld;

const int inf = 1e9;
const ll inf64 = 1e18;

const int mod = inf + 7;

inline int _sum(int a, int b) {
    return a + b < mod ? a + b : a + b - mod;
}

inline int _mul(int a, int b) {
    return (1ll * a * b) % mod;
}

inline int _sub(int a, int b) {
    return a >= b ? a - b : a - b + mod;
}

inline void _inc(int &x, int y) {
    if ((x += y) >= mod) {
        x -= mod;
    }
}

inline void _dec(int &x, int y) {
    if ((x -= y) < 0) {
        x += mod;
    }
}

inline int _binpow(int x, int pw) {
    int res = 1;
    int tmp = x;
    while (pw > 0) {
        if (pw & 1) {
            res = _mul(res, tmp);
        }
        tmp = _mul(tmp, tmp);
        pw >>= 1;
    }
    return res;
}

inline int _div(int a, int b) {
    return _mul(a, _binpow(b, mod - 2));
}

void read(string& s) {
    cin >> s;
}

void gen(string& s) {
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    int n = 2 * (rnd() % 3 + 1);
    s.resize(n, '?');
    for (int i = 0; i < n; i++) {
        s[i] = rnd() % 5 == 0 ? 'a' : 'b';
    }
}

string join_halfs(string s) {
    int n = (int) s.size();
    string t;
    for (int i = 0; i < n / 2; i++) {
        t.push_back(s[i]);
        t.push_back(s[n - 1 - i]);
    }
    return t;
}

int slow(string s) {
    s = join_halfs(s);
    int n = (int) s.size();
    s = "#" + s;
    vector<int> dp(n + 1);
    dp[0] = 1;
    cout << s << "\n";
    for (int i = 1; i <= n; i++) {
        for (int j = i; j >= 1; j--) {
            if ((i - j + 1) % 2) continue;
            string hlp = s.substr(j, i - j + 1);
            string rhlp = hlp; reverse(rhlp.begin(), rhlp.end());
            if (hlp == rhlp) {
                _inc(dp[i], dp[j - 1]);
            }
        }
    }
    return dp[n];
}

const int N = 2e6 + 5;

struct Node {
    map<int, int> nxt;
    int link = -1;
    int dp = 0;
    int slink = -1;
    int len = 0;
    int diff = 0;

    Node() = default;
};

Node t[N];
int sz, max_suff;

int fast(string s) {
    { // init
        sz = 0;
        t[sz++] = Node(); // (-1)
        t[sz++] = Node(); // (0)
        max_suff = 1;

        t[0].link = 1;
        t[1].link = 0;

        t[0].len = 0;
        t[1].len = -1;
    }
    int n = (int) s.size();
    s = "#" + join_halfs(s);
    vector<int> dp(n + 1);
    dp[0] = 1;
    max_suff = 0;
    for (int i = 1; i <= n; i++) {
        { // add symbol
            while (s[i] != s[i - t[max_suff].len - 1]) {
                max_suff = t[max_suff].link;
            }
            if (!t[max_suff].nxt.count(s[i])) {
                t[sz++] = Node();
                t[sz - 1].len = t[max_suff].len + 2;

                int next_max_suff = t[max_suff].link;
                while (s[i] != s[i - t[next_max_suff].len - 1]) {
                    next_max_suff = t[next_max_suff].link;
                }
                t[sz - 1].link = t[next_max_suff].nxt[s[i]];

                t[sz - 1].diff = t[sz - 1].len - t[t[sz - 1].link].len;
                if (t[sz - 1].diff == t[t[sz - 1].link].diff) {
                    t[sz - 1].slink = t[t[sz - 1].link].slink;
                } else {
                    t[sz - 1].slink = t[sz - 1].link;
                }

                t[max_suff].nxt[s[i]] = sz - 1;
            }
            max_suff = t[max_suff].nxt[s[i]];
        }
//        cout << i << " : " << t[max_suff].len << "\n";
        for (int x = max_suff; t[x].len > 0; x = t[x].slink) {
            {
                int j = i - t[t[x].slink].len - t[x].diff;
                t[x].dp = dp[j];
            }
            if (t[x].diff == t[t[x].link].diff) {
                _inc(t[x].dp, t[t[x].link].dp);
            }
            if (i % 2 == 0) {
                _inc(dp[i], t[x].dp);
            }
//            for (int y = x; t[y].len > t[t[x].slink].len; y = t[y].link) {
//                int j = i - t[y].len;
//                if (i % 2 == j % 2) {
//                    _inc(dp[i], dp[j]);
//                }
//            }
        }
    }
//    for (int i = 1; i <= n; i++) {
//        cout << dp[i] << "\n";
//    }
    return dp[n];
}

void WORK() {
    string s;
    read(s);
//    cout << slow(s) << "\n";
    cout << fast(s) << "\n";
}

void TEST() {
    while (1) {
        string s;
        gen(s);
        cout << "s = " << s << endl;
        int sl = slow(s);
        int fs = fast(s);
        if (sl == fs) {
            cout << "OK (" << fs << ")" << endl;
        } else {
            cout << "WA" << endl;
            cout << "exp = " << sl << endl;
            cout << "fnd = " << fs << endl;
            break;
        }
    }
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0);
    cin.tie(0);

    WORK();
//    TEST();

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long double ld;

const int inf = 1e9;
const ll inf64 = 1e18;

const int mod = inf + 7;

inline int _sum(int a, int b) {
    return a + b < mod ? a + b : a + b - mod;
}

inline int _mul(int a, int b) {
    return (1ll * a * b) % mod;
}

inline int _sub(int a, int b) {
    return a >= b ? a - b : a - b + mod;
}

inline void _inc(int &x, int y) {
    if ((x += y) >= mod) {
        x -= mod;
    }
}

inline void _dec(int &x, int y) {
    if ((x -= y) < 0) {
        x += mod;
    }
}

inline int _binpow(int x, int pw) {
    int res = 1;
    int tmp = x;
    while (pw > 0) {
        if (pw & 1) {
            res = _mul(res, tmp);
        }
        tmp = _mul(tmp, tmp);
        pw >>= 1;
    }
    return res;
}

inline int _div(int a, int b) {
    return _mul(a, _binpow(b, mod - 2));
}

void read(string& s) {
    cin >> s;
}

void gen(string& s) {
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    int n = 2 * (rnd() % 20 + 1);
    s.resize(n, '?');
    for (int i = 0; i < n; i++) {
        s[i] = rnd() % 5 == 0 ? 'a' : 'b';
    }
}

string join_halfs(string s) {
    int n = (int) s.size();
    string t;
    for (int i = 0; i < n / 2; i++) {
        t.push_back(s[i]);
        t.push_back(s[n - 1 - i]);
    }
    return t;
}

int slow(string s) {
    s = join_halfs(s);
    int n = (int) s.size();
    s = "#" + s;
    vector<int> dp(n + 1);
    dp[0] = 1;
    cout << s << "\n";
    for (int i = 1; i <= n; i++) {
        for (int j = i; j >= 1; j--) {
            if ((i - j + 1) % 2) continue;
            string hlp = s.substr(j, i - j + 1);
            string rhlp = hlp; reverse(rhlp.begin(), rhlp.end());
            if (hlp == rhlp) {
                _inc(dp[i], dp[j - 1]);
            }
        }
    }
    return dp[n];
}

const int N = 2e6 + 5;

struct Node {
    map<int, int> nxt;
    int link = -1;
    int dp = 0;
    int slink = -1;
    int len = 0;
    int diff = 0;

    Node() = default;
};

Node t[N];
int sz, max_suff;

int fast(string s) {
    { // init
        sz = 0;
        t[sz++] = Node(); // (-1)
        t[sz++] = Node(); // (0)
        max_suff = 1;

        t[0].link = 0;
        t[0].len = -1;
        t[0].slink = t[0].link;
        t[0].diff = t[0].len - t[t[0].link].len;

        t[1].link = 0;
        t[1].len = 0;
        t[1].slink = t[1].link;
        t[1].diff = t[1].len - t[t[1].link].len;
    }
    int n = (int) s.size();
    s = "#" + join_halfs(s);
    vector<int> dp(n + 1);
    dp[0] = 1;
    for (int i = 1; i <= n; i++) {
        { // add symbol
            while (s[i] != s[i - t[max_suff].len - 1]) {
                max_suff = t[max_suff].link;
            }
            if (!t[max_suff].nxt.count(s[i])) {
                t[max_suff].nxt[s[i]] = sz;
                t[sz++] = Node();
                t[sz - 1].len = t[max_suff].len + 2;
                int next_max_suff = t[max_suff].link;
                while (s[i] != s[i - t[next_max_suff].len - 1]) {
                    next_max_suff = t[next_max_suff].link;
                }
                t[sz - 1].link =
                        next_max_suff && t[next_max_suff].nxt.count(s[i]) ?
                        t[next_max_suff].nxt[s[i]] :
                        1;
            }
            max_suff = t[max_suff].nxt[s[i]];
        }
        for (int x = max_suff; t[x].len > 0; x = t[x].link) {
            if (t[x].len % 2 == 0) {
                _inc(dp[i], dp[i - t[x].len]);
            }
        }
    }
//    for (int i = 1; i <= n; i++) {
//        cout << dp[i] << "\n";
//    }
    return dp[n];
}

void WORK() {
    string s;
    read(s);
//    cout << slow(s) << "\n";
    cout << fast(s) << "\n";
}

void TEST() {
    while (1) {
        string s;
        gen(s);
        cout << "s = " << s << endl;
        int sl = slow(s);
        int fs = fast(s);
        if (sl == fs) {
            cout << "OK (" << fs << ")" << endl;
        } else {
            cout << "WA" << endl;
            cout << "exp = " << sl << endl;
            cout << "fnd = " << fs << endl;
            break;
        }
    }
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0);
    cin.tie(0);

    WORK();
//    TEST();

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long double ld;

const int inf = 1e9;
const ll inf64 = 1e18;

const int mod = inf + 7;

inline int _sum(int a, int b) {
    return a + b < mod ? a + b : a + b - mod;
}

inline int _mul(int a, int b) {
    return (1ll * a * b) % mod;
}

inline int _sub(int a, int b) {
    return a >= b ? a - b : a - b + mod;
}

inline void _inc(int &x, int y) {
    if ((x += y) >= mod) {
        x -= mod;
    }
}

inline void _dec(int &x, int y) {
    if ((x -= y) < 0) {
        x += mod;
    }
}

inline int _binpow(int x, int pw) {
    int res = 1;
    int tmp = x;
    while (pw > 0) {
        if (pw & 1) {
            res = _mul(res, tmp);
        }
        tmp = _mul(tmp, tmp);
        pw >>= 1;
    }
    return res;
}

inline int _div(int a, int b) {
    return _mul(a, _binpow(b, mod - 2));
}

void read(string& s) {
    cin >> s;
}

void gen(string& s) {
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    int n = 2 * (rnd() % 3 + 1);
    s.resize(n, '?');
    for (int i = 0; i < n; i++) {
        s[i] = rnd() % 5 == 0 ? 'a' : 'b';
    }
}

string join_halfs(string s) {
    int n = (int) s.size();
    string t;
    for (int i = 0; i < n / 2; i++) {
        t.push_back(s[i]);
        t.push_back(s[n - 1 - i]);
    }
    return t;
}

int slow(string s) {
    s = join_halfs(s);
    int n = (int) s.size();
    s = "#" + s;
    vector<int> dp(n + 1);
    dp[0] = 1;
    cout << s << "\n";
    for (int i = 1; i <= n; i++) {
        for (int j = i; j >= 1; j--) {
            if ((i - j + 1) % 2) continue;
            string hlp = s.substr(j, i - j + 1);
            string rhlp = hlp; reverse(rhlp.begin(), rhlp.end());
            if (hlp == rhlp) {
                _inc(dp[i], dp[j - 1]);
            }
        }
    }
    return dp[n];
}

const int N = 2e6 + 5;

struct Node {
    map<int, int> nxt;
    int link = -1;
    int dp[2] = {0, 0};
    int slink = -1;
    int len = 0;
    int diff = 0;

    Node() = default;
};

Node t[N];
int sz, max_suff;

int fast(string s) {
    { // init
        sz = 0;
        t[sz++] = Node(); // (-1)
        t[sz++] = Node(); // (0)
        max_suff = 1;

        t[0].link = 1;
        t[1].link = 0;

        t[0].len = -1;
        t[1].len = 0;
    }
    int n = (int) s.size();
    s = "#" + join_halfs(s);
    vector<int> dp(n + 1);
    dp[0] = 1;
    max_suff = 1;
    for (int i = 1; i <= n; i++) {
        { // add symbol
            while (s[i] != s[i - t[max_suff].len - 1]) {
                max_suff = t[max_suff].link;
            }
            if (!t[max_suff].nxt.count(s[i])) {
                t[sz++] = Node();
                t[sz - 1].len = t[max_suff].len + 2;

                int next_max_suff = t[max_suff].link;
                while (s[i] != s[i - t[next_max_suff].len - 1]) {
                    next_max_suff = t[next_max_suff].link;
                }
                t[sz - 1].link = t[next_max_suff].nxt.count(s[i]) ? t[next_max_suff].nxt[s[i]] : 1;

                t[sz - 1].diff = t[sz - 1].len - t[t[sz - 1].link].len;
                if (t[sz - 1].diff == t[t[sz - 1].link].diff) {
                    t[sz - 1].slink = t[t[sz - 1].link].slink;
                } else {
                    t[sz - 1].slink = t[sz - 1].link;
                }

                t[max_suff].nxt[s[i]] = sz - 1;
            }
            max_suff = t[max_suff].nxt[s[i]];
        }
        for (int x = max_suff; t[x].len > 0; x = t[x].slink) {
            t[x].dp[0] = t[x].dp[1] = 0;
            {
                int j = i - t[t[x].slink].len - t[x].diff;
                t[x].dp[j & 1] = dp[j];
            }
            if (t[x].diff == t[t[x].link].diff) {
                _inc(t[x].dp[0], t[t[x].link].dp[0]);
                _inc(t[x].dp[1], t[t[x].link].dp[1]);
            }
            _inc(dp[i], t[x].dp[i & 1]);
        }
    }
//    for (int i = 1; i <= n; i++) {
//        cout << dp[i] << "\n";
//    }
    return dp[n];
}

void WORK() {
    string s;
    read(s);
//    cout << slow(s) << "\n";
    cout << fast(s) << "\n";
}

void TEST() {
    while (1) {
        string s;
        gen(s);
        cout << "s = " << s << endl;
        int sl = slow(s);
        int fs = fast(s);
        if (sl == fs) {
            cout << "OK (" << fs << ")" << endl;
        } else {
            cout << "WA" << endl;
            cout << "exp = " << sl << endl;
            cout << "fnd = " << fs << endl;
            break;
        }
    }
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0);
    cin.tie(0);

    WORK();
//    TEST();

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long double ld;

const int inf = 1e9;
const ll inf64 = 1e18;

const int mod = inf + 7;

inline int _sum(int a, int b) {
    return a + b < mod ? a + b : a + b - mod;
}

inline int _mul(int a, int b) {
    return (1ll * a * b) % mod;
}

inline int _sub(int a, int b) {
    return a >= b ? a - b : a - b + mod;
}

inline void _inc(int &x, int y) {
    if ((x += y) >= mod) {
        x -= mod;
    }
}

inline void _dec(int &x, int y) {
    if ((x -= y) < 0) {
        x += mod;
    }
}

inline int _binpow(int x, int pw) {
    int res = 1;
    int tmp = x;
    while (pw > 0) {
        if (pw & 1) {
            res = _mul(res, tmp);
        }
        tmp = _mul(tmp, tmp);
        pw >>= 1;
    }
    return res;
}

inline int _div(int a, int b) {
    return _mul(a, _binpow(b, mod - 2));
}

void read(string& s) {
    cin >> s;
}

void gen(string& s) {
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    int n = 2 * (rnd() % 3 + 1);
    s.resize(n, '?');
    for (int i = 0; i < n; i++) {
        s[i] = rnd() % 5 == 0 ? 'a' : 'b';
    }
}

string join_halfs(string s) {
    int n = (int) s.size();
    string t;
    for (int i = 0; i < n / 2; i++) {
        t.push_back(s[i]);
        t.push_back(s[n - 1 - i]);
    }
    return t;
}

int slow(string s) {
    s = join_halfs(s);
    int n = (int) s.size();
    s = "#" + s;
    vector<int> dp(n + 1);
    dp[0] = 1;
    cout << s << "\n";
    for (int i = 1; i <= n; i++) {
        for (int j = i; j >= 1; j--) {
            if ((i - j + 1) % 2) continue;
            string hlp = s.substr(j, i - j + 1);
            string rhlp = hlp; reverse(rhlp.begin(), rhlp.end());
            if (hlp == rhlp) {
                _inc(dp[i], dp[j - 1]);
            }
        }
    }
    return dp[n];
}

const int N = 2e6 + 5;

struct Node {
    map<int, int> nxt;
    int link = -1;
    int dp = 0;
    int slink = -1;
    int len = 0;
    int diff = 0;

    Node() = default;
};

Node t[N];
int sz, max_suff;

int fast(string s) {
    { // init
        sz = 0;
        t[sz++] = Node(); // (-1)
        t[sz++] = Node(); // (0)
        max_suff = 1;

        t[0].link = 1;
        t[1].link = 0;

        t[0].len = -1;
        t[1].len = 0;
    }
    int n = (int) s.size();
    s = "#" + join_halfs(s);
    vector<int> dp(n + 1);
    dp[0] = 1;
    max_suff = 1;
    for (int i = 1; i <= n; i++) {
        { // add symbol
            while (s[i] != s[i - t[max_suff].len - 1]) {
                max_suff = t[max_suff].link;
            }
            if (!t[max_suff].nxt.count(s[i])) {
                t[sz++] = Node();
                t[sz - 1].len = t[max_suff].len + 2;

                int next_max_suff = t[max_suff].link;
                while (s[i] != s[i - t[next_max_suff].len - 1]) {
                    next_max_suff = t[next_max_suff].link;
                }
                t[sz - 1].link = t[next_max_suff].nxt.count(s[i]) ? t[next_max_suff].nxt[s[i]] : 1;

                t[sz - 1].diff = t[sz - 1].len - t[t[sz - 1].link].len;
                if (t[sz - 1].diff == t[t[sz - 1].link].diff) {
                    t[sz - 1].slink = t[t[sz - 1].link].slink;
                } else {
                    t[sz - 1].slink = t[sz - 1].link;
                }

                t[max_suff].nxt[s[i]] = sz - 1;
            }
            max_suff = t[max_suff].nxt[s[i]];
        }
//        cout << i << " : " << t[max_suff].len << "\n";
        for (int x = max_suff; t[x].len > 0; x = t[x].slink) {
            {
                int j = i - t[t[x].slink].len - t[x].diff;
                t[x].dp = dp[j];
            }
            if (t[x].diff == t[t[x].link].diff) {
                _inc(t[x].dp, t[t[x].link].dp);
            }
            if (i % 2 == 0) {
                _inc(dp[i], t[x].dp);
            }
//            for (int y = x; t[y].len > t[t[x].slink].len; y = t[y].link) {
//                int j = i - t[y].len;
//                if (i % 2 == j % 2) {
//                    _inc(dp[i], dp[j]);
//                }
//            }
        }
    }
//    for (int i = 1; i <= n; i++) {
//        cout << dp[i] << "\n";
//    }
    return dp[n];
}

void WORK() {
    string s;
    read(s);
//    cout << slow(s) << "\n";
    cout << fast(s) << "\n";
}

void TEST() {
    while (1) {
        string s;
        gen(s);
        cout << "s = " << s << endl;
        int sl = slow(s);
        int fs = fast(s);
        if (sl == fs) {
            cout << "OK (" << fs << ")" << endl;
        } else {
            cout << "WA" << endl;
            cout << "exp = " << sl << endl;
            cout << "fnd = " << fs << endl;
            break;
        }
    }
}

int main() {

#ifdef debug
    freopen("input.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0);
    cin.tie(0);

    WORK();
//    TEST();

    return 0;
}