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 <iostream>
#include <map>

using namespace std;

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

int main(){
  
  while (1){
    int w, h;
    char mp[20][30];
    const int diff[] = {1, 0, -1, 0, 1, 1, -1, -1, 1};
    map<string, int> spells;
    string input, ans="";
    
    cin >> h >> w;
    if (w==0 && h==0){
      break;
    }
    
    REP(j, h){
      cin >> input;
      REP(k, w){
        mp[j][k] = input[k];
      }
    }
    
    REP(j0, h){
      REP(k0, w){
        REP(i,8){
//          printf("(%d, %d) i=%d\n", j0, k0, i);
          string str = "";
          int j=j0, k=k0;
          while(1){
//            printf("(%d, %d)\n", j, k);
            str += mp[j][k];
            spells[str]++;
            if (spells[str]>1){
              if (ans.length() < str.length() || (ans.length()==str.length() && ans > str)){
                ans = str;
              }
            }
            j = (j+diff[i]+h)%h;
            k = (k+diff[i+1]+w)%w;
            if (j==j0 && k==k0){
              break;
            }
          }
//          cout << str << endl;
        
        }
      }
    }
    
    if (ans.length()<2){
      cout << 0 << endl;
    }else{
      cout << ans << endl;
    }
    
    
  }
}

C++: #include<iostream>
#include<map>
#include<vector>
using namespace std;
string s[10];
int h,w;
int dx[]={0,1,0,-1,1,1,-1,-1},dy[]={1,0,-1,0,1,-1,1,-1};
main()
{
	while(cin>>h>>w,h)
	{
		for(int i=0;i<h;i++)cin>>s[i];
		map<string,int>M;
		string ans="0";
		for(int i=0;i<h;i++)for(int j=0;j<w;j++)
		{
			for(int r=0;r<8;r++)
			{
				string now=s[i].substr(j,1);
				int x=i+dx[r],y=j+dy[r];
				x=(x+h)%h;y=(y+w)%w;
				while(x!=i||y!=j)
				{
					now+=s[x][y];
					if(M[now]++==1)
					{
						if(now.size()>ans.size())ans=now;
						else if(ans.size()==now.size()&&ans>now)ans=now;
					}
					x+=dx[r],y+=dy[r];
					x=(x+h)%h;y=(y+w)%w;
				}
			}
		}
		cout<<ans<<endl;
	}
}

C++: #include <bits/stdc++.h>
#define syosu(x) fixed<<setprecision(x)
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> P;
typedef pair<double,double> pdd;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<string> vs;
typedef vector<P> vp;
typedef vector<vp> vvp;
typedef vector<pll> vpll;
typedef pair<int,P> pip;
typedef vector<pip> vip;
const int inf=1<<29;
const ll INF=1ll<<60;
const double pi=acos(-1);
const double eps=1e-9;
const ll mod=1e9+7;
//const int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1};
const int dx[8]={-1,0,1,0,-1,-1,1,1},dy[8]={0,-1,0,1,-1,1,-1,1};

const int N=16;

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	while(1){
		int h,w;
		cin>>h>>w;
		if(h==0) break;
		vs a(h);
		for(auto &i:a) cin>>i;
		map<string,int> mp;
		for(int i=0;i<h;i++) for(int j=0;j<w;j++){
			for(int k=0;k<8;k++){
				vvi b(h,vi(w));
				int x=i,y=j;
				string s;
				while(!b[x][y]){
					b[x][y]=1;
					s+=a[x][y];
					x+=dx[k],y+=dy[k];
					if(x>=h) x=0;
					if(x<0) x=h-1;
					if(y>=w) y=0;
					if(y<0) y=w-1;
					mp[s]++;
				}
//				cout<<i<<' '<<j<<' '<<k<<' '<<s<<endl;
//				mp[s]++;
			}
		}
		string res="";
		for(auto p:mp) if(p.second>1&&p.first.size()>res.size()){
			res=p.first;
		}
		if(res.size()<=1) res="0";
		cout<<res<<endl;
//		cout<<mp["ABRACADABRA"]<<endl;
	}
}

C++: #include <iostream>
#include <map>
#include <string>
using namespace std;
int main(){
  //?????¶????????§?§£????????¨?????????
  int H, W;
  while(cin >> H >> W, H||W){
    string pattern[H];
    for(int i = 0; i < H; ++i){
      cin >> pattern[i];
    }
    int ng = H*W + 1, ok = 2;
    int dx[] = {1,0,-1,0,1,1,-1,-1}, dy[] = {0,1,0,-1,1,-1,1,-1};
    string ans = "0";
    while(ng - ok > 1){
      int m = (ng + ok)/2;
      map<string,int> M;
      for(int i = 0; i < H; ++i){
	for(int j = 0; j < W; ++j){
	  for(int k = 0; k < 8; ++k){
	    string str(m,'.');
	    str[0] = pattern[i][j];
	    bool f = true;
	    for(int l = 1; l < m; ++l){//??????????????????
	      int s = ((i + l*dx[k])%H+H)%H, t = ((j + l*dy[k])%W+W)%W;
	      if(s == i && t == j){
		f = false;
		break;
	      }else{
		str[l] = pattern[s][t];
		//str += pattern[s][t];
	      }
	    }
	    //cout << str << endl;
	    if(f){
	      M[str] += 1;
	    }
	  }
	}
      }
      bool g = false;
      //for(map<string,int>::iterator itr = M.end(); itr != M.begin(); --itr){
      for(map<string,int>::iterator itr = M.begin(); itr != M.end(); ++itr){
	if(itr->second > 1){
	  g = true;
	  ans = itr->first;
	  break;
	}
      }
      
      if(g){
	ok = m;
      }else{
	ng = m;
      }

    }
    
    cout << ans << endl;
    
  }
  return 0;
}