#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
template <class T>
void na(vector<T>& a, int n) {
  a = vector<T>(n);
  for (T& i : a) cin >> i;
}
template <class T>
void printVector(vector<T>& a) {
  for (T& i : a) cout << i << ' ';
  cout << '\n';
}
template <class T>
vector<T> shrink(vector<T>& x) {
  vector<T> vals = x;
  sort((vals).begin(), (vals).end());
  (vals).resize(unique((vals).begin(), (vals).end()) - (vals).begin());
  for (T& i : x)
    i = upper_bound((vals).begin(), (vals).end(), i) - vals.begin();
  return vals;
}
const int N = 5555;
int n;
bool gmat[N][N];
vector<int> g[N];
bool found = false;
bool onstack[N], seen[N];
stack<int> stk;
vector<int> cycle;
void dfs(int u) {
  onstack[u] = 1;
  seen[u] = 1;
  stk.push(u);
  for (int v : g[u]) {
    if (found) return;
    if (onstack[v]) {
      found = true;
      int cur = u;
      cycle.push_back(cur);
      do {
        stk.pop();
        cur = stk.top();
        cycle.push_back(cur);
      } while (cur != v);
      return;
    }
    if (!seen[v]) dfs(v);
  }
  onstack[u] = false;
  stk.pop();
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0), cout.tie();
  cin >> n;
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j) {
      char c;
      cin >> c;
      if (c == '1') g[i].push_back(j), gmat[i][j] = 1;
    }
  for (int i = 1; i <= n && !found; ++i)
    if (!seen[i]) dfs(i);
  reverse((cycle).begin(), (cycle).end());
  if (!found)
    cout << "-1\n";
  else {
    int j = 1, k = 2;
    while (k < ((int)(cycle).size())) {
      if (gmat[cycle[k]][cycle[0]]) {
        cout << cycle[0] << ' ' << cycle[j] << ' ' << cycle[k] << '\n';
        break;
      }
      ++k, ++j;
    }
  }
  return 0;
}
