#include <fstream>
#include <vector>
#include <cmath>
#include <cassert>
#include <iostream>
using namespace std;
#define MAX_LEN 1000000
typedef vector<int> VI;
const double PI = acos(0) * 2;
unsigned partialSums[MAX_LEN + 1];
class complex
{
public:
double a, b;
complex() {a = 0.0; b = 0.0;}
complex(double na, double nb) {a = na; b = nb;}
const complex operator+(const complex &c) const
{return complex(a + c.a, b + c.b);}
const complex operator-(const complex &c) const
{return complex(a - c.a, b - c.b);}
const complex operator*(const complex &c) const
{return complex(a*c.a - b*c.b, a*c.b + b*c.a);}
double magnitude() {return sqrt(a*a+b*b);}
void print() {printf("(%.3f %.3f)\n", a, b);}
};
class FFT
{
public:
vector<complex> data;
vector<complex> roots;
VI rev;
int s, n;
void setSize(int ns)
{
s = ns;
n = (1 << s);
int i, j;
rev = VI(n);
data = vector<complex> (n);
roots = vector<complex> (n+1);
for (i = 0; i < n; i++)
for (j = 0; j < s; j++)
if ((i & (1 << j)) != 0)
rev[i] += (1 << (s-j-1));
roots[0] = complex(1, 0);
complex mult = complex(cos(2*PI/n), sin(2*PI/n));
for (i = 1; i <= n; i++)
roots[i] = roots[i-1] * mult;
}
void bitReverse(vector<complex> &array)
{
vector<complex> temp(n);
int i;
for (i = 0; i < n; i++)
temp[i] = array[rev[i]];
for (i = 0; i < n; i++)
array[i] = temp[i];
}
void transform(bool inverse = false)
{
bitReverse(data);
int i, j, k;
for (i = 1; i <= s; i++) {
int m = (1 << i), md2 = m / 2;
int start = 0, increment = (1 << (s-i));
if (inverse) {
start = n;
increment *= -1;
}
complex t, u;
for (k = 0; k < n; k += m) {
int index = start;
for (j = k; j < md2+k; j++) {
t = roots[index] * data[j+md2];
index += increment;
data[j+md2] = data[j] - t;
data[j] = data[j] + t;
}
}
}
if (inverse)
for (i = 0; i < n; i++) {
data[i].a /= n;
data[i].b /= n;
}
}
static VI convolution(VI &a, VI &b)
{
int alen = a.size(), blen = b.size();
int resn = alen; // size of the resulting array
int s = 0, i;
while ((1 << s) < resn) s++; // n = 2^s
int n = 1 << s; // round up the the nearest power of two
FFT pga, pgb;
pga.setSize(s); // fill and transform first array
for (i = 0; i < alen; i++) pga.data[i] = complex(a[i], 0);
for (i = alen; i < n; i++) pga.data[i] = complex(0, 0);
pga.transform();
pgb.setSize(s); // fill and transform second array
for (i = 0; i < blen; i++) pgb.data[i] = complex(b[i], 0);
for (i = blen; i < n; i++) pgb.data[i] = complex(0, 0);
pgb.transform();
for (i = 0; i < n; i++) pga.data[i] = pga.data[i] * pgb.data[i];
pga.transform(true); // inverse transform
VI result = VI (resn); // round to nearest integer
for (i = 0; i < resn; i++) result[i] = (int) (pga.data[i].a + 0.5);
int actualSize = resn - 1; // find proper size of array
while (result[actualSize] == 0)
actualSize--;
if (actualSize < 0) actualSize = 0;
result.resize(actualSize+1);
return result;
}
};
unsigned square(uint32_t x) {
return x * x;
}
int getSum(int pos, uint32_t needlelen) {
return partialSums[pos + needlelen - 1] - ((!pos) ? 0 : partialSums[pos - 1]);
}
const int SIGMA = 26;
const int ALL = 1 << 8;
int alphaTable[ALL + 1];
void init() {
for (char c = 'a'; c <= 'z'; c++)
alphaTable[c] = c - 'a';
for (char c = 'A'; c <= 'Z'; c++)
alphaTable[c] = c - 'A' + SIGMA;
}
inline int encode(char c) {
return alphaTable[c];
}
unsigned solve(VI& s, uint32_t size, string& pattern) {
unsigned needlelen = pattern.size();
if (needlelen > s.size())
return 'N';
VI p(needlelen);
for (unsigned index = 0; index < needlelen; index++)
p[needlelen - index - 1] = encode(pattern[index]);
int constPattern = 0;
for (unsigned index = 0; index < needlelen; index++)
constPattern += square(p[index]);
// Apply only for s and p.
VI ret = FFT::convolution(s, p);
// Shift the window at every step.
unsigned noMatches = 0;
for (unsigned i = 0; i < size - needlelen + 1; i++)
noMatches += ((ret[i + needlelen - 1] << 1) == constPattern + getSum(i, needlelen));
return noMatches;
}
int main(void) {
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
init();
string text;
int Q;
cin >> text >> Q;
unsigned size = text.size();
VI s(size);
for (unsigned index = 0; index < size; index++) {
s[index] = encode(text[index]);
partialSums[index] = square(s[index]) + ((!index) ? 0 : partialSums[index - 1]);
}
while (Q--) {
string pattern;
cin >> pattern;
cout << solve(s, size, pattern) << '\n';
}
return 0;
}