#include <bits/stdc++.h>   using namespace std;   const int INF = 1791791791;   const long long INFLL = 1791791791791791791ll;   template <int input_buf_size, int output_buf_size>   class FastIO {     char cbuf[input_buf_size + 1];     int icur = 0;     inline bool go_to_next_token() {       while (cbuf[icur] ==     || cbuf[icur] ==   n ) icur++;       while (cbuf[icur] == 0) {         icur = 0;         if (fgets(cbuf, sizeof(cbuf), stdin) != cbuf) return false;         while (cbuf[icur] ==     || cbuf[icur] ==   n ) icur++;       }       return true;     }       public:     string readString() {       assert(go_to_next_token());       string ans;       while (cbuf[icur] !=     && cbuf[icur] !=   n  && cbuf[icur] != 0)         ans.push_back(cbuf[icur++]);       ans.shrink_to_fit();       return ans;     }     template <class int_type>     int_type readInt() {       assert(go_to_next_token());       int_type x = 0;       bool m = cbuf[icur] ==  - ;       if (m) icur++;       while ( 0  <= cbuf[icur] && cbuf[icur] <=  9 ) {         x *= 10;         x += (cbuf[icur] -  0 );         icur++;       }       if (m) x = -x;       return x;     }     bool seekEof() { return !go_to_next_token(); }       private:     char obuf[output_buf_size + 1];     int ocur = 0;     inline void write_string(const char* str, size_t sz = 0) {       if (sz == 0) sz = strlen(str);       if (ocur + sz > output_buf_size) {         fputs(obuf, stdout);         fputs(str, stdout);         ocur = 0;         obuf[0] = 0;         return;       }       strcpy(obuf + ocur, str);       ocur += sz;       obuf[ocur] = 0;     }       public:     template <class int_type>     void writeInt(int_type x, bool sp = true) {       char buf[20];       int c = 0;       if (x < 0) {         buf[c++] =  - ;         x = -x;       }       int s = c;       if (x == 0) {         buf[c++] =  0 ;       }       while (x > 0) {         buf[c++] = (x % 10) +  0 ;         x /= 10;       }       for (int i = 0; 2 * i < c - s; i++) {         swap(buf[s + i], buf[c - 1 - i]);       }       buf[c] = 0;       write_string(buf, c);       if (sp) write_string(   , 1);     }     void writeString(string s, bool space = true) {       write_string(s.c_str(), s.size());       if (space) write_string(   , 1);     }     void writeEndl() { write_string(  n , 1); }     void flush() {       fputs(obuf, stdout);       ocur = 0;       obuf[0] = 0;     }       private:     bool lflush;       public:     FastIO(bool local_flush) {       obuf[0] = 0;       lflush = local_flush;     }     ~FastIO() { fputs(obuf, stdout); }   };   FastIO<10000000, 10000000> IO(true);   const int maxn = 3179;   vector<int> graph[maxn];   int dist[maxn][maxn];   vector<int> mdff[maxn];   vector<int> mdfs[maxn];   int main() {     int n = IO.readInt<int>();     int m = IO.readInt<int>();     for (int i = 0; i < ((int)(m)); ++i) {       int u = IO.readInt<int>() - 1;       int v = IO.readInt<int>() - 1;       graph[u].push_back(v);     }     for (int start = 0; start < ((int)(n)); ++start) {       fill(dist[start], dist[start] + n, -1);       dist[start][start] = 0;       queue<int> q;       q.push(start);       while (!q.empty()) {         int a = q.front();         q.pop();         for (int v : graph[a]) {           if (dist[start][v] == -1) {             dist[start][v] = dist[start][a] + 1;             q.push(v);           }         }       }     }     for (int i = 0; i < ((int)(n)); ++i) {       for (int j = 0; j < ((int)(n)); ++j)         if (j != i) {           mdfs[i].push_back(j);           mdff[i].push_back(j);         }       sort((mdfs[i]).begin(), (mdfs[i]).end(),            [&](const int& a, const int& b) -> bool {              return dist[i][a] > dist[i][b];            });       sort((mdff[i]).begin(), (mdff[i]).end(),            [&](const int& a, const int& b) -> bool {              return dist[a][i] > dist[b][i];            });     }     int a, b, c, d;     int ans = -1;     for (int m1 = 0; m1 < ((int)(n)); ++m1) {       for (int m2 = 0; m2 < ((int)(n)); ++m2) {         if (m1 != m2) {           for (int i = 0; i < ((int)(3)); ++i) {             for (int j = 0; j < ((int)(3)); ++j) {               int l = mdff[m1][i];               int r = mdfs[m2][j];               if (m1 == r || m2 == l || l == r) continue;               if (dist[l][m1] == -1 || dist[m1][m2] == -1 || dist[m2][r] == -1)                 continue;               if (dist[l][m1] + dist[m1][m2] + dist[m2][r] > ans) {                 ans = dist[l][m1] + dist[m1][m2] + dist[m2][r];                 a = l;                 b = m1;                 c = m2;                 d = r;               }             }           }         }       }     }     cerr << ans << endl;     IO.writeInt(a + 1);     IO.writeInt(b + 1);     IO.writeInt(c + 1);     IO.writeInt(d + 1);     IO.writeEndl();     return 0;   }