#include <bits/stdc++.h>
using namespace std;
const int maxn = 3010;
struct Pre {
  int to, Len;
};
int dist[maxn][maxn], V, E;
Pre SO[maxn][5], AR[maxn][5];
vector<int> G[maxn];
void SPFA(int s, int *d) {
  bool visited[maxn];
  memset(visited, 0, sizeof(visited));
  fill(d + 1, d + V + 1, 1e9 + 7);
  queue<int> Q;
  d[s] = 0;
  visited[s] = 1;
  Q.push(s);
  while (!Q.empty()) {
    int t;
    t = Q.front();
    Q.pop();
    visited[t] = 0;
    for (int i = 0; i < G[t].size(); i++) {
      int temp = G[t][i];
      if (d[t] + 1 < d[temp]) {
        d[temp] = d[t] + 1;
        if (!visited[temp]) {
          visited[temp] = 1;
          Q.push(temp);
        }
      }
    }
  }
}
int main() {
  scanf("%d%d", &V, &E);
  for (int i = 1; i <= V; i++) {
    SO[i][1].Len = 0;
    SO[i][2].Len = 0;
    SO[i][3].Len = 0;
    AR[i][1].Len = 0;
    AR[i][2].Len = 0;
    AR[i][3].Len = 0;
  }
  for (int i = 0; i < E; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    G[u].push_back(v);
  }
  for (int i = 1; i <= V; i++) {
    SPFA(i, dist[i]);
  }
  for (int i = 1; i <= V; i++) {
    for (int j = 1; j <= V; j++) {
      if (dist[i][j] != 1e9 + 7 && dist[i][j] > SO[i][1].Len) {
        SO[i][3].Len = SO[i][2].Len;
        SO[i][3].to = SO[i][2].to;
        SO[i][2].Len = SO[i][1].Len;
        SO[i][2].to = SO[i][1].to;
        SO[i][1].Len = dist[i][j];
        SO[i][1].to = j;
      } else if (dist[i][j] != 1e9 + 7 && dist[i][j] > SO[i][2].Len) {
        SO[i][3].Len = SO[i][2].Len;
        SO[i][3].to = SO[i][2].to;
        SO[i][2].Len = dist[i][j];
        SO[i][2].to = j;
      } else if (dist[i][j] != 1e9 + 7 && dist[i][j] > SO[i][3].Len) {
        SO[i][3].Len = dist[i][j];
        SO[i][3].to = j;
      }
      if (dist[j][i] != 1e9 + 7 && dist[j][i] > AR[i][1].Len) {
        AR[i][3].Len = AR[i][2].Len;
        AR[i][3].to = AR[i][2].to;
        AR[i][2].Len = AR[i][1].Len;
        AR[i][2].to = AR[i][1].to;
        AR[i][1].Len = dist[j][i];
        AR[i][1].to = j;
      } else if (dist[j][i] != 1e9 + 7 && dist[j][i] > AR[i][2].Len) {
        AR[i][3].Len = AR[i][2].Len;
        AR[i][3].to = AR[i][2].to;
        AR[i][2].Len = dist[j][i];
        AR[i][2].to = j;
      } else if (dist[j][i] != 1e9 + 7 && dist[j][i] > AR[i][3].Len) {
        AR[i][3].Len = dist[j][i];
        AR[i][3].to = j;
      }
    }
  }
  int cnt = 0, a = 0, b = 0, c = 0, d = 0;
  for (int j = 1; j <= V; j++) {
    for (int k = 1; k <= V; k++) {
      if (j == k || dist[j][k] == 1e9 + 7) continue;
      int i = 0, l = 0;
      for (int zz = 1; zz <= 3; zz++) {
        if (AR[j][zz].to != j && AR[j][zz].to != k && AR[j][zz].to != 0) {
          i = AR[j][zz].to;
          break;
        }
      }
      for (int ss = 1; ss <= 3; ss++) {
        if (SO[k][ss].to != j && SO[k][ss].to != k && SO[k][ss].to != i &&
            SO[k][ss].to != 0) {
          l = SO[k][ss].to;
          break;
        }
      }
      int tot = dist[i][j] + dist[j][k] + dist[k][l];
      if (i != 0 && l != 0 && cnt < tot) {
        cnt = tot;
        a = i;
        b = j;
        c = k;
        d = l;
      }
      for (int ss = 1; ss <= 3; ss++) {
        if (SO[k][ss].to != j && SO[k][ss].to != k && SO[k][ss].to != 0) {
          l = SO[k][ss].to;
          break;
        }
      }
      for (int zz = 1; zz <= 3; zz++) {
        if (AR[j][zz].to != j && AR[j][zz].to != k && AR[j][zz].to != 0 &&
            AR[j][zz].to != l) {
          i = AR[j][zz].to;
          break;
        }
      }
      if (i != 0 && l != 0 && cnt < tot) {
        cnt = tot;
        a = i;
        b = j;
        c = k;
        d = l;
      }
    }
  }
  printf("%d %d %d %d\n", a, b, c, d);
  return 0;
}
