#if 1
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <array>
#include <deque>
#include <algorithm>
#include <utility>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <numeric>
#include <assert.h>
#include <bitset>
#include <list>

auto& in = std::cin;
auto& out = std::cout;
#define all(C) std::begin(C), std::end(C)
const double PI = 3.141592653589793238462643383279502884197169399375105820974944;

struct Trie {
	Trie* node[26] = {};//各アルファベットへの子のポインタ
	bool black=false;//この文字列の頂点が黒かどうか
	Trie() :node() {}
	void add(const char* str) {
		if (*str == '\0') {
			black = true;
			return;
		}
		int nxt = *str - 'a';
		if (!node[nxt]) {
			node[nxt] = new Trie;
		}
		node[nxt]->add(str + 1);
	}
	//strを見つけて、最も浅い高さにいるblackな頂点の高さを返す
	//ない場合は-1
	int search(const char* str) {
		if (black)
			return 0;
		if (*str == '\0')
			return -1;
		int nxt = *str - 'a';
		if (!node[nxt]) {
			return -1;
		}
		int res = node[nxt]->search(str + 1);
		if (res == -1)return -1;
		return res + 1;
	}
};

using namespace std;
using ULL = unsigned long long;
const ULL P = 1000000007;
struct RollHash {
	string str;
	vector<ULL>imos;//[0,i)までのハッシュがあるよ
	vector<ULL>pvar;//Pのi乗が入っているよ
	RollHash(string str) :str(str) {
		imos.push_back(0);
		for (int i = 0; i < (int)str.size(); ++i) {
			imos.push_back(imos.back() * P + str[i]);
		}
		pvar.push_back(1);
		for (int i = 0; i <(int)str.size(); ++i) {
			pvar.push_back(pvar.back() * P);
		}
	}
	//[x,y)までのハッシュを返すよ
	ULL getHash(int x, int y) {
		return imos[y] - imos[x] * pvar[y - x];
	}
};

Trie trie;
std::string S;
std::string S_rever;
std::vector<std::string> p_small;
//std::vector<std::string> p_large;
std::vector<RollHash> p_RH;
int32_t N;
int32_t DP_[100010];
int32_t* DP = DP_+2;//[j]はjに*を入れたときの最小値
int main()
{
	using std::endl;
	in.sync_with_stdio(false);
	out.sync_with_stdio(false);
	in.tie(nullptr);
	out.tie(nullptr);

	in >> S >> N; S_rever = S; std::reverse(S_rever.begin(), S_rever.end());
	for (int32_t i = 0; i < N; i++)
	{
		std::string input;
		in >> input;
		if (input.size() <= 317) {
			p_small.emplace_back(std::move(input));
		}
		else {
			//p_large.emplace_back(std::move(input));
			p_RH.emplace_back(std::move(input));
		}
	}


	//小さいほうをとらい木に突っ込む
	for (auto& i : p_small)
	{
		std::reverse(i.begin(), i.end());
		trie.add(i.c_str());
	}

	RollHash S_RH{ S };
	auto iter = S_rever.c_str() + S_rever.size()-1;
	int32_t ok_begin = -1;
	DP[-1] = 0;
	for (int32_t i = 0; i < S.size(); i++)
	{
		//i追加
		DP[i] = DP[ok_begin] + 1;

		//OKを移動
		int res = trie.search(iter);
		if (res == -1) {}
		else {
			ok_begin = std::max(ok_begin, i - res + 1);
		}
		--iter;

		for (auto& P : p_RH)
		{
			int size = P.str.size();
			if (i - size + 1 < 0) { continue; }
			auto bace = S_RH.getHash(i- size+1, i + 1);
			auto other = P.getHash(0, size);
			if (bace == other) {
				ok_begin = std::max(ok_begin, i - size + 1);
			}
		}

	}

	int32_t min_ = 10000000;
	for (int32_t i = ok_begin; i < (int)S.size(); i++)
	{
		min_ = std::min(min_, DP[i]);
	}
	out << min_ << endl;

	return 0;
}
#endif




Measured memory_bytes: 22776