#include <bits/stdc++.h>
const size_t MAX_N = 3003;
struct Vertex {
  std::vector<Vertex *> edges;
  int32_t ind;
};
Vertex graph[MAX_N];
int32_t vertexCnt;
int32_t dist[MAX_N][MAX_N];
void input() {
  int32_t edgeCnt;
  scanf("%i %i", &vertexCnt, &edgeCnt);
  for (int32_t i = 0; i < vertexCnt; i++) {
    graph[i].ind = i;
  }
  for (int32_t i = 0; i < edgeCnt; i++) {
    int32_t f, t;
    scanf("%i %i", &f, &t);
    graph[f - 1].edges.push_back(&graph[t - 1]);
  }
}
void calc_dist(int32_t from) {
  for (int32_t i = 0; i < vertexCnt; i++) {
    dist[from][i] = -100 * MAX_N;
  }
  dist[from][from] = 0;
  std::queue<Vertex *> next;
  next.push(&graph[from]);
  while (not next.empty()) {
    Vertex *cur = next.front();
    next.pop();
    for (Vertex *v : cur->edges) {
      if (dist[from][v->ind] < 0) {
        dist[from][v->ind] = dist[from][cur->ind] + 1;
        next.push(v);
      }
    }
  }
}
std::vector<std::pair<int32_t, int32_t>> sortFrom[MAX_N];
std::vector<std::pair<int32_t, int32_t>> sortTo[MAX_N];
void calc_sort_dist(int32_t from) {
  for (int32_t i = 0; i < vertexCnt; i++) {
    sortFrom[from].push_back(std::make_pair(dist[from][i], i));
    sortTo[from].push_back(std::make_pair(dist[i][from], i));
  }
  std::sort(sortFrom[from].begin(), sortFrom[from].end());
  std::sort(sortTo[from].begin(), sortTo[from].end());
  std::reverse(sortFrom[from].begin(), sortFrom[from].end());
  std::reverse(sortTo[from].begin(), sortTo[from].end());
}
int main() {
  input();
  for (int32_t i = 0; i < vertexCnt; i++) {
    calc_dist(i);
  }
  for (int32_t i = 0; i < vertexCnt; i++) {
    calc_sort_dist(i);
  }
  int32_t bestSum = -1;
  int32_t best1 = -1, best2, best3, best4;
  for (int32_t cur2 = 0; cur2 < vertexCnt; cur2++) {
    for (int32_t cur3 = 0; cur3 < vertexCnt; cur3++) {
      if (cur3 == cur2) {
        continue;
      }
      int32_t ind2 = 0;
      int32_t ind3 = 0;
      while ((sortFrom[cur3][ind3].second == cur2) ||
             (sortFrom[cur3][ind3].second == cur3)) {
        ind3++;
      }
      while ((sortTo[cur2][ind2].second == cur3) ||
             (sortTo[cur2][ind2].second == sortFrom[cur3][ind3].second) ||
             (sortTo[cur2][ind2].second == cur2)) {
        ind2++;
      }
      int32_t curDist = dist[cur2][cur3] + sortTo[cur2][ind2].first +
                        sortFrom[cur3][ind3].first;
      if (curDist > bestSum) {
        bestSum = curDist;
        best1 = sortTo[cur2][ind2].second;
        best2 = cur2;
        best3 = cur3;
        best4 = sortFrom[cur3][ind3].second;
      }
      ind3 = 0;
      ind2 = 0;
      while ((sortTo[cur2][ind2].second == cur3) ||
             (sortTo[cur2][ind2].second == cur2)) {
        ind2++;
      }
      while ((sortFrom[cur3][ind3].second == cur2) ||
             (sortFrom[cur3][ind3].second == sortTo[cur2][ind2].second) ||
             (sortFrom[cur3][ind3].second == cur3)) {
        ind3++;
      }
      curDist = dist[cur2][cur3] + sortTo[cur2][ind2].first +
                sortFrom[cur3][ind3].first;
      if (curDist > bestSum) {
        bestSum = curDist;
        best1 = sortTo[cur2][ind2].second;
        best2 = cur2;
        best3 = cur3;
        best4 = sortFrom[cur3][ind3].second;
      }
    }
  }
  printf("%i %i %i %i\n", best1 + 1, best2 + 1, best3 + 1, best4 + 1);
}
