#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 move(v);
}
void err(vector<string>::iterator it) {}
template <typename T, typename... Args>
void err(vector<string>::iterator it, T a, Args... args) {
  cerr << it->substr((*it)[0] == ' ', it->length()) << " = " << a << '\n';
  err(++it, args...);
}
static constexpr int inf = std::numeric_limits<int>::max() / 4;
const int M = 3010;
struct data {
  int u, c;
  data(int a, int b) {
    u = a;
    c = b;
  }
  bool operator<(const data& d) const {
    if (c == d.c)
      return u < d.u;
    else
      return c < d.c;
  }
};
vector<int> A[M], T[M];
set<data> F[M], R[M];
int dist[M][M], rev[M][M];
void bfs(int p) {
  int visited[M], u, v, i;
  memset((visited), (false), sizeof(visited));
  queue<int> q;
  q.push(p);
  dist[p][p] = 0;
  visited[p] = true;
  while (!q.empty()) {
    u = q.front();
    q.pop();
    for (i = 0; i < A[u].size(); i++) {
      v = A[u][i];
      if (!visited[v]) {
        visited[v] = true;
        dist[p][v] = dist[p][u] + 1;
        q.push(v);
      }
    }
  }
}
void bfs_rev(int p) {
  int visited[M], u, v, i;
  memset((visited), (false), sizeof(visited));
  queue<int> q;
  q.push(p);
  rev[p][p] = 0;
  visited[p] = true;
  while (!q.empty()) {
    u = q.front();
    q.pop();
    for (i = 0; i < T[u].size(); i++) {
      v = T[u][i];
      if (!visited[v]) {
        visited[v] = true;
        rev[p][v] = rev[p][u] + 1;
        q.push(v);
      }
    }
  }
}
int main() {
  int i, j, k, l, n, m, u, v;
  set<data>::iterator it, x, y;
  scanf("%d%d", &n, &m);
  while (m--) {
    scanf("%d%d", &u, &v);
    A[u].push_back(v);
    T[v].push_back(u);
  }
  for (i = 1; i <= n; i++)
    for (j = 1; j <= n; j++) dist[i][j] = -inf, rev[i][j] = -inf;
  for (i = 1; i <= n; i++) bfs(i);
  for (i = 1; i <= n; i++) {
    for (j = 1; j <= n; j++) {
      if (F[i].size() < 4)
        F[i].insert(data(j, dist[i][j]));
      else {
        it = F[i].begin();
        if (dist[i][j] > it->c) {
          F[i].erase(it);
          F[i].insert(data(j, dist[i][j]));
        }
      }
    }
  }
  for (i = 1; i <= n; i++) bfs_rev(i);
  for (i = 1; i <= n; i++) {
    for (j = 1; j <= n; j++) {
      if (R[i].size() < 4)
        R[i].insert(data(j, rev[i][j]));
      else {
        it = R[i].begin();
        if (rev[i][j] > it->c) {
          R[i].erase(it);
          R[i].insert(data(j, rev[i][j]));
        }
      }
    }
  }
  int maxx = 0, a, b, c, d;
  for (i = 1; i <= n; i++) {
    for (j = 1; j <= n; j++) {
      if (i == j) continue;
      for (__typeof((R[i]).begin()) x = (R[i]).begin(); x != (R[i]).end();
           x++) {
        for (__typeof((F[j]).begin()) y = (F[j]).begin(); y != (F[j]).end();
             y++) {
          k = x->u;
          l = y->u;
          if (k == l || i == k || i == l || j == k || j == l) continue;
          if (dist[k][i] + dist[i][j] + dist[j][l] > maxx) {
            maxx = dist[k][i] + dist[i][j] + dist[j][l];
            a = k;
            b = i;
            c = j;
            d = l;
          }
        }
      }
    }
  }
  printf("%d %d %d %d\n", a, b, c, d);
  return 0;
}
