using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("ABCDABCD");
WillReturn.Add("3");
WillReturn.Add("A");
WillReturn.Add("DA");
WillReturn.Add("ABCDABCD");
//4
}
else if (InputPattern == "Input2") {
WillReturn.Add("YUKICODER");
WillReturn.Add("2");
WillReturn.Add("X");
WillReturn.Add("ABCDEFGHIJ");
//0
}
else if (InputPattern == "Input3") {
WillReturn.Add("AAAA");
WillReturn.Add("4");
WillReturn.Add("A");
WillReturn.Add("AA");
WillReturn.Add("AAA");
WillReturn.Add("AAAA");
//10
}
else if (InputPattern == "Input4") {
WillReturn.Add("ABAACABCAACBABABACBBAC");
WillReturn.Add("7");
WillReturn.Add("A");
WillReturn.Add("C");
WillReturn.Add("AA");
WillReturn.Add("ABB");
WillReturn.Add("ABA");
WillReturn.Add("BA");
WillReturn.Add("CBBAC");
//26
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
string S = InputList[0];
var InsRollingHash = new RollingHash(S);
int UB = S.Length - 1;
// 件数[ハッシュ値]なDict
var CntDict = new Dictionary<decimal, long>();
for (int LoopRange = 1; LoopRange <= 10; LoopRange++) {
for (int RangeSta = 0; RangeSta <= UB; RangeSta++) {
int RangeEnd = RangeSta + LoopRange - 1;
if (RangeEnd > UB) break;
decimal Hash = InsRollingHash.GetRangeHash(RangeSta, RangeEnd);
if (CntDict.ContainsKey(Hash) == false) {
CntDict[Hash] = 0;
}
CntDict[Hash]++;
}
}
long Answer = 0;
foreach (string EachStr in InputList.Skip(2)) {
var CurrRollingHash = new RollingHash(EachStr);
int RangeSta = 0;
int RangeEnd = EachStr.Length - 1;
decimal CurrHash = CurrRollingHash.GetRangeHash(RangeSta, RangeEnd);
if (CntDict.ContainsKey(CurrHash)) {
Answer += CntDict[CurrHash];
}
}
Console.WriteLine(Answer);
}
}
#region RollingHash
// ローリングハッシュ
internal class RollingHash
{
const decimal Base = 100M;
const decimal Hou = 67280421310721M;
// ハッシュ値[終了Ind]で、[0,終了Ind]のハッシュ値を保持
decimal[] mHashArr;
// 桁の重みの配列
decimal[] mOmomiArr;
// コンストラクタ
internal RollingHash(string pTargetStr)
{
decimal Omomi = 1;
long UB = pTargetStr.Length - 1;
mHashArr = new decimal[UB + 1];
mOmomiArr = new decimal[UB + 1];
for (int I = 0; I <= UB; I++) {
mOmomiArr[I] = Omomi;
if (I > 0) {
mHashArr[I] += mHashArr[I - 1] * Base;
mHashArr[I] %= Hou;
}
mHashArr[I] += pTargetStr[I];
mHashArr[I] %= Hou;
Omomi *= Base;
Omomi %= Hou;
}
}
// [Sta,End]のハッシュ値を返す
internal decimal GetRangeHash(long pSta, long pEnd)
{
decimal WillReturn = mHashArr[pEnd];
if (pSta > 0) {
long Range = pEnd - pSta + 1;
decimal PrevVal = mHashArr[pSta - 1];
decimal MinusVal = PrevVal * mOmomiArr[Range];
MinusVal %= Hou;
WillReturn -= MinusVal;
if (WillReturn < 0) {
WillReturn += Hou;
}
}
return WillReturn;
}
}
#endregion