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

using namespace std;

int h, w;
string board[20];

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

void Solve()
{
    map<string, int> memo;
    string res;

    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            for (int d = 0; d < 8; ++d) {
                string s;
                int nx = j, ny = i;

                do {

                    s += board[ny][nx];
                    ++memo[s];

                    nx = (nx + dx[d] + w) % w;
                    ny = (ny + dy[d] + h) % h;

                    if (memo[s] >= 2) {
                        if (s.size() > res.size() ||
                            (s.size() == res.size() && (s < res)))
                            res = s;
                    }

                } while (nx != j || ny != i);

            }
        }
    }

    if (res.size() <= 1)
        cout << "0\n";
    else
        cout << res << endl;
}

int main()
{
    while (cin >> h >> w, h || w) {

        for (int i = 0; i < h; ++i)
            cin >> board[i];

        Solve();
    }

    return 0;
}

C++: #include <cstdio>
#include <string>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;
#define REP(i,x)for(int i=0;i<x;i++)

string res;
int H,W,dx,dy,min_len;
char s[200];
char MAP[11][22];
bool visit[20][20];
vector<string> ss;
void dfs(int x,int y,int k){
  if(visit[y][x]){
    ss.push_back(string(s));
    return;
  }
  s[k]=MAP[y][x];  visit[y][x]=1;
  dfs((x + dx + W) % W, (y + dy + H) % H, k + 1);
  s[k]=0;  visit[y][x]=0;
}
int main() {
  while(scanf("%d%d",&H,&W),H){
    REP(i,H)scanf("%s",MAP[i]);
    ss.clear();
    min_len=1; res="0";
    REP(y,H)REP(x,W){
      for(dx=-1;dx<=1;dx++){
        for(dy=-1;dy<=1;dy++){
          if(dx|dy)dfs(x,y,0);
        }
      }
    }
    string res = "0";
    sort(ss.begin(),ss.end());
    REP(i,ss.size()-1){
      int len = 0;
      REP(k,min(ss[i].size(),ss[i+1].size())){
        if(ss[i][k]==ss[i+1][k])len++;
      }
      if(len < res.size())continue;
      if(res.size() == len){
        res = min(res, ss[i].substr(0,len));
      }else{
        res = ss[i].substr(0, len);
      }
    }
    puts(res.c_str());
  }
}

C++: #include <iostream>
#include <algorithm>
#include <set>
using namespace std;
#define REP(i,x)for(__typeof(x) i=0;i<x;i++)

string res;
set<string> m;
int H,W,dx,dy,min_len;
char s[200];
string MAP[11];
bool visit[20][20];
void dfs(int x,int y,int k){
  if(k==min_len){
    if(m.count(string(s)))res=min(res,string(s));
    m.insert(string(s));
  }else if(k>min_len){
    if(m.count(string(s)))res=string(s),min_len=k;
    m.insert(string(s));
  }
  if(visit[y][x])
    return;
  s[k]=MAP[y][x];  visit[y][x]=1;
  dfs((x + dx + W) % W, (y + dy + H) % H, k + 1);
  s[k]=0;  visit[y][x]=0;
}
int main() {
  while(cin>>H>>W,H){
    REP(i,H)cin>>MAP[i];
    m.clear();
    min_len=1;
    res="0";
    REP(y,H)REP(x,W){
      for(dx=-1;dx<=1;dx++){
        for(dy=-1;dy<=1;dy++){
          if(dx|dy)dfs(x,y,0);
        }
      }
    }
    cout<<res<<endl;
  }
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<set>
using namespace std;
int w,h;

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

void solve(){
	set<string> S;
	vector<string> V;
	for(int i=0;i<h;i++){
		string s;
		cin>>s;
		V.push_back(s);
	}
	string res="";

	for(int y=0;y<h;y++){
		for(int x=0;x<w;x++){
			for(int r=0;r<8;r++){
				int nx=x,ny=y;
				string read="";
				while(!(nx==x && ny==y) || read.size()==0){
					read+=V[ny][nx];
					if(S.count(read)){
						if(res.size()<read.size()) res=read;
						if(res.size()==read.size() && res>read) res=read;
					}
					S.insert(read);
					ny+=dy[r];
					nx+=dx[r];
					if(ny<0) ny=h-1;
					if(ny>=h) ny=0;
					if(nx<0) nx=w-1;
					if(nx>=w) nx=0;
				}
			}
		}
	}
	if(res.size()>1)
		cout<<res<<endl;
	else cout<<0<<endl;
}



int main()
{
	while(cin>>h>>w){
		if(h==0) break;
		solve();
	}
	return 0;
}

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

using namespace std;

int H,W;
bool visited[25][25];
char field[25][25];
map<string,int> mp;
const int dx[] = {-1,-1,-1,0,0,1,1,1};
const int dy[] = {-1,0,1,-1,1,-1,0,1};

void rec(int x,int y,int d,string s){
  if(visited[y][x]){ return; }
  visited[y][x] = true;
  int nx = (x + dx[d] + W) % W;
  int ny = (y + dy[d] + H) % H;
  mp[s+field[y][x]]++;
  rec(nx,ny,d,s+field[y][x]);
}

int main(){
  while(cin >> H >> W, H){
    mp.clear();
    for(int i = 0 ; i < H ; i++){
      for(int j = 0 ; j < W ; j++){
        cin >> field[i][j];
      }
    }
    for(int i = 0 ; i < H ; i++){
      for(int j = 0 ; j < W ; j++){
        for(int k = 0 ; k < 8 ; k++){
          memset(visited,false,sizeof(visited));
          rec(j,i,k,"");
        }
      }
    }
    int ans_size = -1;
    string ans;
    map<string,int>::iterator it;
    for(it = mp.begin() ; it != mp.end() ; ++it){
      int size = it->first.size();
      if(it->second < 2 || size < 2){ continue; }
      if(ans_size < size){
        ans_size = size;
        ans = it->first;
      }
    }
    if(ans_size == -1){
      cout << 0 << endl;
    }else{
      cout << ans << endl;
    }
  }
  return 0;
}