#include <bits/stdc++.h>
using namespace std;
vector<string> _split(const string& s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c)) v.emplace_back(x);
  return v;
}
void _print(vector<string>::iterator) {}
template <typename T, typename... Args>
void _print(vector<string>::iterator it, T a, Args... args) {
  string name = it->substr((*it)[0] == ' ', it->length());
  if (isalpha(name[0]))
    cerr << name << " = " << a << " ";
  else
    cerr << name << " ";
  _print(++it, args...);
}
const int INF = (int)1e9;
const int N = 3005;
int n, m;
vector<int> graph[N], rev_graph[N];
int dist[N];
int mx_dist[N][N];
vector<pair<int, int> > go[N];
vector<pair<int, int> > rev_go[N];
int ans;
vector<int> ans_path;
bool used[N];
void precalc(int sv) {
  fill(dist, dist + n, INF);
  dist[sv] = 0;
  queue<int> q;
  q.push(sv);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (int to : graph[v])
      if (dist[to] == INF) {
        dist[to] = dist[v] + 1;
        q.push(to);
      }
  }
  for (int i = 0; i < n; i++) mx_dist[sv][i] = dist[i];
  vector<pair<int, int> > list;
  for (int i = 0; i < n; i++) {
    if (i == sv || dist[i] == INF) continue;
    list.emplace_back(dist[i], i);
    sort(list.rbegin(), list.rend());
    if ((int)list.size() == 4) list.pop_back();
  }
  go[sv] = list;
}
void rev_precalc(int sv) {
  fill(dist, dist + n, INF);
  dist[sv] = 0;
  queue<int> q;
  q.push(sv);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (int to : rev_graph[v])
      if (dist[to] == INF) {
        dist[to] = dist[v] + 1;
        q.push(to);
      }
  }
  vector<pair<int, int> > list;
  for (int i = 0; i < n; i++) {
    if (i == sv || dist[i] == INF) continue;
    list.emplace_back(dist[i], i);
    sort(list.rbegin(), list.rend());
    if ((int)list.size() == 4) list.pop_back();
  }
  rev_go[sv] = list;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    graph[a].push_back(b);
    rev_graph[b].push_back(a);
  }
  for (int i = 0; i < n; i++) {
    precalc(i);
    rev_precalc(i);
  }
  for (int b = 0; b < n; b++) {
    for (int c = 0; c < n; c++) {
      if (b == c || mx_dist[b][c] == INF) continue;
      for (auto aa : rev_go[b]) {
        int a = aa.second;
        int a_dist = aa.first;
        if (a == b || a == c) continue;
        for (auto dd : go[c]) {
          int d = dd.second;
          int d_dist = dd.first;
          if (d == a || d == b || d == c) continue;
          int cur_ans = a_dist + mx_dist[b][c] + d_dist;
          if (cur_ans > ans) {
            ans = cur_ans;
            ans_path = {a, b, c, d};
          }
        }
      }
    }
  }
  for (int x : ans_path) printf("%d ", x + 1);
  return 0;
}
