// Arup Guha
// 12/20/2017
// Solution to 2017 SER Division 1 Problem: Flipping Out
// This solution uses Raptor's idea to subtract out patterns that already exist of the possible strings.

import java.util.*;
import java.io.*;

public class flippingout2 {

	// 'T' = 'A' and 'H' = 'B'
	public static int len;
	public static char[] target;
	public static char[] actual;

	public static int nWords;
	public static char[][] words;
	public static int sumWLen;

	public static node trie;

	public static void main(String[] args) throws Exception {

		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
		nWords = Integer.parseInt(stdin.readLine().trim())-1;

		// Read in the patterns.
		sumWLen = 0;
		words = new char[nWords][];
		for (int i=0; i<nWords; i++) {
			words[i] = convert(stdin.readLine().trim().toCharArray());
			sumWLen += words[i].length;
		}

		// This is what the flips were.
		target = convert(stdin.readLine().trim().toCharArray());
		len = target.length;

		// Run Aho-Corasick, to figure out what the string would be WITHOUT an extra pattern.
		ahoCorasick();
		System.out.println(solve());
	}

	public static int solve() {

		// These have to match!
		if (target[0] != actual[0]) return 0;

		// Another easy case, extra pattern could be anything long...
		if (equal()) return -1;

		// Find where the extra pattern finishes matching.
		boolean[] newMatch = getNewMatches();

		// Find the last index where the extra pattern matches.
		int addlen = 1;
		while (!newMatch[addlen-1]) addlen++;

		// Reverse this string, add 'C', then reverse the whole target string, marking where
		// the new string matches.
		boolean[] revMatch = new boolean[addlen+1+len];
		for (int i=0,j=addlen-1; i<addlen; i++,j--)
			revMatch[i] = newMatch[j];
		for (int i=addlen+1,j=len-1; j>=0; i++,j--)
			revMatch[i] = newMatch[j];

		char[] newTarget = new char[addlen+1+len];

		for (int i=0,j=addlen-1; i<addlen; i++,j--)
			newTarget[i] = target[j];
		newTarget[addlen] = 'C'; // Special separator from target string we are matching.

		// This is the whole target.
		for (int i=addlen+1,j=len-1; j>=0; i++,j--)
			newTarget[i] = target[j];

		// My hackpack code takes in a String...
		int[] zValues = getZarr(new String(newTarget));

		int minMatch = addlen, maxNoMatch = 0;

		// We are looking for the minimum Z-value from each location where the new string matches, as well
		// as the maximum Z value from each location where the new string doesn't match.
		// Trick is that we don't look at the very last letter, since we don't know the status of whether
		// or not our new string matched at the very end.
		for (int i=addlen+2; i<addlen+1+len; i++) {
			if (revMatch[i])
				minMatch = Math.min(minMatch, zValues[i]);
			else
				maxNoMatch = Math.max(maxNoMatch, zValues[i]);
		}

		// Our initial result, which assumes each suffix of the minMatch reversed is possible.
		int res = minMatch - maxNoMatch;

		// Go through each word to see if it was counted above, if so, remove it as a possibility.
		for (int i=0; i<nWords; i++) {
			
			// These weren't counted to begin with, so we don't need to sub them out.
			if (words[i].length > minMatch || words[i].length <= maxNoMatch) continue;
			
			boolean match = true;
			
			// Loop matching letters until there is a discrepancy.
			for (int j=words[i].length-1, k=0; j>=0; j--,k++) {
				if (words[i][j] != newTarget[k]) {
					match = false;
					break;
				}
			}
			
			// If the pattern matched and we get here, we sub out 1.
			if (match) res--;
		}

		// Here is our result.
		return Math.max(0, res);
	}

	// returns an array such that arr[i] == true iff the "extra" string matches as index i.
	public static boolean[] getNewMatches() {

		boolean[] res = new boolean[len];
		boolean cur = true;
		int i = -1;

		while (i+1 < len) {

			// Find the next time there is a "flip" in result between the two strings.
			while (i+1 < len && ((target[i+1] == actual[i+1]) == cur) ) i++;

			// Here is where the flip occurred.
			if (i < len-1) res[i] = true;

			// Update status.
			cur = !cur;
			i++;
		}

		return res;
	}

	// Returns true iff generated string is the same as the final string with the added pattern.
	public static boolean equal() {
		for (int i=0; i<len; i++)
			if (target[i] != actual[i])
				return false;
		return true;
	}

	// Turns T->A, H->B.
	public static char[] convert(char[] arr) {
		char[] res = new char[arr.length];
		for (int i=0; i<arr.length; i++)
			res[i] = arr[i] == 'T' ? 'A' : 'B';
		return res;
	}

	public static void ahoCorasick() {

		trie = new node();

		// Also insert each word into the trie.
		for (int i=0; i<nWords; i++)
			trie.insert(words[i], 0, i);

		// First step in building the Aho-Corasick Automaton. (Forwarding function...)
		trie.setNullToSelf();

		// Adding reachable states from initial to queue.
		ArrayDeque<node> q = new ArrayDeque<node>();
		for (int i=0; i<2; i++) {
			if (trie.next[i] != trie) {
				q.offer(trie.next[i]);
				trie.next[i].fail = trie;
			}
		}

		// Go until we've cleared the queue.
		while (q.size() > 0) {

			// Get the next item.
			node cur = q.poll();

			// Look at all the next links.
			for (int i=0; i<2; i++) {

				// Don't care about these.
				if (cur.next[i] == null) continue;

				// Put this state in the queue.
				q.offer(cur.next[i]);

				// Now, start from this fail state and "hop back"
				node tmp = cur.fail;

				while (tmp.next[i] == null) tmp = tmp.fail;

				// Link the next letter's fail function.
				cur.next[i].fail = tmp.next[i];

				// Add in all of these words into the matches at this node.
				cur.next[i].freq += cur.next[i].fail.freq;
			}
		}

		// Store result from n-1 strings here.
		actual = new char[len];
		actual[0] = 'A';
		int numMatches = 0;

		// Start out our pointer.
		node ptr = trie;

		// Go through the target string.
		for (int i=0; i<len-1; i++) {

			int nI = target[i]-'A';

			// Follow the next valid fail.
			while (ptr.next[nI] == null)
				ptr = ptr.fail;

			// This is where we want to go.
			ptr = ptr.next[nI];

			// All we care about is the parity of total matches!
			numMatches = (numMatches + ptr.freq)%2;

			actual[i+1] = (char)('A'+numMatches);
		}
	}

	/*** Taken from http://www.geeksforgeeks.org/z-algorithm-linear-time-pattern-searching-algorithm/ ***/

	//  Fills Z array for given string str[]
	public static int[] getZarr(String str) {

    	int n = str.length();
    	int[] Z = new int[n];
    	int L, R, k;
    	Z[0] = n; // Necessary for my purposes...

    	// [L,R] make a window which matches with prefix of s
    	L = R = 0;
    	for (int i = 1; i < n; ++i) {

        	// if i>R nothing matches so we will calculate.
        	// Z[i] using naive way.
        	if (i > R) {
	            L = R = i;

    	        // R-L = 0 in starting, so it will start
        	    // checking from 0'th index. For example,
            	// for "ababab" and i = 1, the value of R
            	// remains 0 and Z[i] becomes 0. For string
            	// "aaaaaa" and i = 1, Z[i] and R become 5
            	while (R<n && str.charAt(R-L) == str.charAt(R))
                	R++;
            	Z[i] = R-L;
            	R--;
        	}
        	else {

            	// k = i-L so k corresponds to number which
            	// matches in [L,R] interval.
            	k = i-L;

            	// if Z[k] is less than remaining interval
            	// then Z[i] will be equal to Z[k].
            	// For example, str = "ababab", i = 3, R = 5
            	// and L = 2
            	if (Z[k] < R-i+1)
                	 Z[i] = Z[k];

            	// For example str = "aaaaaa" and i = 2, R is 5,
            	// L is 0
            	else {

                	//  else start from R  and check manually
                	L = i;
                	while (R<n && str.charAt(R-L) == str.charAt(R))
                    	R++;
                	Z[i] = R-L;
                	R--;
            	}
        	}
    	}

    	return Z;
	}
}

class node {

	public int freq;
	public node[] next;
	public node fail;

	public node() {
		freq = 0;
		next = new node[2];
		Arrays.fill(next, null);
		fail = null;
	}

	// Inserts str at node i levels down the trie.
	public void insert(char[] str, int i, int wI) {

		// We are here!
		if (i == str.length) {
			freq++;
			return;
		}

		// Create the node if we need it.
		int nI = str[i]-'A';
		if (next[nI] == null) next[nI] = new node();

		// Recursively insert.
		next[nI].insert(str, i+1, wI);
	}

	// For forwarding function - only to be called on root.
	public void setNullToSelf() {
		for (int i=0; i<2; i++)
			if (next[i] == null)
				next[i] = this;
	}
}