def dfs(vertex, target, graph, visited):
    # Если достигли целевой вершины, возвращаем True
    if vertex == target:
        return True
    visited[vertex] = True
    # Рекурсивно проверяем всех соседей
    for neighbor in graph[vertex]:
        if not visited[neighbor]:
            if dfs(neighbor, target, graph, visited):
                return True
    return False

# Чтение входных данных:
# Первая строка: количество вершин и рёбер
n, m = map(int, input("Введите количество вершин и рёбер: ").split())

# Инициализация списка смежности для n вершин
graph = [[] for _ in range(n)]

print("Введите рёбра (по одному на строке, с номерами вершин):")
for _ in range(m):
    u, v = map(int, input().split())
    # Приведение номеров вершин к индексации с 0
    u -= 1
    v -= 1
    graph[u].append(v)
    graph[v].append(u)  # Если граф неориентированный

# Чтение номеров начальной (s) и целевой (t) вершин
s, t = map(int, input("Введите номера начальной и целевой вершин: ").split())
s -= 1
t -= 1

# Массив для отслеживания посещённых вершин
visited = [False] * n

# Проверка наличия пути с помощью DFS
if dfs(s, t, graph, visited):
    print("Путь между вершинами существует.")
else:
    print("Путь между вершинами отсутствует.")
            

#include <iostream>
#include <vector>

using namespace std;

// Рекурсивная функция DFS для проверки наличия пути от vertex до target
bool dfs(int vertex, int target, const vector<vector<int>>& graph, vector<bool>& visited) {
    if (vertex == target) return true; // Если достигли целевой вершины, путь найден
    visited[vertex] = true;            // Помечаем вершину как посещённую
    for (int neighbor : graph[vertex]) {  // Проходим по всем соседям
        if (!visited[neighbor]) {         // Если сосед ещё не посещён
            if (dfs(neighbor, target, graph, visited)) { // Рекурсивно ищем путь от соседа до target
                return true;
            }
        }
    }
    return false; // Если ни один путь не найден, возвращаем false
}

int main() {
    int n, m;
    cout << "Введите количество вершин и рёбер: ";
    cin >> n >> m;

    // Инициализация списка смежности для n вершин (индексация с 0)
    vector<vector<int>> graph(n);
    cout << "Введите рёбра (по одному на строке, с номерами вершин):" << endl;
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        // Приводим номера вершин к индексации с 0
        u--;
        v--;
        // Добавляем ребро в список смежности (для неориентированного графа)
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    int s, t;
    cout << "Введите номера начальной и целевой вершин: ";
    cin >> s >> t;
    // Приводим номера вершин к индексации с 0
    s--;
    t--;

    // Массив для отслеживания посещённых вершин
    vector<bool> visited(n, false);

    // Проверяем наличие пути с помощью DFS
    if (dfs(s, t, graph, visited))
        cout << "Путь между вершинами существует." << endl;
    else
        cout << "Путь между вершинами отсутствует." << endl;

    return 0;
}