"""
    https://stepik.org/lesson/701990/step/8?unit=702091

Ваша задача написать программу поиска слова в строке. Задача усложняется тем, что слово должно определяться в разных его формах. Например, слово:
программирование
может иметь следующие формы:
программирование, программированию, программированием, программировании, программирования, программированиям, программированиями, программированиях

Для решения этой задачи необходимо объявить класс Morph (морфология), объекты которого создаются командой:
mw = Morph(word1, word2, ..., wordN)
где word1, word2, ..., wordN - возможные формы слова.

В классе Morph реализовать методы:
add_word(self, word) - добавление нового слова (если его нет в списке слов объекта класса Morph);
get_words(self) - получение кортежа форм слов.

Также с объектами класса Morph должны выполняться следующие операторы сравнения:
mw1 == "word"  # True, если объект mv1 содержит слово "word" (без учета регистра)
mw1 != "word"  # True, если объект mv1 не содержит слово "word" (без учета регистра)
И аналогичная пара сравнений:
"word" == mw1
"word" != mw1

После создания класса Morph, формируется список dict_words из объектов этого класса, для следующих слов с их словоформами:
- связь, связи, связью, связей, связям, связями, связях
- формула, формулы, формуле, формулу, формулой, формул, формулам, формулами, формулах
- вектор, вектора, вектору, вектором, векторе, векторы, векторов, векторам, векторами, векторах
- эффект, эффекта, эффекту, эффектом, эффекте, эффекты, эффектов, эффектам, эффектами, эффектах
- день, дня, дню, днем, дне, дни, дням, днями, днях

Затем, прочитайте строку из входного потока командой:
text = input()
Найдите все вхождения слов из списка dict_words (используя операторы сравнения) в строке text (без учета регистра, знаков пунктуаций и их словоформы). Выведите на экран полученное число.
"""
import sys
import subprocess

sys.stdin.reconfigure(encoding="utf-8")


def run_test(request, expected, num=0, count=0):
    test_id = "" if num == 0 else f" #{num}" + (f"of {count}" if count else "")

    p = subprocess.run(
        [sys.executable, __file__],
        input=f"{request}\n",
        encoding="utf-8",
        text=True,
        capture_output=True,
    )
    if p.stderr:
        print("StdErr:\n", p.stderr, file=sys.stderr)
    p.check_returncode()

    answer = (p.stderr + p.stdout).strip()
    assert (
        answer == expected
    ), f"""\nFailed test{test_id}. Wrong answer
    
    This is a sample test from the problem statement!

    Test input:
    {request}

    Correct output:
    {expected}


    Your code output:
    {answer}
    """


def stdin_tests():
    tests = [
        ("Мы будем устанавливать связь завтра днем.", "2"),
        ("Завтра после полудня мы установим контакт.", "0"),
        ("Напишите формулу L1-нормы вектора.", "2"),
        ("Ф:о@рм-у-л.а за формулой, д.е.н.ь за днем", "4"),
    ]
    for i, test in enumerate(tests):
        run_test(*test, i, len(tests))


if sys.argv[-1] == "test":
    stdin_tests()
    exit()
# ---------

from functools import total_ordering


@total_ordering
class Morph:
    def __init__(self, *words):
        self.words = set(map(str.lower, words))
        # тесты просят сохранять порядок и дубликаты для get_words
        #  но только для исходных данных
        # немножко возражаю, хочу set!
        self.words_for_tests = list(map(str.lower, words))

    def __repr__(self):
        return f"{self.__class__.__name__}({', '.join(map(repr, self.words))})"

    def add_word(self, word):
        l0 = len(self)
        self.words.add(word.lower())
        if len(self) > l0:
            self.words_for_tests.append(word.lower())

    def get_words(self):
        return tuple(self.words_for_tests)

    def __len__(self):
        return len(self.words)

    def __radd__(self, other):
        return self + other

    def __add__(self, other):
        if hasattr(other, "words"):
            return self.__class__(*self.words, *other.words)
        if isinstance(other, str):
            return self.__class__(*self.words, *other.split())
        return NotImplemented

    def __contains__(self, other):
        return self == other

    def __eq__(self, other):
        if hasattr(other, "words"):
            return self.words == other.words
        if isinstance(other, str):
            return other.lower() in self.words
        return NotImplemented

    def __lt__(self, other):
        if hasattr(other, "words"):
            return self.words < other.words
        if isinstance(other, str):
            return other.lower() in self.words
        return NotImplemented

    def __gt__(self, other):
        if hasattr(other, "words"):
            return self.words > other.words
        if isinstance(other, str):
            return False
        return NotImplemented


data = """\
- связь, связи, связью, связей, связям, связями, связях
- формула, формулы, формуле, формулу, формулой, формул, формулам, формулами, формулах
- вектор, вектора, вектору, вектором, векторе, векторы, векторов, векторам, векторами, векторах
- эффект, эффекта, эффекту, эффектом, эффекте, эффекты, эффектов, эффектам, эффектами, эффектах
- день, дня, дню, днем, дне, дни, дням, днями, днях\
"""
sanitizer = str.maketrans({k: "" for k in "–?!,.:;()+-*^%$#@№/\\<>"})
dict_words = [*map(lambda x: Morph(*x.translate(sanitizer).split()), data.split("\n"))]
all_words = sum(dict_words, Morph())

text = input()  # эту строчку не менять

words = [*map(lambda x: x.translate(sanitizer), text.split())]
print(sum(word in all_words for word in words))