#include <bits/stdc++.h>
using namespace std;
int current, n, m, ans;
vector<int> to[3010], from[3010], G[3010];
int d[3010][3010];
bool viz[3010];
vector<int> sol;
bool cmp1(int a, int b) { return d[a][current] > d[b][current]; }
bool cmp2(int a, int b) { return d[current][a] > d[current][b]; }
void bfs(int x, int d[]) {
  for (int i = 1; i <= n; ++i) {
    d[i] = 1000000000;
    viz[i] = false;
  }
  d[x] = 0;
  queue<int> Q;
  Q.push(x);
  viz[x] = true;
  while (!Q.empty()) {
    int x = Q.front();
    Q.pop();
    for (auto &y : G[x]) {
      if (!viz[y]) {
        viz[y] = true;
        Q.push(y);
        d[y] = d[x] + 1;
      }
    }
  }
}
void update(vector<int> v) {
  int tans = d[v[0]][v[1]] + d[v[1]][v[2]] + d[v[2]][v[3]];
  if (tans > ans) {
    ans = tans;
    sol = v;
  }
}
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int a, b;
    cin >> a >> b;
    G[a].push_back(b);
  }
  for (int i = 1; i <= n; ++i) {
    bfs(i, d[i]);
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      if (d[j][i] != 1000000000) to[i].push_back(j);
      if (d[i][j] != 1000000000) from[i].push_back(j);
    }
    current = i;
    sort(to[i].begin(), to[i].end(), cmp1);
    sort(from[i].begin(), from[i].end(), cmp2);
  }
  int ans = 0;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      if (i == j || d[i][j] == 1000000000) continue;
      int k1 = 0;
      while (k1 < to[i].size() && (to[i][k1] == i || to[i][k1] == j)) ++k1;
      if (k1 != to[i].size()) {
        int k2 = 0;
        while (k2 < from[j].size() && (from[j][k2] == i || from[j][k2] == j ||
                                       from[j][k2] == to[i][k1]))
          ++k2;
        if (k2 != from[j].size()) {
          update({to[i][k1], i, j, from[j][k2]});
        }
      }
      k1 = 0;
      while (k1 < from[j].size() && (from[j][k1] == i || from[j][k1] == j))
        ++k1;
      if (k1 != from[j].size()) {
        int k2 = 0;
        while (k2 < to[i].size() &&
               (to[i][k2] == i || to[i][k2] == j || to[i][k2] == from[j][k1]))
          ++k2;
        if (k2 != to[i].size()) {
          update({to[i][k2], i, j, from[j][k1]});
        }
      }
    }
  }
  for (auto &el : sol) {
    cout << el << " ";
  }
}
