#include <bits/stdc++.h>
using namespace std;
struct Result {
  int u, v, w, z;
};
int N, M;
vector<vector<int>> edges, distances;
vector<vector<pair<int, int>>> D, R;
vector<int> enqueued;
int best = -1;
Result result;
int scan() {
  auto c = getchar();
  while (c < '0' || c > '9') c = getchar();
  int n;
  for (n = 0; '0' <= c && c <= '9'; c = getchar()) n = n * 10 + c - '0';
  return n;
}
void bfs(int start) {
  queue<pair<int, int>> q;
  q.push({start, 0});
  enqueued[start] = start;
  while (!q.empty()) {
    auto &p = q.front();
    q.pop();
    D[start].push_back(p);
    R[p.first].push_back({start, p.second});
    distances[start][p.first] = p.second;
    for (auto &v : edges[p.first]) {
      if (enqueued[v] != start) {
        q.push({v, p.second + 1});
        enqueued[v] = start;
      }
    }
  }
}
inline bool cmp(const pair<int, int> &a, const pair<int, int> &b) {
  return a.second > b.second;
}
pair<int, int> find(const vector<pair<int, int>> &X, int a, int b, int c) {
  for (auto &x : X) {
    if (x.first != a && x.first != b && x.first != c) return x;
  }
  return {-1, -1};
}
void process() {
  for (auto i = 0; i < N; i++) {
    for (auto j = 0; j < N; j++) {
      if (i == j || distances[i][j] == 0) continue;
      do {
        auto k = find(R[i], i, j, -1);
        if (k.first == -1) break;
        auto l = find(D[j], i, j, k.first);
        if (l.first == -1) break;
        auto value = k.second + l.second + distances[i][j];
        if (value > best) {
          best = value;
          result = {k.first, i, j, l.first};
        }
      } while (false);
      do {
        auto l = find(D[j], i, j, -1);
        if (l.first == -1) break;
        auto k = find(R[i], i, j, l.first);
        if (k.first == -1) break;
        auto value = k.second + l.second + distances[i][j];
        if (value > best) {
          best = value;
          result = {k.first, i, j, l.first};
        }
      } while (false);
    }
  }
}
int main() {
  N = scan();
  M = scan();
  edges.resize(N);
  distances.resize(N);
  D.resize(N);
  R.resize(N);
  enqueued.resize(N);
  fill(enqueued.begin(), enqueued.end(), -1);
  for (auto i = 0; i < M; i++) {
    auto x = scan() - 1;
    auto y = scan() - 1;
    edges[x].push_back(y);
  }
  for (auto i = 0; i < N; i++) {
    vector<int> &v = edges[i];
    sort(v.begin(), v.end());
    v.resize(distance(v.begin(), unique(v.begin(), v.end())));
    distances[i].resize(N);
  }
  for (auto i = 0; i < N; i++) bfs(i);
  for (auto i = 0; i < N; i++) {
    sort(D[i].begin(), D[i].end(), cmp);
    sort(R[i].begin(), R[i].end(), cmp);
  }
  process();
  printf("%d %d %d %d\n", result.u + 1, result.v + 1, result.w + 1,
         result.z + 1);
}
