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 <stdio.h>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

int div_row[8] = {-1,-1,-1,0,0,1,1,1},div_col[8] = {-1,0,1,-1,1,-1,0,1},H,W;

struct Info{
	void init(){
		length = count = 0;
	}
	char spell[201];
	int length,count;
};

//base??¨comp??????????????????????????¢??°
bool strCmp(char* base, char* comp){
	int length1 = 0,length2 = 0;
	for(int i=0;base[i] != '\0'; i++)length1++;
	for(int i=0;comp[i] != '\0'; i++)length2++;
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}

//???????????????????????????3,left?????????????????´??????1,right?????????????????¨??????2
int strCmp2(char* left,char* right){
	int i;

	if(strCmp(left,right))return 3;

	for(i=0;left[i] != '\0' && right[i] != '\0'; i++){
		if(left[i] != right[i]){
			if(left[i] < right[i])return 1;
			else{
				return 2;
			}
		}
	}
	if(left[i] == '\0')return 1;
	else{
		return 2;
	}
}

int main(){

	int work_row,work_col,work_index,ans,info_index = 0,inner_work_index,tmp,max_length;
	char table[10][21],work[201],inner_work[201];
	bool FLG;

	Info* info = (Info*)malloc(sizeof(Info)*(39800));

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		for(int i = 0; i < info_index; i++)info[i].init();

		ans = -1; //?§£?????????????????????
		info_index = 0; //info?????????????????????

		for(int i = 0; i < H; i++){
			scanf("%s",table[i]);
		}

		for(int row = 0; row < H; row++){ //???????????????
			for(int col = 0; col < W; col++){ //???????????????
				for(int a = 0; a < 8; a++){ //8??????????????????
					work_index = 0;
					work[work_index++] = table[row][col];

					work_row = (row + div_row[a]+H)%H;
					work_col = (col + div_col[a]+W)%W;

					while(work_row != row || work_col != col){ //???????????????????????§????§????????¶???????
						work[work_index++] = table[work_row][work_col];
						//printf("work_row:%d work_col:%d\n",work_row,work_col);
						work_row = (work_row + div_row[a]+H)%H;
						work_col = (work_col + div_col[a]+W)%W;
					}

					//return 0;

					//?????????????????£??????????????§?????§????????????????????¨??????????????????????????????
					for(int right = 1; right <= work_index-1;right++){
						inner_work_index = 0;
						for(int b = 0; b <= right; b++){
							inner_work[inner_work_index++] = work[b];
						}
						inner_work[inner_work_index] = '\0';

						//??¢?????????????????????????????????????????????
						FLG = false;
						for(int b = 0; b < info_index; b++){
							if(strCmp(inner_work,info[b].spell)){
								FLG = true;
								tmp = b;
								break;
							}

						}
						if(FLG){ //??¢??????????????????????????´???
							info[tmp].count++;
						}else{ //??????????????????????????£?????´???
							strcpy(info[info_index].spell,inner_work);
							info[info_index].length = right+1;
							info[info_index].count = 1;
							info_index++;
						}
					}
				}
			}
		}

		max_length = 2;

		//??????????????????????????°???
		for(int i = 0; i < info_index; i++){

			if(info[i].count >= 2 && info[i].length >= max_length){
				if(ans == -1){ //?????????????§£????£?
					max_length = info[i].length;
					ans = i;
				}else{
					if(info[i].length > max_length){ //???????????§???
						max_length = info[i].length;
						ans = i;
					}else{ //info[i].length == max_length
						if(strCmp2(info[i].spell,info[ans].spell) == 1){ //?????¨????§£????????????????????§??????
							ans = i;
						}
					}
				}
			}
		}

		if(ans == -1){
			printf("0\n");
		}else{
			printf("%s\n",info[ans].spell);
		}
	}

	return 0;
}

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

using namespace std;

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

int main(){
	while(true){
		int w, h;
		cin >> h >> w;
		if(h == 0 && w == 0){ break; }
		vector<string> v(h);
		for(int i = 0; i < h; ++i){ cin >> v[i]; }
		set<string> found;
		string answer;
		for(int i = 0; i < h; ++i){
			for(int j = 0; j < w; ++j){
				for(int d = 0; d < 8; ++d){
					int y = i, x = j;
					string s;
					do {
						s += v[y][x];
						if(found.find(s) == found.end()){
							found.insert(s);
						}else{
							if(answer.size() < s.size()){
								answer = s;
							}else if(answer.size() == s.size() && s < answer){
								answer = s;
							}
						}
						y = (y + dy[d] + h) % h;
						x = (x + dx[d] + w) % w;
					} while(y != i || x != j);
				}
			}
		}
		if(answer.size() <= 1){ answer = "0"; }
		cout << answer << endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
using namespace std;

char s[10][21];
bool used[10][20];
int main() {
	int h, w;
	while (scanf("%d%d", &h, &w), h) {
		rep(i, h)scanf("%s", s[i]);
		map<string, int>mp;
		rep(i, h)rep(j, w) {
			for (int dx = -1; dx <= 1; dx++) {
				for (int dy = -1; dy <= 1; dy++) {
					if (dx == 0 && dy == 0)continue;
					string t;
					memset(used, 0, sizeof(used));
					int x = i, y = j;
					while (!used[x][y]) {
						t += s[x][y]; used[x][y] = 1; x += dx; y += dy;
						x = (x + h) % h; y = (y + w) % w;
						mp[t]++;
					}
				}
			}
		}
		string ans;
		for (auto p : mp) {
			if (p.second > 1 && ans.size() < p.first.size())ans = p.first;
		}
		if (ans == "")ans = "0";
		cout << ans << endl;
	}
}