Problem: You are given a non-empty string s consisting of lowercase letters. Find the number of pairs of non-overlapping palindromic substrings of this string.

In a more formal way, you have to find the quantity of tuples (a, b, x, y) such that 1 ≤ a ≤ b < x ≤ y ≤ |s| and substrings s[a... b], s[x... y] are palindromes.

A palindrome is a string that can be read the same way from left to right and from right to left. For example, "abacaba", "z", "abba" are palindromes.

A substring s[i... j] (1 ≤ i ≤ j ≤ |s|) of string s = s1s2... s|s| is a string sisi + 1... sj. For example, substring s[2...4] of string s = "abacaba" equals "bac".

Input

The first line of input contains a non-empty string s which consists of lowercase letters ('a'...'z'), s contains at most 2000 characters.

Output

Output a single number — the quantity of pairs of non-overlapping palindromic substrings of s.

Please do not use the %lld format specifier to read or write 64-bit integers in С++. It is preferred to use cin, cout streams or the %I64d format specifier.

Examples

Input

aa


Output

1


Input

aaa


Output

5


Input

abacaba


Output

36

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;

public class Main implements Runnable {

	public void _main() throws IOException {
		char[] s = next().toCharArray();
		int n = s.length;
		int[] even = new int[n];
		int[] odd = new int[n];
		int[] palsOnSuffix = new int[n];
		Manacher(n, s, even, odd);
		for (int i = n - 1; i >= 0; i--) {
			for (int j = i; j < n; j++) {
				if (isPal(i, j, even, odd)) {
					++palsOnSuffix[i];
				}
			}
			if (i < n - 1) {
				palsOnSuffix[i] += palsOnSuffix[i + 1];
			}
		}
		long res = 0;
		for (int i = 0; i + 1 < n; i++) {
			int endingHere = 0;
			for (int j = 0; j <= i; j++) {
				if (isPal(j, i, even, odd)) {
					++endingHere;
				}
			}
			res += endingHere * (long)palsOnSuffix[i + 1];
		}
		out.println(res);
	}

	// [l, r] both inclusive
	private boolean isPal(int l, int r, int[] even, int[] odd) {
		int len = r - l + 1;
		int c = l + len/2;
		if (len % 2 == 0) {
			return even[c - 1] >= len/2;
		}
		return odd[c] >= (len + 1) / 2;
	}

	private void Manacher(int n, char[] s, int[] even, int[] odd) {
		int l, r;
		l = -1;
		r = -1;
		for (int i = 0; i < n - 1; i++) {
			int p = 0;
			if (i <= r) {
				int j = l + r - i - 1;
				if (j >= 0)
					p = Math.min(even[j], r - i);
			}
			while (i - p >= 0 && i + p + 1 < s.length && s[i - p] == s[i + p + 1])
				++p;
			even[i] = p;
			if (p > 0) {
				l = i - p + 1;
				r = i + p;
			}
		}
		l = -1;
		r = -1;
		for (int i = 0; i < n; i++) {
			int p = 0;
			if (i <= r) {
				int j = l + r - i;
				p = Math.min(odd[j], r - i);
			}
			while (i - p >= 0 && i + p < s.length && s[i - p] == s[i + p])
				++p;
			odd[i] = p;
			if (p > 0) {
				l = i - p + 1;
				r = i + p - 1;
			}
		}
	}


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

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

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

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

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

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

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			//in = new BufferedReader(new FileReader("a.in"));
			//out = new PrintWriter(new FileWriter("a.out"));

			_main();

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

}