#include <cstdio>
#include <deque>

using namespace std;

char a[5000][5001];
int n;
int uses[5000];
deque<int> q;

int main()
{
        scanf("%d", &n);
        for(int i = 0;i < n;++i)
            scanf("%s", a[i]);
        for(int i = 0;i < n;++i)
            if(!uses[i])
            {
                uses[i] = 6000*i;
                q.push_back(i);
                while(!q.empty())
                {
                    int t = q[0];
                    q.pop_front();
                    for(int j = 0;j < n;++j)
                        if(a[t][j] == '1')
                        {
                            if(uses[t] == uses[j] + 2)
                            {
                                for(int k = 0;k < n;++k)
                                    if(a[j][k] == '1' && a[k][t]== '1')
                                    {
                                        printf("%d %d %d", j + 1, k + 1, t + 1);
                                        return 0;
                                    }
                            }
                            if(uses[j] == 0)
                            {
                                q.push_back(j);
                                uses[j] = uses[t] + 1;
                            }
                        }
                }
            }
    for(int i = 0;i < n;++i)
        uses[i] = 0;
    for(int i = 0;i < n;++i)
        if(!uses[i])
        {
            uses[i] = 6000*(i + 1);
            q.push_front(i);
            while(!q.empty())
            {
                int t = q[0] % 10000, j = q[0] / 10000;
                for(;j < n;++j)
                    if(a[t][j] == '1')
                    {
                        if(uses[t] == uses[j] + 2)
                            for(int k = 0;k < n;++k)
                                if(a[j][k] == '1' && a[k][t]== '1')
                                {
                                    printf("%d %d %d", j + 1, k + 1, t + 1);
                                    return 0;
                                }
                        if(uses[j] == 0)
                        {
                            q[0] = 10000*(j + 1) + t;
                            q.push_front(j);
                            uses[j] = uses[t] + 1;
                            break;
                        }
                    }
				if(j == n)
					q.pop_front();
            }
        }
    printf("-1");
    return 0;
}


#include <cstdio>
#include <deque>

using namespace std;

char a[5000][5001];
int n;
int uses[5000];
deque<int> q;

int main()
{
	//freopen("input.txt", "r", stdin);
    scanf("%d", &n);
    for(int i = 0;i < n;++i)
        scanf("%s", a[i]);
    for(int i = 0;i < n;++i)
        if(!uses[i])
        {
            uses[i] = 6000*(i + 1);
            q.push_front(i);
            while(!q.empty())
            {
                int t = q[0] % 10000, j = q[0] / 10000;
                for(;j < n;++j)
                    if(a[t][j] == '1')
                    {
                        if(uses[t] == uses[j] + 2)
                            for(int k = 0;k < n;++k)
                                if(a[j][k] == '1' && a[k][t]== '1')
                                {
                                    printf("%d %d %d", j + 1, k + 1, t + 1);
                                    return 0;
                                }
                        if(uses[j] == 0)
                        {
                            q[0] = 10000*(j + 1) + t;
                            q.push_front(j);
                            uses[j] = uses[t] + 1;
                            break;
                        }
                    }
				if(j == n)
					q.pop_front();
            }
        }
    printf("-1");
    return 0;
}


#include <stdio.h>

char a[5000][5001];
int n;

int main()
{
    freopen("input.txt", "r", stdin);
    scanf("%d", &n);
    for(int i = 0;i < n;++i)
        scanf("%s", a[i]);
    for(int i = 0;i < n;++i)
        for(int j = 0;j < n;++j)
            if(a[i][j] == '1')
                for(int k = 0;k < n;++k)
                    if(a[j][k] == '1' && a[k][i] == '1')
                    {
                        printf("%d %d %d", i + 1, j + 1, k + 1);
                        return 0;
                    }
    printf("-1");
    return 0;
}


#include <cstdio>
#include <deque>

using namespace std;

char a[5000][5001];
int n, v = 10;
int uses[5000];
deque<int> q;

int main()
{
        scanf("%d", &n);
        for(int i = 0;i < n;++i)
                scanf("%s", a[i]);
        for(int i = 0;i < n;++i)
                if(!uses[i])
                {
                        uses[i] = v;
                        q.push_back(i);
                        while(!q.empty())
                        {
                                int t = q[0];
                                q.pop_front();
                                for(int j = 0;j < n;++j)
                                        if(a[t][j] == '1')
                                        {
                                                if(uses[j] == 0)
                                                {
                                                        q.push_back(j);
                                                        uses[j] = uses[t] + 1;
                                                        v = uses[j] + 100;
                                                }
                                        }
                        }
                }
		for (int t=0;t<n;++t)
			for (int j=0;j<n;++j)
			{
				if(uses[t] == uses[j] + 2)
				{
						for(int k = 0;k < n;++k)
								if(uses[k] == uses[j] + 1 && a[j][k] == '1' && a[k][t]== '1')
								{
										printf("%d %d %d", j + 1, k + 1, t + 1);
										return 0;
								}
				}
			}
        printf("-1");
        return 0;
}


#include <cstdio>
#include <deque>

using namespace std;

char a[5000][5001];
int n;
int uses[5000];
deque<int> q;

int main()
{
	scanf("%d", &n);
	for(int i = 0;i < n;++i)
		scanf("%s", a[i]);
	for(int i = 0;i < n;++i)
		if(!uses[i])
		{
			uses[i] = 6000*i;
			q.push_back(i);
			while(!q.empty())
			{
				int t = q[0];
				q.pop_front();
				for(int j = 0;j < n;++j)
					if(a[t][j] == '1')
					{
						if(uses[t] == uses[j] + 2)
						{
							for(int k = 0;k < n;++k)
								if(a[j][k] == '1' && a[k][t]== '1')
								{
									printf("%d %d %d", j + 1, k + 1, t + 1);
									return 0;
								}
						}
						if(uses[j] == 0)
						{
							q.push_back(j);
							uses[j] = uses[t] + 1;
						}
					}
			}
		}
	printf("-1");
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
void add(int in , int d , int par){
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par){
	add(root, d , par);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root);
		}
		else if(matrix[root][i] && mark[i] && depth[root] - depth[i] == cycle_s - 1){
			int t = 0;
			ans.clear();
			for(int j = root ; j != parent[i] ; j = parent[j]){
				t++;
				if(t == cycle_s && j != i){
					ans.clear();
					break;
				}
				ans.push_back(j);
			}
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
void add(int in , int d , int par){
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par){
	if(has)
		return;
	add(root, d , par);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root);
			if(has)
				return;
		}
		else if(matrix[root][i] && mark[i]){
			if(par != -1 && matrix[i][par]){
				has = true;
				cout << i + 1<< " " << par + 1<< " " << root + 1<< endl;
				return;
			}

/*			int t = 0;
			vector<int> preans = ans;
			ans.clear();
			for(int j = root ; j != -1 ; j = parent[j]){
				t++;
				if(t == cycle_s && j != i){
					ans.clear();
					ans = preans;
					break;
				}
				ans.push_back(j);
			}*/
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1);
	if(!has)
		cout << "-1" << endl;
/*	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}*/
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
void add(int in , int d , int par){
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par){
	if(has)
		return;
	add(root, d , par);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root);
		}
		else if(matrix[root][i] && mark[i]){
			if(matrix[i][par]){
				has = true;
				cout << i + 1<< " " << par + 1<< " " << root + 1<< endl;
				return;
			}

/*			int t = 0;
			vector<int> preans = ans;
			ans.clear();
			for(int j = root ; j != -1 ; j = parent[j]){
				t++;
				if(t == cycle_s && j != i){
					ans.clear();
					ans = preans;
					break;
				}
				ans.push_back(j);
			}*/
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1);
	if(!has)
		cout << "-1" << endl;
/*	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}*/
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
vector<int> roots;
void add(int in , int d , int par , int root){
//	cerr << in << " " << d << " " << par << " " << root << endl;
//	S.push(in);
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
	roots[in] = root;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par , int mr){
	add(root, d , par , mr);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root , mr);
		}
		else if(matrix[root][i] && mark[i] && depth[root] - depth[i] == cycle_s - 1 && roots[i] == roots[root]){
//			cerr << root << " " << i << endl;
			ans.clear();
			for(int j = root ; j != parent[i] ; j = parent[j]){
				ans.push_back(j);
			}
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	roots.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1 , i);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
vector<int> roots;
void add(int in , int d , int par){
//	cerr << in << " " << d << " " << par << " " << root << endl;
//	S.push(in);
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
//	roots[in] = root;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par){
	add(root, d , par);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root);
		}
		else if(matrix[root][i] && mark[i] && depth[root] - depth[i] == cycle_s - 1){
			cerr << "@" << endl;
			ans.clear();
			for(int j = root ; j != parent[i] ; j = parent[j]){
				ans.push_back(j);
			}
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	roots.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
vector<int> roots;
void add(int in , int d , int par , int root){
//	cerr << in << " " << d << " " << par << " " << root << endl;
	S.push(in);
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
	roots[in] = root;
}
int n;
const int cycle_s = 3;
vector<int> ans;
void BFS(int root){
	add(root, 0 , -1 , root);
	while(!S.empty()){
		int x = S.front();
		S.pop();
		for(int i = 0 ; i < n ; i++)
			if(matrix[x][i] && !mark[i])
				add(i , depth[x] + 1 , x , root);
			else if(mark[i] && depth[x] - depth[i] == cycle_s - 1 && roots[x] == roots[i]){
				ans.clear();
				for(int j = x ; j != parent[i] ; j = parent[j]){
					ans.push_back(j);
				}
			}

	}
}
int main(){
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	roots.resize(n);
	matrix.resize(n , vector<bool>(n));
	for(int i = 0 ; i < n ; i++)
		for(int j = 0 ; j < n ; j++){
			char c;
			cin >> c;
			matrix[i][j] = c == '1';
		}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			BFS(i);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
void add(int in , int d , int par){
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par){
	add(root, d , par);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root);
		}
		else if(matrix[root][i] && mark[i] && depth[root] - depth[i] == cycle_s - 1){

			int t = 0;
			vector<int> preans = ans;
			ans.clear();
			for(int j = root ; j != parent[i] ; j = parent[j]){
				t++;
				if(t == cycle_s && j != i){
					ans = preans;
					ans.clear();
			//		break;
				}
				ans.push_back(j);
			}
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
void add(int in , int d , int par){
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par){
	add(root, d , par);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root);
		}
		else if(matrix[root][i] && mark[i] && depth[root] - depth[i] == cycle_s - 1){

			int t = 0;
			vector<int> preans = ans;
			ans.clear();
			for(int j = root ; j != parent[i] ; j = parent[j]){
				t++;
				if(t == cycle_s && j != i){
					ans.clear();
					ans = preans;
					break;
				}
				ans.push_back(j);
			}
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
vector<int> roots;
void add(int in , int d , int par , int root){
//	cerr << in << " " << d << " " << par << " " << root << endl;
	S.push(in);
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
	roots[in] = root;
}
int n;
const int cycle_s = 3;
vector<int> ans;
void BFS(int root){
	add(root, 0 , -1 , root);
	while(!S.empty()){
		int x = S.front();
		S.pop();
		for(int i = 0 ; i < n ; i++)
			if(matrix[x][i] && !mark[i])
				add(i , depth[x] + 1 , x , root);
			else if(mark[i] && depth[x] - depth[i] == cycle_s - 1 && roots[x] == roots[i]){
				ans.clear();
				for(int j = x ; j != parent[i] ; j = parent[j]){
					ans.push_back(j);
				}
			}

	}
}
int main(){
	cin >> n;
	mark.resize(n , false);
	ios_base::sync_with_stdio(false);
	depth.resize(n);
	parent.resize(n);
	roots.resize(n);
	matrix.resize(n , vector<bool>(n));
	for(int i = 0 ; i < n ; i++)
		for(int j = 0 ; j < n ; j++){
			char c;
			cin >> c;
			matrix[i][j] = c == '1';
		}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			BFS(i);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
void add(int in , int d , int par){
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par){
	if(has)
		return;
	add(root, d , par);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root);
		}
		else if(matrix[root][i] && mark[i]){
			if(par != -1 && matrix[i][par]){
				has = true;
				cout << i + 1<< " " << par + 1<< " " << root + 1<< endl;
				return;
			}

/*			int t = 0;
			vector<int> preans = ans;
			ans.clear();
			for(int j = root ; j != -1 ; j = parent[j]){
				t++;
				if(t == cycle_s && j != i){
					ans.clear();
					ans = preans;
					break;
				}
				ans.push_back(j);
			}*/
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1);
	if(!has)
		cout << "-1" << endl;
/*	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}*/
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
vector<int> roots;
void add(int in , int d , int par , int root){
//	cerr << in << " " << d << " " << par << " " << root << endl;
	S.push(in);
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
	roots[in] = root;
}
int n;
const int cycle_s = 3;
vector<int> ans;
void BFS(int root){
	add(root, 0 , -1 , root);
	while(!S.empty()){
		int x = S.front();
		S.pop();
		for(int i = 0 ; i < n ; i++)
			if(matrix[x][i] && !mark[i])
				add(i , depth[x] + 1 , x , root);
			else if(mark[i] && depth[x] - depth[i] == cycle_s - 1 && roots[x] == roots[i]){
				ans.clear();
				for(int j = x ; j != parent[i] ; j = parent[j]){
					ans.push_back(j);
				}
			}

	}
}
int main(){
	cin >> n;
	mark.resize(n , false);
	ios_base::sync_with_stdio(true);
	depth.resize(n);
	parent.resize(n);
	roots.resize(n);
	matrix.resize(n , vector<bool>(n));
	for(int i = 0 ; i < n ; i++)
		for(int j = 0 ; j < n ; j++){
			char c;
			cin >> c;
			matrix[i][j] = c == '1';
		}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			BFS(i);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
vector<int> roots;
void add(int in , int d , int par , int root){
//	cerr << in << " " << d << " " << par << " " << root << endl;
	S.push(in);
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
	roots[in] = root;
}
int n;
const int cycle_s = 3;
vector<int> ans;
void BFS(int root){
	add(root, 0 , -1 , root);
	while(!S.empty()){
		int x = S.front();
		S.pop();
		for(int i = 0 ; i < n ; i++)
			if(matrix[x][i] && !mark[i])
				add(i , depth[x] + 1 , x , root);
			else if(mark[i] && depth[x] - depth[i] == cycle_s - 1 && roots[x] == roots[i]){
				ans.clear();
				for(int j = x ; j != parent[i] ; j = parent[j]){
					ans.push_back(j);
				}
			}

	}
}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	roots.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			BFS(i);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<bool> > matrix;
vector<bool> mark;
queue<int> S;
vector<int> depth;
vector<int> parent;
void add(int in , int d , int par){
	mark[in] = true;
	depth[in] = d;
	parent[in] = par;
}
int n;
const int cycle_s = 3;
vector<int> ans;
bool has = false;
void DFS(int root , int d , int par){
	add(root, d , par);
	for(int i = 0 ; i < n ; i++)
		if(matrix[root][i] && !mark[i]){
			DFS(i , depth[root] + 1 , root);
		}
		else if(matrix[root][i] && mark[i] && depth[root] - depth[i] == cycle_s - 1){

			int t = 0;
			vector<int> preans = ans;
			ans.clear();
			for(int j = root ; j != parent[i] ; j = parent[j]){
				t++;
				if(t == cycle_s && j != i){
					ans.clear();
					ans = preans;
			//		break;
				}
				ans.push_back(j);
			}
		}

}
int main(){
	ios_base::sync_with_stdio(false);
	cin >> n;
	mark.resize(n , false);
	depth.resize(n);
	parent.resize(n);
	matrix.resize(n , vector<bool>(n));
	char c;
	for(int i = 0 ; i < n ; i++){
		for(int j = 0 ; j < n ; j++){
			cin >> c;
			matrix[i][j] = c == '1';
		}
	}
	for(int i = 0 ; i < n ; i++)
		if(!mark[i])
			DFS(i , 0 , -1);
	if(ans.size() == 0)
		cout << "-1" << endl;
	else{
		reverse(ans.begin() , ans.end());
		int flag = 0;
		for(int i = 0 ; i < (int)ans.size() ; i++)
			cout << (flag++?" ":"") << ans[i] + 1;
		cout << endl;
	}
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define pb push_back
using namespace std;
char mat[5005][5005];
int n,bas,orta,d[5005],fl,next;
bool dfs(const vector <int> a)
{
	//printf("%d\n",(int)a.size() );
	if(a.empty())
		return 0;
	int uz=a.size();
	vector<int> in,out;
	int x=a[uz/2];
	for (int i = 0; i < a.size(); ++i)
		if (mat[x][a[i]]=='1')
			out.pb(a[i]);
		else if(a[i]!=x)
			in.pb(a[i]);
	for (int i = 0; i < out.size(); ++i)
		for(int j=0;j<in.size();j++)
		{
			if(mat[out[i]][in[j]]=='1')
			{
				printf("%d %d %d\n",x+1,out[i]+1,in[j]+1);
				exit(0);
			}
		}
	if(dfs(in)) return 1;
	if (dfs(out))	return 1;
	return 0;

}
int main ()
{
	//freopen("oku.txt","r",stdin);

	scanf("%d\n",&n);
	for (int i = 0; i < n; ++i)
	{
		scanf(" %s",mat[i]);
	}
	vector <int> v;
	for (int i = 0; i < n; ++i)
	{
		v.pb(i);
	}
	dfs(v);
	printf("-1\n");
}


#include <cstdio>
#include <algorithm>
using namespace std;
FILE *in;
int n,mat[5005][5005],mark[5005];
char ch;
void dfs(int a,int b,int ata)
{
	//printf("=%d %d %d\n",a,b,ata);getchar();
	mark[a]=1;
	if(b==2)
	{
		for(int i=1;i<=n;i++)
			if(mark[i] && mat[a][i] && i!=ata && mat[i][ata])
			{
				printf("%d %d %d",i,ata,a);
				scanf(" ");
				exit(0);
			}
		return ;
	}
	for(int i=1;i<=n;i++)
		if(mat[a][i] & !mark[i])
			dfs(i,b+1,a);
	mark[a]=1;
}
int main ()
{
	//FILE *in=fopen("cycle.in","r");
	in=stdin;
	fscanf(in,"%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			fscanf(in," %c ",&ch);
			mat[i][j]=ch-'0';
		}
	for(int i=1;i<=n;i++)
		dfs(i,0,0);
	printf("-1");
	scanf(" ");
}


#include <cstdio>
#include <algorithm>
using namespace std;
char mat[5005][5005];
int n,bas,orta,d[5005],mark[5005],d2[5005],fl,next;
void dfs(int a,int mal)
{
	if(mark[a])
	{
		for (int i = 0; i < mal; ++i)
		{
			if(d[i]==a)
			{
				fl=1;
			}
			if(fl)
			{
				d2[next]=d[i];
				next++;
			}
		}
		bas=d2[0];
		while(next>2)
		{
			if(mat[bas][d2[next-2]])
			{
				printf("%d %d %d\n",bas+1,d2[next-2]+1,d2[next-1]+1);
				exit(0);
			}
			next--;
		}

	}
	mark[a]=1;
	d[mal]=a;
	if(a==bas && mal>0)
	{
		while(mal>=2)
		{
			if(mat[bas][d[mal-1]]=='1')
			{
				printf("%d %d %d\n",bas+1,d[mal-1]+1,d[mal]+1);
				exit(0);
			}

			mal--;
		}
		return ;
	}
	for (int i = 0; i < n; ++i)
		if(mat[a][i]=='1')
		{
			dfs(i,mal+1);
		}
}
int main ()
{
	//freopen("oku.txt","r",stdin);

	scanf("%d\n",&n);
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			scanf(" %c",&mat[i][j]);

		}
	}
	for (int i = 0; i < n; ++i)
	{
		bas=i;
		dfs(i,0);
	}
	printf("-1\n");
}


#include <cstdio>
#include <algorithm>
using namespace std;
char mat[5005][5005];
int n,bas;
void dfs(int a,int mal)
{
	//printf("%d %d\n",a,mal );
	if(mal==1)
	{
		for (int i = 0; i < n; ++i)
			if(mat[a][i]=='1' && mat[i][bas]=='1')
			{
				printf("%d %d %d\n",bas+1,a+1,i+1);
				exit(0);
			}
	}
	else
	{
		for (int i = 0; i < n; ++i)
			if(mat[a][i]=='1')
			{
				dfs(i,mal+1);
			}
	}
}
int main ()
{
	freopen("oku.txt","r",stdin);

	scanf("%d\n",&n);
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			scanf(" %c",&mat[i][j]);
		}
	}
	for (int i = 0; i < n; ++i)
	{
		bas=i;
		dfs(i,0);
	}
	printf("-1\n");
}


#include <cstdio>
#include <algorithm>
using namespace std;
char mat[5005][5005];
int n,bas,orta;
void dfs(int a,int mal)
{
	//printf("%d %d\n",a,mal);
	if(mat[a][bas]=='1'/* && mal==2*/)
	{
		printf("%d %d %d\n",bas+1,orta+1,a+1);
		exit(0);
	}
	mal--;
	for (int i = 0; i < n; ++i)
		if(mat[a][i]=='1')
		{
			orta=a;
			dfs(i,mal+1);

		}

}
int main ()
{
	//freopen("oku.txt","r",stdin);

	scanf("%d\n",&n);
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			scanf(" %c",&mat[i][j]);

		}
	}
	for (int i = 0; i < n; ++i)
	{
		bas=i;
		dfs(i,0);
	}
	printf("-1\n");
}


#include <cstdio>
#include <algorithm>
using namespace std;
FILE *in;
int n,mat[5005][5005],mark[5005];
char ch;
void dfs(int a,int b,int ata)
{
	//printf("=%d %d %d\n",a,b,ata);getchar();
	mark[a]=1;
	if(b==2)
	{
		for(int i=1;i<=n;i++)
			if(mat[a][i] && i!=ata && mat[i][ata])
			{
				printf("%d %d %d",i,ata,a);
				scanf(" ");
				exit(0);
			}
			return ;
	}
	for(int i=1;i<=n;i++)
		if(mat[a][i] & !mark[i])
			dfs(i,b+1,a);
}
int main ()
{
	//FILE *in=fopen("cycle.in","r");
	in=stdin;
	fscanf(in,"%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			fscanf(in," %c ",&ch);
			mat[i][j]=ch-'0';
		}
	for(int i=1;i<=n;i++)
		dfs(i,0,0);
	printf("-1");
	scanf(" ");
}


#include <cstdio>
#include <list>
#include <iostream>
#include <stack>
#include <algorithm>
#define pb push_back
using namespace std;
int l[2005];
int n,x,Mx,mark[5005];
char mat[5005][5005];
stack <int> st,st2;
void dfs(int a,int derin)
{
	//cout << a+1<<" " << derin << endl;
	if(mark[a])
	{
		//printf("%d",a);
		while(!st.empty())
		{
			//cout << st.top()+1 << " ";
			st2.push(st.top()+1);
			st.pop();
		}
		while(!st2.empty())
		{
			cout << st2.top() << " ";
			st2.pop();
		}
		exit(0);
	}
	if(derin>2)
		return ;
	mark[a]=1;
	st.push(a);
	for (int i = 0; i < n; ++i)
	{
		if(mat[a][i]=='1')
			dfs(i,derin+1);
	}
	mark[a]=0;
	st.pop();
	return ;
}
int main ()
{
	//freopen("oku.txt","r",stdin);
	scanf("%d",&n);
	for (int i = 0; i < n; ++i)
		for (int j = 0;j <n; ++j)
		{
			scanf(" %c",&mat[i][j]);
		}
	for (int i = 0; i < n; ++i)
	{
		dfs(i,0);
	}
	cout << "-1" << endl;

}


#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <list>
#include <iostream>
#include <stack>
#include <algorithm>
#define pb push_back
using namespace std;
char mat[5005][5005];
int n,x,y,z;
int main ()
{
	//freopen("oku.txt","r",stdin);
	srand(time(NULL));
	scanf("%d",&n);

	for (int i = 0; i < n; ++i)
		for (int j = 0;j <n; ++j)
		{
			scanf(" %c",&mat[i][j]);
		}
	for (int i = 1; i <=5000000; ++i)
	{
		x=rand()%n;
		y=rand()%n;
		z=rand()%n;
		if(mat[x][y]=='1' && mat[y][z]=='1' && mat[z][x]=='1')
		{
			printf("%d %d %d\n",x+1,y+1,z+1);
			return 0;
		}
	}
	cout << "-1" << endl;

}


#include <cstdio>
#include <list>
#include <iostream>
#include <stack>
#include <algorithm>
#define pb push_back
using namespace std;
list <int> l[2005];
int n,x,Mx,mark[5005];
char mat[5005][5005],ch;
stack <int> st,st2;
void dfs(int a,int derin)
{
	//cout << a+1<<" " << derin << endl;
	if(mark[a])
	{
		while(!st.empty())
		{
			st2.push(st.top());
			st.pop();
		}
		while(!st2.empty())
		{
			cout << st2.top() << " ";
			st2.pop();
		}
		exit(0);
	}
	if(derin>2)
		return ;
	mark[a]=1;
	st.push(a);
	for(list<int>::iterator it=l[a].begin();it!=l[a].end();it++)
	{
		dfs((*it),derin+1);
	}
	mark[a]=0;
	st.pop();
	return ;
}
int main ()
{
	//freopen("oku.txt","r",stdin);
	scanf("%d",&n);
	for (int i = 0; i < n; ++i)
		for (int j = 0;j <n; ++j)
		{
			scanf(" %c",&ch);
			if(ch=='1')
				l[i+1].pb(j+1);
		}
	for (int i = 1; i <=n; ++i)
	{
		dfs(i,0);
	}
	cout << "-1" << endl;

}


#include <cstdio>
#include <algorithm>
using namespace std;
char mat[5005][5005];
int n,bas;
void dfs(int a,int mal)
{
	//printf("%d %d\n",a,mal );
	if(mal==1)
	{
		for (int i = 0; i < n; ++i)
			if(mat[a][i]=='1' && mat[i][bas]=='1')
			{
				printf("%d %d %d\n",bas+1,a+1,i+1);
				exit(0);
			}
	}
	else
	{
		for (int i = 0; i < n; ++i)
			if(mat[a][i]=='1')
			{
				dfs(i,mal+1);
			}
	}
}
int main ()
{
	//freopen("oku.txt","r",stdin);

	scanf("%d\n",&n);
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			scanf(" %c",&mat[i][j]);
		}
	}
	for (int i = 0; i < n; ++i)
	{
		bas=i;
		dfs(i,0);
	}
	printf("-1\n");
}


#include <cstdio>
#include <algorithm>
using namespace std;
FILE *in;
int n,mat[5005][5005],mark2[5005][5005],mark[5005];
char ch;
void dfs(int a,int b,int ata)
{
	//printf("=%d %d %d\n",a,b,ata);getchar();
	mark[a]=1;
	mark2[ata][a]=1;
	if(b==2)
	{
		for(int i=1;i<=n;i++)
			if(mark[i] && mat[a][i] && i!=ata && mat[i][ata])
			{
				printf("%d %d %d",i,ata,a);
				scanf(" ");
				exit(0);
			}
		return ;
	}
	for(int i=1;i<=n;i++)
		if(mat[a][i] && !mark[i] && !mark2[a][i])
			dfs(i,b+1,a);
	mark[a]=1;
}
int main ()
{
	//FILE *in=fopen("cycle.in","r");
	in=stdin;
	fscanf(in,"%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			fscanf(in," %c ",&ch);
			mat[i][j]=ch-'0';
		}
	for(int i=1;i<=n;i++)
		dfs(i,0,0);
	printf("-1");
	scanf(" ");
}


#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <list>
#include <iostream>
#include <stack>
#include <algorithm>
#define pb push_back
using namespace std;
char mat[5005][5005];
int n,x,y,z;
int main ()
{
	freopen("oku.txt","r",stdin);
	srand(time(NULL));
	scanf("%d",&n);

	for (int i = 0; i < n; ++i)
		for (int j = 0;j <n; ++j)
		{
			scanf(" %c",&mat[i][j]);
		}
	for (int i = 1; i <=5000000; ++i)
	{
		x=rand()%n;
		y=rand()%n;
		z=rand()%n;
		if(mat[x][y]=='1' && mat[y][z]=='1' && mat[z][x]=='1')
		{
			printf("%d %d %d\n",x+1,y+1,z+1);
			return 0;
		}
	}
	cout << "-1" << endl;

}


#include <cstdio>
#include <algorithm>
using namespace std;
char mat[5005][5005];
int n,bas,orta,d[5005];
void dfs(int a,int mal)
{
	d[mal]=a;
	if(a==bas && mal>0)
	{
		while(mal>=2)
		{
			if(mat[bas][d[mal-1]]=='1')
			{
				printf("%d %d %d\n",bas+1,d[mal-1]+1,d[mal]+1);
				exit(0);
			}

			mal--;
		}
		return ;
	}
	for (int i = 0; i < n; ++i)
		if(mat[a][i]=='1')
		{
			dfs(i,mal+1);

		}

}
int main ()
{
	//freopen("oku.txt","r",stdin);

	scanf("%d\n",&n);
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			scanf(" %c",&mat[i][j]);

		}
	}
	for (int i = 0; i < n; ++i)
	{
		bas=i;
		dfs(i,0);
	}
	printf("-1\n");
}


#include <cstdio>
#include <algorithm>
using namespace std;
FILE *in;
int n,mat[5005][5005],mark[5005];
char ch;
void dfs(int a,int b,int ata)
{
    //printf("=%d %d %d\n",a,b,ata);getchar();
    mark[a]=1;
    if(b==2)
    {
        for(int i=1;i<=n;i++)
            if(mat[a][i] && i!=ata && mat[i][ata])
            {
                printf("%d %d %d",i,ata,a);
                scanf(" ");
                exit(0);
            }
            return ;
    }
    for(int i=1;i<=n;i++)
        if(mat[a][i] & !mark[i])
            dfs(i,b+1,a);
    mark[a]=0;
}
int main ()
{
    //FILE *in=fopen("cycle.in","r");
    in=stdin;
    fscanf(in,"%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            fscanf(in," %c ",&ch);
            mat[i][j]=ch-'0';
        }
    for(int i=1;i<=n;i++)
        dfs(i,0,0);
    printf("-1");
    scanf(" ");
}


#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

ifstream fin("input.txt");

char G[5001][5001];
int i,j,N;
int A[5001][5001],v[5001];
vector<int> S;

bool DFS(int node) {
	if(v[node]==1) return true;
	v[node]=1;
	S.push_back(node);

	for(int i=1;i<=A[node][0];i++) {
		if(v[A[node][i]]==2) continue;

		if(DFS(A[node][i])) return true;
	}
	v[node]=2;
	S.pop_back();
	return false;
}

int main() {
	cin >> N;
	for(i=1;i<=N;i++) {
		for(j=1;j<=N;j++)
			cin >> G[i][j];

	}
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	for(i=1;i<=N;i++)
		if(v[i]==0)
			if(DFS(i)) {
				int a,b;
				a=S[0]; b=S[S.size()-1];
				for(j=(int)S.size()-2; j; j--)
					if(G[a][S[j]]=='1' && G[S[j]][b]=='1' && G[b][a]=='1') break;
				cout << a << ' ' << S[j] << ' ' << b;
				return 0;
			}
	cout << -1;
}


#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

//ifstream fin("input.txt");

char G[5001][5001];
int i,j,N;
int A[5001][5001],v[5001];
vector<int> S;

bool DFS(int node) {
	v[node]=1;
	S.push_back(node);

	for(int i=1;i<=A[node][0];i++) {
		if(v[A[node][i]]==2) continue;
		if(v[A[node][i]]==1) return true;
		if(DFS(A[node][i])) return true;
	}
	v[node]=2;
	S.pop_back();
	return false;
}
ofstream fout("out.txt");

int main() {
	cin >> N;
	for(i=1;i<=N;i++)
			cin >> G[i]+1;
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	for(i=1;i<=N;i++)
		if(v[i]==0)
			if(DFS(i)) {
				int a,b;
				a=S[0]; b=S[S.size()-1];
				for(j=(int)S.size()-2; j; j--)
					if(G[a][S[j]]=='1' && G[S[j]][b]=='1' && G[b][a]=='1') break;
				cout << a << ' ' << S[j] << ' ' << b;
				return 0;
			}
	cout << -1;
}


#include <iostream>
#include <fstream>
#include <stack>
using namespace std;

//ifstream fin("input.txt");

char G[5001][5001];
int i,j,N;
int A[5001][5001],v[5001];
stack<int> S;

bool DFS(int node) {
	if(v[node]==1) return true;
	v[node]=1;
	S.push(node);

	for(int i=1;i<=A[node][0];i++) {
		if(v[A[node][i]]==2) continue;

		if(DFS(A[node][i])) return true;
	}
	v[node]=2;
	S.pop();
	return false;
}

int main() {
	cin >> N;
	for(i=1;i<=N;i++) {
		for(j=1;j<=N;j++)
			cin >> G[i][j];

	}
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	for(i=1;i<=N;i++)
		if(v[i]==0)
			if(DFS(i)) {
				int a,b,c;
				c=S.top(); S.pop();
				b=S.top(); S.pop();
				a=S.top();
				cout << a << ' ' << b << ' ' << c;
				return 0;
			}
	cout << -1;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

ifstream fin("input.txt");

char G[5001][5001];
int i,j,N,S,OK;
int A[5001][5001];
int C[5];

void DFS(int node, int len) {

	for(int v=1;v<=A[node][0] && !OK;v++) {
		if(A[node][v]==S && len==2) OK=1;
		else if(len<2) DFS(A[node][v],len+1);
	}
	if(OK) C[++C[0]]=node;
}

int main() {
	fin >> N;
	fin.get();
	for(i=1;i<=N;i++) {
		for(j=1;j<=N;j++)
			fin.get(G[i][j]);

		fin.get();
	}
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	OK=0;
	for(i=1;i<=N && !OK;i++) {
		S=i;
		DFS(i,0);
	}
	if(!OK) cout << -1;
	else cout << C[3] << ' ' << C[2] << ' ' << C[1];
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

//ifstream fin("input.txt");

char G[5001][5001];
int i,j,N,S,OK;
int A[5001][5001];
int C[5];

void DFS(int node, int len) {

	for(int v=1;v<=A[node][0] && !OK;v++) {
		if(A[node][v]==S && len==2) OK=1;
		else if(len<2) DFS(A[node][v],len+1);
	}
	if(OK) C[++C[0]]=node;
}

int main() {
	cin >> N;
	//cin.get();
	for(i=1;i<=N;i++) {
		for(j=1;j<=N;j++)
			cin >> G[i][j];

		//cin.get();
	}
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	OK=0;
	for(i=1;i<=N && !OK;i++) {
		S=i;
		DFS(i,0);
	}
	if(!OK) cout << -1;
	else cout << C[3] << ' ' << C[2] << ' ' << C[1];
}


#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

//ifstream fin("input.txt");

char G[5001][5001];
int i,j,N,st;
int A[5001][5001],v[5001];
vector<int> S;

bool DFS(int node) {
	v[node]=1;
	S.push_back(node);

	for(int i=1;i<=A[node][0];i++) {
		if(v[A[node][i]]==2) continue;
		if(v[A[node][i]]==1) { st=A[node][i]; return true; }
		if(DFS(A[node][i])) return true;
	}
	v[node]=2;
	S.pop_back();
	return false;
}

int main() {
	cin >> N;
	for(i=1;i<=N;i++)
			cin >> G[i]+1;
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	for(i=1;i<=N;i++)
		if(v[i]==0)
			if(DFS(i)) {
				int a,b;
				a=st; b=S[S.size()-1];
				for(j=(int)S.size()-2; j; j--)
					if(G[a][S[j]]=='1' && G[S[j]][b]=='1' && G[b][a]=='1') break;
				cout << a << ' ' << S[j] << ' ' << b;
				return 0;
			}
	cout << -1;
}


#include <iostream>
#include <fstream>
using namespace std;

//ifstream fin("input.txt");

char G[5001][5001];
int i,j,N,st;
int A[5001][5001],v[5001],S[5001];

bool DFS(int node) {
	v[node]=1;
	S[++S[0]]=node;

	for(int i=1;i<=A[node][0];i++) {
		if(v[A[node][i]]==2) continue;
		if(v[A[node][i]]==1) { st=A[node][i]; return true; }
		if(DFS(A[node][i])) return true;
	}
	v[node]=2;
	S[0]--;
	return false;
}

int main() {
	cin >> N;
	for(i=1;i<=N;i++)
			cin >> G[i]+1;
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	for(i=1;i<=N;i++)
		if(v[i]==0)
			if(DFS(i)) {
				int a,b;
				a=st; b=S[S[0]];
				for(j=S[0]-1; j; j--)
					if(G[a][S[j]]=='1' && G[S[j]][b]=='1' && G[b][a]=='1') break;
				cout << a << ' ' << S[j] << ' ' << b;
				return 0;
			}
	cout << -1;
}


#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

//ifstream fin("input.txt");

char G[5001][5001];
int i,j,N,st;
int A[5001][5001],v[5001];
vector<int> S;

bool DFS(int node) {
	v[node]=1;
	S.push_back(node);

	for(int i=1;i<=A[node][0];i++) {
		if(v[A[node][i]]==2) continue;
		if(v[A[node][i]]==1) { st=A[node][i]; return true; }
		if(DFS(A[node][i])) return true;
	}
	v[node]=2;
	S.pop_back();
	return false;
}
ofstream fout("out.txt");

int main() {
	cin >> N;
	for(i=1;i<=N;i++)
			cin >> G[i]+1;
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	for(i=1;i<=N;i++)
		if(v[i]==0)
			if(DFS(i)) {
				int a,b;
				a=S[st]; b=S[S.size()-1];
				for(j=(int)S.size()-2; j>st; j--)
					if(G[a][S[j]]=='1' && G[S[j]][b]=='1' && G[b][a]=='1') break;
				cout << a << ' ' << S[j] << ' ' << b;
				return 0;
			}
	cout << -1;
}


#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

//ifstream fin("input.txt");

char G[5001][5001];
int i,j,N;
int A[5001][5001],v[5001];
vector<int> S;

bool DFS(int node) {
	if(v[node]==1) return true;
	v[node]=1;
	S.push_back(node);

	for(int i=1;i<=A[node][0];i++) {
		if(v[A[node][i]]==2) continue;

		if(DFS(A[node][i])) return true;
	}
	v[node]=2;
	S.pop_back();
	return false;
}

int main() {
	cin >> N;
	for(i=1;i<=N;i++) {
		for(j=1;j<=N;j++)
			cin >> G[i][j];

	}
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	for(i=1;i<=N;i++)
		if(v[i]==0)
			if(DFS(i)) {
				while(S.size()>3)
					S.erase(S.end()-2);
				cout << S[0] << ' ' << S[1] << ' ' << S[2];
				return 0;
			}
	cout << -1;
}


#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

ifstream fin("input.txt");

char G[5001][5001];
int i,j,N;
int A[5001][5001],v[5001];
vector<int> S;

bool DFS(int node) {
	if(v[node]==1) return true;
	v[node]=1;
	S.push_back(node);

	for(int i=1;i<=A[node][0];i++) {
		if(v[A[node][i]]==2) continue;

		if(DFS(A[node][i])) return true;
	}
	v[node]=2;
	S.pop_back();
	return false;
}

int main() {
	fin >> N;
	for(i=1;i<=N;i++) {
		for(j=1;j<=N;j++)
			fin >> G[i][j];

	}
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	for(i=1;i<=N;i++)
		if(v[i]==0)
			if(DFS(i)) {
				while(S.size()>3)
					S.erase(S.end()-2);
				cout << S[0] << ' ' << S[1] << ' ' << S[2];
				return 0;
			}
	cout << -1;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

//ifstream fin("input.txt");

char G[5001][5001];
int i,j,N,S,OK;
int A[5001][5001];
int C[5];

void DFS(int node, int len) {

	for(int v=1;v<=A[node][0] && !OK;v++) {
		if(A[node][v]==S && len==2) OK=1;
		else if(len<2) DFS(A[node][v],len+1);
	}
	if(OK) C[++C[0]]=node;
}

int main() {
	cin >> N;
	//cin.get();
	for(i=1;i<=N;i++) {
		for(j=1;j<=N;j++)
			cin.get(G[i][j]);

		//cin.get();
	}
	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++)
			if(G[i][j]=='1') A[i][++A[i][0]]=j;

	OK=0;
	for(i=1;i<=N && !OK;i++) {
		S=i;
		DFS(i,0);
	}
	if(!OK) cout << -1;
	else cout << C[3] << ' ' << C[2] << ' ' << C[1];
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>

using namespace std;

vector<int> G[5001];
bool d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s){
    used[s]=true;
    pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=1;i<=n;i++){
        int to=i;
        if(to==s||!d[s][i])continue;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            a[0]=to;
            a[1]=nxt[a[0]];
            a[2]=nxt[a[1]];
            if(a[2]==s){
                for(int i=0;i<3;i++)res.push_back(a[i]);
                fin=true;
                return;
            }
            continue;
        }
        if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to);
        if(fin)return;
    }
}

int main(){
    char ch;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
            d[i+1][j+1]=ch-'0';
            if(ch=='1')
                G[i+1].push_back(j+1);
        }
    }
    for(int i=1;i<=n;i++){
        memset(used,0,sizeof(used));
        if(pastUsed[i])continue;
        dfs(i);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//
vector<int> G[5001];
//bool d[5001][5001];
//string d[5001];
char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
//  for(int i=0;i<n;i++){
//      int to=i;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[to][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    for(int i=0;i<n;i++)nxt[i]=-1;
    //scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;

            //gets(d[i]);
            //      for(int j=0;j<n;j++){
            //          cin>>ch;
            //          d[i+1][j+1]=ch-'0';
            d[i][j]=ch;
            if(ch=='1')
                G[i].push_back(j);
        }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;

vector<int> G[5001];
string d[5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[to][par]=='1'&&nxt[to]==par){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    for(int i=0;i<n;i++)nxt[i]=-10;
    for(int i=0;i<n;i++){
        cin>>d[i];
        for(int j=0;j<n;j++){
            ch=d[i][j];
            if(ch=='1')
                G[i].push_back(j);
        }
    }
    for(int i=0;i<n;i++){
        if(pastUsed[i])continue;
        memset(used,0,sizeof(used));
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;

vector<int> G[5001];
//bool d[5001][5001];
string d[5001];
//char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=0;i<n;i++){
        int to=i;
        if(to==s||d[s][i]=='0')continue;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[i][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    //scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        cin>>d[i];
        //gets(d[i]);
//      for(int j=0;j<n;j++){
//          cin>>ch;
//          d[i+1][j+1]=ch-'0';
//          if(ch=='1')
//              G[i+1].push_back(j+1);
//      }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;

vector<int> G[5001];
string d[5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[to][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    for(int i=0;i<n;i++)nxt[i]=-10;
    for(int i=0;i<n;i++){
        cin>>d[i];
        for(int j=0;j<n;j++){
            ch=d[i][j];
            if(ch=='1')G[i].push_back(j);
        }
    }
    for(int i=0;i<n;i++){
        if(pastUsed[i])continue;
        memset(used,0,sizeof(used));
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//
//ifstream ifs("input.txt");
//#define cin ifs

vector<int> G[5001];
//bool d[5001][5001];
//string d[5001];
char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=0;i<n;i++){
        int to=i;
        if(to==s||d[s][i]=='0')continue;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[i][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    char ch;
    //cin>>n;
    scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        //cin>>d[i];
        gets(d[i]);
//      for(int j=0;j<n;j++){
//          cin>>ch;
//          d[i+1][j+1]=ch-'0';
//          if(ch=='1')
//              G[i+1].push_back(j+1);
//      }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>

using namespace std;

vector<int> G[5001];
bool d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=1;i<=n;i++){
        int to=i;
        if(to==s||!d[s][i])continue;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            a[0]=to;
            a[1]=nxt[a[0]];
            a[2]=nxt[a[1]];
            if(a[2]==s){
                for(int i=0;i<3;i++)res.push_back(a[i]);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to);
        if(fin)return;
    }
}

int main(){
    char ch;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
            d[i+1][j+1]=ch-'0';
            if(ch=='1')
                G[i+1].push_back(j+1);
        }
    }
    for(int i=1;i<=n;i++){
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>

using namespace std;

ifstream ifs("input.txt");
#define cin ifs

vector<int> G[5001];
bool used[5001];
bool pastUsed[5001];
int dr[5001];
int nxt[5001];
bool fin;
vector<int> res;

void dfs(int s){
    used[s]=true;
    pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            int a=to;
            int b=nxt[a];
            int c=nxt[b];
            if(c==s){
                res.push_back(a);
                res.push_back(b);
                res.push_back(c);
                fin=true;
                return;
            }
            continue;
        }
        if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to);
        if(fin)return;
    }
}

int main(){
    int n;
    char ch;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
            if(ch=='1'){
                G[i+1].push_back(j+1);
            }
        }
    }
    for(int i=1;i<=n;i++){
        memset(used,0,sizeof(used));
        if(pastUsed[i])continue;
        dfs(i);
    }
    if(fin)
        cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//

vector<int> G[5001];
//bool d[5001][5001];
//string d[5001];
char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
//  for(int i=0;i<n;i++){
//      int to=i;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&nxt[to]==par){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    //scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
        //gets(d[i]);
//      for(int j=0;j<n;j++){
//          cin>>ch;
//          d[i+1][j+1]=ch-'0';
        if(ch=='1')
            G[i].push_back(j);
        }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//

vector<int> G[5001];
//bool d[5001][5001];
//string d[5001];
char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=0;i<n;i++){
        int to=i;
        if(to==s||d[s][i]=='0')continue;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[i][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    //scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++)
            cin>>d[i][j];
        //gets(d[i]);
//      for(int j=0;j<n;j++){
//          cin>>ch;
//          d[i+1][j+1]=ch-'0';
//          if(ch=='1')
//              G[i+1].push_back(j+1);
//      }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//
ifstream ifs("input.txt");
#define cin ifs

vector<int> G[5001];
//bool d[5001][5001];
string d[5001];
//char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=0;i<n;i++){
        int to=i;
        if(to==s||d[s][i]=='0')continue;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[i][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    //scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        cin>>d[i];
        //gets(d[i]);
//      for(int j=0;j<n;j++){
//          cin>>ch;
//          d[i+1][j+1]=ch-'0';
//          if(ch=='1')
//              G[i+1].push_back(j+1);
//      }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//

vector<int> G[5001];
//bool d[5001][5001];
//string d[5001];
char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
//  for(int i=0;i<n;i++){
//      int to=i;
        if(to==s||d[s][i]=='0')continue;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[i][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    //scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>d[i][j];
        //gets(d[i]);
//      for(int j=0;j<n;j++){
//          cin>>ch;
//          d[i+1][j+1]=ch-'0';
        if(ch=='1')
            G[i].push_back(j);
        }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>

using namespace std;

vector<int> G[5001];
bool d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=1;i<=n;i++){
        int to=i;
        if(to==s||!d[s][i])continue;
        // 以前に通過
        if(used[to]){
            if(par!=-1&&d[to][par]){
                // ループになっているかチェック
                a[0]=to;
                a[1]=nxt[a[0]];
                a[2]=nxt[a[1]];
                for(int i=0;i<3;i++)res.push_back(a[i]);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    char ch;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
            d[i+1][j+1]=ch-'0';
            if(ch=='1')
                G[i+1].push_back(j+1);
        }
    }
    for(int i=1;i<=n;i++){
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//
ifstream ifs("input.txt");
#define cin ifs

vector<int> G[5001];
//bool d[5001][5001];
//string d[5001];
char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
	used[s]=true;
	//pastUsed[s]=true;
	for(int i=0;i<(int)G[s].size();i++){
		int to=G[s][i];
//	for(int i=0;i<n;i++){
//		int to=i;
		// 以前に通過
		if(used[to]){
			// ループになっているかチェック
			if(par!=-1&&d[to][par]=='1'){
				a[0]=to;
				a[1]=par;
				a[2]=s;
				for(int j=0;j<3;j++)res.push_back(a[j]+1);
				fin=true;
				return;
			}
			continue;
		}
		//if(pastUsed[to])continue;
		nxt[s]=to;
		dfs(to,s);
		if(fin)return;
	}
}

int main(){
	std::ios_base::sync_with_stdio(0);
	char ch;
	cin>>n;
	for(int i=0;i<n;i++)nxt[i]=-1;
	//scanf("%d\n",&n);
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			cin>>ch;

			//gets(d[i]);
			//		for(int j=0;j<n;j++){
			//			cin>>ch;
			//			d[i+1][j+1]=ch-'0';
			d[i][j]=ch;
			if(ch=='1')
				G[i].push_back(j);
		}
	}
	for(int i=0;i<n;i++){
		if(used[i])continue;
//		memset(used,0,sizeof(used));
//		if(pastUsed[i])continue;
		dfs(i,-1);
	}
	if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
	else cout<<-1<<endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>

using namespace std;

vector<int> G[5001];
//bool d[5001][5001];
string d[5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=0;i<n;i++){
        int to=i;
        if(to==s||d[s][i]=='0')continue;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[i][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    char ch;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>d[i];
//      for(int j=0;j<n;j++){
//          cin>>ch;
//          d[i+1][j+1]=ch-'0';
//          if(ch=='1')
//              G[i+1].push_back(j+1);
//      }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//

vector<int> G[5001];
//bool d[5001][5001];
//string d[5001];
char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
//  for(int i=0;i<n;i++){
//      int to=i;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&nxt[to]==par){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    for(int i=0;i<n;i++)nxt[i]=-1;
    //scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
        //gets(d[i]);
//      for(int j=0;j<n;j++){
//          cin>>ch;
//          d[i+1][j+1]=ch-'0';
        if(ch=='1')
            G[i].push_back(j);
        }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>

using namespace std;

ifstream ifs("input.txt");
#define cin ifs

vector<int> G[5001];
bool d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=1;i<=n;i++){
        int to=i;
        if(to==s||!d[s][i])continue;
        // 以前に通過
        if(used[to]){
            if(par!=-1&&d[to][par]){
                // ループになっているかチェック
                a[0]=to;
                a[1]=nxt[a[0]];
                a[2]=nxt[a[1]];
                for(int i=0;i<3;i++)res.push_back(a[i]);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    char ch;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
            d[i+1][j+1]=ch-'0';
            if(ch=='1')
                G[i+1].push_back(j+1);
        }
    }
    for(int i=1;i<=n;i++){
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;

vector<int> G[5001];
string d[5001];
bool used[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[to][par]=='1'&&nxt[to]==par){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    for(int i=0;i<n;i++)nxt[i]=-10;
    for(int i=0;i<n;i++){
        cin>>d[i];
        for(int j=0;j<n;j++){
            ch=d[i][j];
            if(ch=='1')
                G[i].push_back(j);
        }
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>

using namespace std;

vector<int> G[5001];
bool d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
//  for(int i=0;i<(int)G[s].size();i++){
//      int to=G[s][i];
    for(int i=1;i<=n;i++){
        int to=i;
        if(to==s||!d[s][i])continue;
        // 以前に通過
        if(used[to]){
            if(par!=-1&&d[to][par]){
                // ループになっているかチェック
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    char ch;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
            d[i+1][j+1]=ch-'0';
            if(ch=='1')
                G[i+1].push_back(j+1);
        }
    }
    for(int i=1;i<=n;i++){
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>

using namespace std;

vector<int> G[5001];
bool used[5001];
bool pastUsed[5001];
int dr[5001];
int nxt[5001];
bool fin;
vector<int> res;

void dfs(int s){
    used[s]=true;
    pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            int a=to;
            int b=nxt[a];
            int c=nxt[b];
            if(c==s){
                res.push_back(a);
                res.push_back(b);
                res.push_back(c);
                fin=true;
                return;
            }
            continue;
        }
        if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to);
        if(fin)return;
    }
}

int main(){
    int n;
    char ch;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>ch;
            if(ch=='1'){
                G[i+1].push_back(j+1);
            }
        }
    }
    for(int i=1;i<=n;i++){
        memset(used,0,sizeof(used));
        if(pastUsed[i])continue;
        dfs(i);
    }
    if(fin)
        cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
//

vector<int> G[5001];
//bool d[5001][5001];
string d[5001];
//char d[5001][5001];
bool used[5001];
bool pastUsed[5001];
int nxt[5001];
bool fin;
vector<int> res;
int a[3];
int n;

void dfs(int s,int par){
    used[s]=true;
    //pastUsed[s]=true;
    for(int i=0;i<(int)G[s].size();i++){
        int to=G[s][i];
//  for(int i=0;i<n;i++){
//      int to=i;
        // 以前に通過
        if(used[to]){
            // ループになっているかチェック
            if(par!=-1&&d[to][par]=='1'){
                a[0]=to;
                a[1]=par;
                a[2]=s;
                for(int j=0;j<3;j++)res.push_back(a[j]+1);
                fin=true;
                return;
            }
            continue;
        }
        //if(pastUsed[to])continue;
        nxt[s]=to;
        dfs(to,s);
        if(fin)return;
    }
}

int main(){
    std::ios_base::sync_with_stdio(0);
    char ch;
    cin>>n;
    for(int i=0;i<n;i++)nxt[i]=-1;
    //scanf("%d\n",&n);
    for(int i=0;i<n;i++){
        cin>>d[i];
        //for(int j=0;j<n;j++){
            //cin>>ch;

            //gets(d[i]);
            //      for(int j=0;j<n;j++){
            //          cin>>ch;
            //          d[i+1][j+1]=ch-'0';
            //d[i][j]=ch;
        for(int j=0;j<n;j++){
            ch=d[i][j];
            if(ch=='1')
                G[i].push_back(j);
        }
        //}
    }
    for(int i=0;i<n;i++){
        if(used[i])continue;
//      memset(used,0,sizeof(used));
//      if(pastUsed[i])continue;
        dfs(i,-1);
    }
    if(fin)cout<<res[0]<<" "<<res[1]<<" "<<res[2]<<endl;
    else cout<<-1<<endl;
    return 0;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}

struct vim{

    int l;
    int ans[5005];
    vi(){
        l=0;
    }
    int size(){
        return l;
    }
    bool empty(){
        return l==0;
    }

    void pop_back(){
        --l;
    }
    void push_back(int k){
        ans[l++]=k;
    }

    int operator[] (int k){
        return ans[k];
    }

    int* begin(){
        return ans;
    }

    int* end(){
        return ans+l;
    }

};
vi g[5555];
int used[5555];
vi ans;

int dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < (int) g[v].size(); ++i) {
        if (used[g[v][i]] == 0) {
            int p = dfs(g[v][i]);
            if (p != -1) {
                if ((p == -2) || (p == v)) {
                    return -2;
                }
                ans.pb(v);
                return p;
            }
        } else if (used[g[v][i]] == 1) {
            ans.pb(g[v][i]);
            ans.pb(v);
            return g[v][i];
        }

    }
    used[v] = 2;
    return -1;
}
char s[5555][5555];

void solve() {

    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> s[i][j];
            if (s[i][j] == '1')
                g[i].pb(j);
        }
    }
    for (int i = 0; i < n && ans.empty(); ++i) {
        if (!used[i])
            dfs(i);
    }
    if (ans.empty()) {
        cout << "-1";
        return;
    }
    reverse(ans.begin(), ans.end());
    //cout<<endl;
    //for(int i=0;i<ans.size();++i)
    //  cout<<ans[i]<<' ';
    //cout<<endl;
    while (ans.size() > 3) {
        if (s[ans[0]][ans[ans.size() - 2]] == '1') {
            cout << ans[0] + 1 << ' ' << ans[ans.size() - 2] + 1 << ' ' << ans[ans.size()-1] + 1;
            return;
        }
        ans.pop_back();
    }

    cout << ans[0] + 1 << ' ' << ans[1] + 1 << ' ' << ans[2] + 1;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}
vi g[5555];
int used[5555];
vi ans;
bool  dfs(int v){
    used[v]=1;
    for(int i=0;i<(int)g[v].size();++i){
        if(used[g[v][i]]==0){
            int p=dfs(g[v][i]);
            if(p!=-1){
                if((p==-2) || (p==v)){
                    return -2;
                }
                ans.pb(v);
                //cout<<v<<' '<<p<<endl;
                return p;
            }
        }
        else if(used[g[v][i]]==1){
            ans.pb(g[v][i]);
            ans.pb(v);
            //cout<<v<<' '<<g[v][i]<<endl;
            return g[v][i];
        }

    }
    used[v]=2;
    return -1;
}
char s[5555][5555];
void solve() {
    int n;
    cin>>n;
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            cin>>s[i][j];
            if(s[i][j]=='1')
                g[i].pb(j);
        }
    }
    for(int i=0;i<n && ans.empty();++i){
        if(!used[i])
            dfs(i);
    }
    if(ans.empty()){
        cout<<"-1";
        return;
    }
    reverse(ans.begin(),ans.end());
    //cout<<endl;
    //for(int i=0;i<ans.size();++i)
    //  cout<<ans[i]<<' ';
    //cout<<endl;
    while(ans.size()>3){
        if(s[ans[0]][ans[ans.size()-2]]=='1'){
            cout<<ans[0]+1<<' '<< ans[ans.size()-2]+1<<' '<<ans.back()+1;
            return;
        }
        ans.pop_back();
    }

    cout<<ans[0]+1<<' '<<ans[1]+1<<' '<<ans[2]+1;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}

struct vim{

    int l;
    int ans[5005];
    vim(){
        l=0;
    }
    int size(){
        return l;
    }
    bool empty(){
        return l==0;
    }

    void pop_back(){
        --l;
    }
    void push_back(int k){
        ans[l++]=k;
    }

    int operator[] (int k){
        return ans[k];
    }

    int* begin(){
        return ans;
    }

    int* end(){
        return ans+l;
    }

};
vi g[5555];
int used[5555];
vi ans;

int dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < (int) g[v].size(); ++i) {
        if (used[g[v][i]] == 0) {
            int p = dfs(g[v][i]);
            if (p != -1) {
                if ((p == -2) || (p == v)) {
                    return -2;
                }
                ans.pb(v);
                return p;
            }
        } else if (used[g[v][i]] == 1) {
            ans.pb(g[v][i]);
            ans.pb(v);
            return g[v][i];
        }

    }
    used[v] = 2;
    return -1;
}
char s[5555][5555];

void solve() {

    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            scanf(" %c",&s[i][j]);
            if (s[i][j] == '1')
                g[i].pb(j);
        }
    }
    for (int i = 0; i < n && ans.empty(); ++i) {
        if (!used[i])
            dfs(i);
    }
    if (ans.empty()) {
        cout << "-1";
        return;
    }
    reverse(ans.begin(), ans.end());
    //cout<<endl;
    //for(int i=0;i<ans.size();++i)
    //  cout<<ans[i]<<' ';
    //cout<<endl;
    while (ans.size() > 3) {
        if (s[ans[0]][ans[ans.size() - 2]] == '1') {
            cout << ans[0] + 1 << ' ' << ans[ans.size() - 2] + 1 << ' ' << ans[ans.size()-1] + 1;
            return;
        }
        ans.pop_back();
    }

    cout << ans[0] + 1 << ' ' << ans[1] + 1 << ' ' << ans[2] + 1;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}

struct vim{

    int l;
    int ans[5005];
    vim(){
        l=0;
    }
    int size(){
        return l;
    }
    bool empty(){
        return l==0;
    }

    void pop_back(){
        --l;
    }
    void push_back(int k){
        ans[l++]=k;
    }

    int operator[] (int k){
        return ans[k];
    }

    int* begin(){
        return ans;
    }

    int* end(){
        return ans+l;
    }

};
vi g[5555];
int used[5555];
vi ans;

int dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < (int) g[v].size(); ++i) {
        if (used[g[v][i]] == 0) {
            int p = dfs(g[v][i]);
            if (p != -1) {
                if ((p == -2) || (p == v)) {
                    return -2;
                }
                ans.pb(v);
                return p;
            }
        } else if (used[g[v][i]] == 1) {
            ans.pb(g[v][i]);
            ans.pb(v);
            return g[v][i];
        }

    }
    used[v] = 2;
    return -1;
}
char s[5555][5555];

void solve() {

    int n;
    cin>>n;
    for (int i = 0; i < n; ++i) {
        cin>>s[i];
        for (int j = 0; j < n; ++j) {

            if (s[i][j] == '1')
                g[i].pb(j);
        }
    }
    for (int i = 0; i < n && ans.empty(); ++i) {
        if (!used[i])
            dfs(i);
    }
    if (ans.empty()) {
        cout << "-1";
        return;
    }
    reverse(ans.begin(), ans.end());
    //cout<<endl;
    //for(int i=0;i<ans.size();++i)
    //  cout<<ans[i]<<' ';
    //cout<<endl;
    while (ans.size() > 3) {
        if (s[ans[0]][ans[ans.size() - 2]] == '1') {
            cout << ans[0] + 1 << ' ' << ans[ans.size() - 2] + 1 << ' ' << ans[ans.size()-1] + 1;
            return;
        }
        ans.pop_back();
    }

    cout << ans[0] + 1 << ' ' << ans[1] + 1 << ' ' << ans[2] + 1;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}

struct vim{

    int l;
    int ans[5005];
    vim(){
        l=0;
    }
    int size(){
        return l;
    }
    bool empty(){
        return l==0;
    }

    void pop_back(){
        --l;
    }
    void push_back(int k){
        ans[l++]=k;
    }

    int operator[] (int k){
        return ans[k];
    }

    int* begin(){
        return ans;
    }

    int* end(){
        return ans+l;
    }

};
vi g[5555];
int used[5555];
vi ans;

int dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < (int) g[v].size(); ++i) {
        if (used[g[v][i]] == 0) {
            int p = dfs(g[v][i]);
            if (p != -1) {
                if ((p == -2) || (p == v)) {
                    return -2;
                }
                ans.pb(v);
                return p;
            }
        } else if (used[g[v][i]] == 1) {
            ans.pb(g[v][i]);
            ans.pb(v);
            return g[v][i];
        }

    }
    used[v] = 2;
    return -1;
}
char s[5555][5555];

void solve() {

    int n;
    scanf("%d",&n);
    for (int i = 0; i < n; ++i) {
        scanf(" %s ",s[i]);
        for (int j = 0; j < n; ++j) {

            if (s[i][j] == '1')
                g[i].pb(j);
        }
    }
    for (int i = 0; i < n && ans.empty(); ++i) {
        if (!used[i])
            dfs(i);
    }
    if (ans.empty()) {
        cout << "-1";
        return;
    }
    reverse(ans.begin(), ans.end());
    //cout<<endl;
    //for(int i=0;i<ans.size();++i)
    //  cout<<ans[i]<<' ';
    //cout<<endl;
    while (ans.size() > 3) {
        if (s[ans[0]][ans[ans.size() - 2]] == '1') {
            cout << ans[0] + 1 << ' ' << ans[ans.size() - 2] + 1 << ' ' << ans[ans.size()-1] + 1;
            return;
        }
        ans.pop_back();
    }

    cout << ans[0] + 1 << ' ' << ans[1] + 1 << ' ' << ans[2] + 1;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}

struct vim{

    int l;
    int ans[5005];
    vim(){
        l=0;
    }
    int size(){
        return l;
    }
    bool empty(){
        return l==0;
    }

    void pop_back(){
        --l;
    }
    void push_back(int k){
        ans[l++]=k;
    }

    int operator[] (int k){
        return ans[k];
    }

    int* begin(){
        return ans;
    }

    int* end(){
        return ans+l;
    }

};
vi g[5555];
int used[5555];
vi ans;

int dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < (int) g[v].size(); ++i) {
        if (used[g[v][i]] == 0) {
            int p = dfs(g[v][i]);
            if (p != -1) {
                if ((p == -2) || (p == v)) {
                    return -2;
                }
                ans.pb(v);
                return p;
            }
        } else if (used[g[v][i]] == 1) {
            ans.pb(g[v][i]);
            ans.pb(v);
            return g[v][i];
        }

    }
    used[v] = 2;
    return -1;
}
char s[5555][5555];

void solve() {

    int n;
    scanf("%d",&n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            scanf(" %c",&s[i][j]);
            if (s[i][j] == '1')
                g[i].pb(j);
        }
    }
    for (int i = 0; i < n && ans.empty(); ++i) {
        if (!used[i])
            dfs(i);
    }
    if (ans.empty()) {
        cout << "-1";
        return;
    }
    reverse(ans.begin(), ans.end());
    //cout<<endl;
    //for(int i=0;i<ans.size();++i)
    //  cout<<ans[i]<<' ';
    //cout<<endl;
    while (ans.size() > 3) {
        if (s[ans[0]][ans[ans.size() - 2]] == '1') {
            cout << ans[0] + 1 << ' ' << ans[ans.size() - 2] + 1 << ' ' << ans[ans.size()-1] + 1;
            return;
        }
        ans.pop_back();
    }

    cout << ans[0] + 1 << ' ' << ans[1] + 1 << ' ' << ans[2] + 1;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
//typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}

struct vi{

    int l;
    int ans[5005];
    vi(){
        l=0;
    }
    int size(){
        return l;
    }
    bool empty(){
        return l==0;
    }

    void pop_back(){
        --l;
    }
    void push_back(int k){
        ans[l++]=k;
    }

    int operator[] (int k){
        return ans[k];
    }

    int* begin(){
        return ans;
    }

    int* end(){
        return ans+l;
    }

};
vi g[5555];
int used[5555];
vi ans;

int dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < (int) g[v].size(); ++i) {
        if (used[g[v][i]] == 0) {
            int p = dfs(g[v][i]);
            if (p != -1) {
                if ((p == -2) || (p == v)) {
                    return -2;
                }
                ans.pb(v);
                return p;
            }
        } else if (used[g[v][i]] == 1) {
            ans.pb(g[v][i]);
            ans.pb(v);
            return g[v][i];
        }

    }
    used[v] = 2;
    return -1;
}
char s[5555][5555];

void solve() {
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> s[i][j];
            if (s[i][j] == '1')
                g[i].pb(j);
        }
    }
    for (int i = 0; i < n && ans.empty(); ++i) {
        if (!used[i])
            dfs(i);
    }
    if (ans.empty()) {
        cout << "-1";
        return;
    }
    reverse(ans.begin(), ans.end());
    //cout<<endl;
    //for(int i=0;i<ans.size();++i)
    //  cout<<ans[i]<<' ';
    //cout<<endl;
    while (ans.size() > 3) {
        if (s[ans[0]][ans[ans.size() - 2]] == '1') {
            cout << ans[0] + 1 << ' ' << ans[ans.size() - 2] + 1 << ' ' << ans[ans.size()-1] + 1;
            return;
        }
        ans.pop_back();
    }

    cout << ans[0] + 1 << ' ' << ans[1] + 1 << ' ' << ans[2] + 1;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}

struct vim{

    int l;
    int ans[5005];
    vim(){
        l=0;
    }
    int size(){
        return l;
    }
    bool empty(){
        return l==0;
    }

    void pop_back(){
        --l;
    }
    void push_back(int k){
        ans[l++]=k;
    }

    int operator[] (int k){
        return ans[k];
    }

    int* begin(){
        return ans;
    }

    int* end(){
        return ans+l;
    }

};
vi g[5555];
int used[5555];
vi ans;

int dfs(int v) {
    used[v] = 1;
    for (int i = 0; i < (int) g[v].size(); ++i) {
        if (used[g[v][i]] == 0) {
            int p = dfs(g[v][i]);
            if (p != -1) {
                if ((p == -2) || (p == v)) {
                    return -2;
                }
                ans.pb(v);
                return p;
            }
        } else if (used[g[v][i]] == 1) {
            ans.pb(g[v][i]);
            ans.pb(v);
            return g[v][i];
        }

    }
    used[v] = 2;
    return -1;
}
char s[5555][5555];

void solve() {

    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> s[i][j];
            if (s[i][j] == '1')
                g[i].pb(j);
        }
    }
    for (int i = 0; i < n && ans.empty(); ++i) {
        if (!used[i])
            dfs(i);
    }
    if (ans.empty()) {
        cout << "-1";
        return;
    }
    reverse(ans.begin(), ans.end());
    //cout<<endl;
    //for(int i=0;i<ans.size();++i)
    //  cout<<ans[i]<<' ';
    //cout<<endl;
    while (ans.size() > 3) {
        if (s[ans[0]][ans[ans.size() - 2]] == '1') {
            cout << ans[0] + 1 << ' ' << ans[ans.size() - 2] + 1 << ' ' << ans[ans.size()-1] + 1;
            return;
        }
        ans.pop_back();
    }

    cout << ans[0] + 1 << ' ' << ans[1] + 1 << ' ' << ans[2] + 1;
}


#include <stdio.h>
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <math.h>
#include <sstream>
#include <complex>
#include <string.h>
#include <algorithm>
using namespace std;

void solve();
#define mp make_pair
#define pb push_back
typedef int fknmain;
typedef long long int li;
/**
 CAUTION Is int really int?
 *
 Real solution after main function
 */
//#define int li
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef double ld;

fknmain main() {
#ifdef DEBUG
    freopen("input", "r", stdin);
    //freopen("output", "w", stdout);
#define LL "%lld"
#else
#define LL "%I64d"
#endif
#ifndef int
#define INT "%d"
#else
#define INT LL
#endif
    cin.sync_with_stdio(false);
    cout.sync_with_stdio(false);
    solve();
    return 0;
}
vi g[5555];
int used[5555];
vi ans;
bool  dfs(int v){
    used[v]=1;
    for(int i=0;i<(int)g[v].size();++i){
        if(used[g[v][i]]==0){
            if(dfs(g[v][i])){
                ans.pb(v);
                return true;
            }
        }
        else if(used[g[v][i]]==1){
            ans.pb(v);
            return true;
        }

    }
    used[v]=2;
    return false;
}
char s[5555][5555];
void solve() {
    int n;
    cin>>n;
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            cin>>s[i][j];
            if(s[i][j]=='1')
                g[i].pb(j);
        }
    }
    bool have=false;
    for(int i=0;i<n;++i){
        if(!used[i])
            if(dfs(i)){
                have=true;
                break;
            }
    }
    if(!have){
        cout<<"-1";
        return;
    }
    reverse(ans.begin(),ans.end());
    while(ans.size()>3){
        if(s[ans[0]][ans[ans.size()-2]]=='1'){
            cout<<ans[0]+1<<' '<< ans[ans.size()-2]+1<<' '<<ans.back()+1;
            return;
        }
        ans.pop_back();
    }

    cout<<ans[0]+1<<' '<<ans[1]+1<<' '<<ans[2]+1;
}