#include <bits/stdc++.h>
using namespace std;
int n, m;
int dis[3010][3010] = {0};
int INF = (1 << 28);
int f[3010] = {0};
bool vis[3010] = {0};
vector<int> G[3010];
int cur;
int rankA[3010][3010] = {0}, rankB[3010][3010] = {0};
int ans = 0, a, b, c, d;
bool com(int i, int j) { return dis[cur][i] > dis[cur][j]; }
bool som(int i, int j) { return dis[i][cur] > dis[j][cur]; }
void BFS(int s) {
  int i, u, v;
  queue<int> q;
  for (i = 1; i <= n; i++) {
    vis[i] = 0;
    f[i] = -INF;
  }
  q.push(s);
  f[s] = 0;
  vis[s] = 1;
  while (!q.empty()) {
    u = q.front();
    q.pop();
    for (i = 0; i < G[u].size(); i++) {
      v = G[u][i];
      if (!vis[v]) {
        vis[v] = 1;
        f[v] = f[u] + 1;
        q.push(v);
      }
    }
  }
  f[s] = -INF;
}
void read() {
  int i, u, v;
  cin >> n >> m;
  for (i = 1; i <= m; i++) {
    cin >> u >> v;
    G[u].push_back(v);
  }
}
void update(int u, int v) {
  int i, j, temp, x, y;
  for (i = 1; i <= 4; i++) {
    x = rankA[u][i];
    if (x == u || x == v) continue;
    for (j = 1; j <= 4; j++) {
      y = rankB[v][j];
      if (y == u || y == v || y == x) continue;
      temp = dis[x][u] + dis[u][v] + dis[v][y];
      if (temp > ans) {
        ans = temp;
        a = x;
        b = u;
        c = v;
        d = y;
      }
    }
  }
}
void work() {
  int i, j;
  for (i = 1; i <= n; i++) {
    BFS(i);
    memcpy(dis[i], f, sizeof(f));
  }
  for (i = 1; i <= n; i++) {
    for (j = 1; j <= n; j++) {
      rankA[i][j] = rankB[i][j] = j;
    }
    cur = i;
    sort(rankA[i] + 1, rankA[i] + n + 1, som);
    sort(rankB[i] + 1, rankB[i] + n + 1, com);
  }
  for (i = 1; i <= n; i++) {
    for (j = 1; j <= n; j++) {
      if (i == j || dis[i][j] == INF) continue;
      update(i, j);
    }
  }
  cout << a << ' ' << b << ' ' << c << ' ' << d << endl;
}
int main() {
  read();
  work();
  return 0;
}
