Go: package main

import "fmt"

var H, W int

type point struct {
	x, y int
}

func (p *point) add(q point) {
	p.x += q.x
	p.y += q.y
	if p.x < 0 {
		p.x += H
	}
	if p.y < 0 {
		p.y += W
	}
	p.x %= H
	p.y %= W
}

func isPalindrome(str string) bool {
	for i, j := 0, len(str)-1; i < j; i, j = i+1, j-1 {
		if str[i] != str[j] {
			return false
		}
	}
	return true
}

func magicSpel(arr []string) string {
	var ans string
	m := map[string]int{}
	for i := range arr {
		for j := range arr[i] {
			for _, d := range []point{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}} {
				cur := point{x: i, y: j}
				str := string(arr[cur.x][cur.y])
				cur.add(d)
				for i != cur.x || j != cur.y {
					str += string(arr[cur.x][cur.y])
					cur.add(d)
					if isPalindrome(str) {
						m[str] += 2
					} else {
						m[str]++
					}
				}
			}
		}
	}
	for s, v := range m {
		if 1 < v {
			if len(ans) < len(s) {
				ans = s
			} else if len(ans) == len(s) && s < ans {
				ans = s
			}
		}
	}

	if len(ans) == 0 {
		return "0"
	}

	return ans
}

func main() {
	for {
		fmt.Scan(&H, &W)
		if H == 0 && W == 0 {
			break
		}

		var arr []string

		for i := 0; i < H; i++ {
			var s string
			fmt.Scan(&s)
			arr = append(arr, s)
		}

		fmt.Println(magicSpel(arr))
	}
}

// 2 3
// ABC
// DEF

C++: #include <bits/stdc++.h>

using namespace std;

inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
template<class T> inline T sqr(T x) {return x*x;}

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;

#define all(a)  (a).begin(),(a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define pb push_back
#define mp make_pair
#define each(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define exist(s,e) ((s).find(e)!=(s).end())
#define range(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)  range(i,0,n)
#define clr(a,b) memset((a), (b) ,sizeof(a))
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

const double eps = 1e-10;
const double pi  = acos(-1.0);
const ll INF =1LL << 62;
const int inf =1 << 29;

int n,m;
string donut[15];
set<string> check;

int dx[8]={1,1,1,0,-1,-1,-1,0};
int dy[8]={1,0,-1,-1,-1,0,1,1};

void longest(string &res,string in){
	if(in.size()>res.size())
		res=in;
	if(in.size()==res.size()&&in<res)
		res=in;
}

string solve(){
	string res="";
	rep(i,n)rep(j,m)rep(k,8){
		string cur="";
		cur+=donut[i][j];
		int ci=(i+dx[k]+n)%n,cj=(j+dy[k]+m)%m;
		while(ci!=i||cj!=j){
			cur+=donut[ci][cj];
			if(check.find(cur)!=check.end())
				longest(res,cur);
			else
				check.insert(cur);
			ci=(ci+dx[k]+n)%n,cj=(cj+dy[k]+m)%m;
		}
	}
	return res;
}

int main(void){
	while(cin >> n >> m){
		rep(i,n) cin >> donut[i];
		if(n==0)
			break;
		check.clear();
		string ans=solve();
		if(ans=="")
			cout << 0 << endl;
		else
			cout << ans << endl;
	}
	return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#include <cstdlib>
#include <string>
#include <set>
#include <ctime>
using namespace std;

int dx[8]={0,0,1,1,1,-1,-1,-1},dy[8]={1,-1,0,-1,1,0,-1,1};

string s[2000],temp;

char str[30][30];

int main()
{
    int n,m,i,j,x,y;
    while(scanf("%d%d",&n,&m)==2)
    {
        if(!n&&!m)
            break;
        for(i=0;i<n;i++)
            scanf("%s",str[i]);
        int num=0,l=0,ans=0,l1,l2,d;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                for(d=0;d<8;d++)
                {
                    x=i;
                    y=j;
                    temp="";
                    temp+=str[x][y];
                    while(1)
                    {
                        x+=dx[d];
                        y+=dy[d];
                     //   printf("%d %d %d %d %d\n",i,j,d,x,y);
                        if(x>=n)
                            x-=n;
                        if(y>=m)
                            y-=m;
                        if(x<0)
                            x+=n;
                        if(y<0)
                            y+=m;
                        if(x==i&&y==j)
                            break;
                        temp+=str[x][y];
                    }
                    s[num++]=temp;
               //     cout<<temp<<endl;
                }
            }
        }
        sort(s,s+num);
        for(i=1;i<num;i++)
        {
            l1=s[i-1].size();
            l2=s[i].size();
            for(j=0;j<l1&&j<l2;j++)
            {
                if(s[i-1][j]!=s[i][j])
                    break;
            }
            if(j>l)
            {
                l=j;
                ans=i;
            }
        }
        if(l<2)
            printf("0\n");
        else
        {
            for(i=0;i<l;i++)
                printf("%c",s[ans][i]);
            printf("\n");
        }
    }
    return 0;
}

C++: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <algorithm>
#include <functional>
#include <cstring>
#include <string>
#include <sstream>
#include <bitset>
using namespace std;
#define INF	100000000
#define MOD 1000000007
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define lb lower_bound
#define ub upper_bound
#define SS stringstream
#define rep(i,n) for(int i = 0; i < n; i++)
#define SORT(x) sort((x).begin(), (x).end())
#define clr(a,b) memset((a),(b),sizeof(a))
typedef long long int ll;
typedef pair<int, int> P;
typedef vector<int> Vi;
typedef vector<ll> Vll;
typedef vector<P> Vp;
typedef priority_queue<P, vector<P>, greater<P> > PQ;

int dx[8] = {1,1,1,-1,-1,-1,0,0}, dy[8] = {1,0,-1,1,0,-1,1,-1};

int main(){
	int h, w;
	while(scanf("%d%d", &h, &w),h||w){
		vector<string> d(h);
		map<int,map<string,int> > m;
		rep(i,h) cin >> d[i];
		rep(i,h) rep(j,w){
			rep(k,8){
				int y = i, x = j;
				string str;
				str.pb(d[y][x]);
				while(true){
					y += dy[k];
					x += dx[k];
					if(y < 0) y = h+y;
					if(y >= h) y = y-h;
					if(x < 0) x = w+x;
					if(x >= w) x = x-w;
					if(y == i && x == j) break;
					str.pb(d[y][x]);
					m[-1*str.size()][str]++;
				}
			}
		}
		map<int,map<string,int> >::iterator ite;
		bool ok = false;
		for(ite = m.begin(); ite != m.end(); ite++){
			map<string,int> tmp = ite->sec;
			map<string,int>::iterator it;
			for(it = tmp.begin(); it != tmp.end(); it++){
				if(it->sec >= 2){
					cout << it->fi << endl;
					ok = true;
					break;
				}
			}
			if(ok) break;
		}
		if(!ok) cout << "0" << endl;
	}
}

C++: #include<iostream>
#include<set>
#include<vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};

int main() {
  int h, w;
  while (true) {
    set<string> s;
    vector<string> vs;
    string res;
    cin >> h >> w;
    if (h == 0 && w == 0) break;
    rep (i, h) {
      string str;
      cin >> str;
      vs.push_back(str);
    }
    rep (i, h) rep (j, w) rep (d, 8) {
      int x = j, y = i;
      string str;
      do {
	str += vs[y][x];
	//cout << i << " " << j << " " << d << " " << str << endl;
	x = (x + w + dx[d]) % w;
	y = (y + h + dy[d]) % h;
	if (str.size() > 1u) {
	  if (s.count(str) > 0) {
	    if (res.size() < str.size()) {
	      res = str;
	    } else if (res.size() == str.size() && res > str) {
	      res = str;
	    }
	  } else {
	    s.insert(str);
	  }
	}
      } while (y != i || x != j);
    }
    if (res == "") {
      cout << 0 << endl;
    } else {
      cout << res << endl;
    }
  }
  return 0;
}