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 <string>
#include <algorithm>
using namespace std;

int gcd(int a, int b){
    while(a != b){
        if(a > b) a = a - b; else b = b - a;
    }
    return a;
}

int lcm(int a, int b){
    return ((a / gcd(a, b)) * b);
}

int main(){
    int h, w;
    while(true){
char torus[10][20];
        string str[2048];
        bool ok[2048];
        int num = 0;

        for(int i=0; i<2048; ++i){
            str[i] = "";
            ok[i] = true;
        }

        cin >> h >> w;
        if(h==0 && w==0) break;

        int cml = lcm(w, h);

        for(int i=0; i<h; ++i){
            for(int j=0; j<w; ++j){
                cin >> torus[i][j];
            }
        }

        //一番長い文字列をつくる

        for(int y=0; y<h; ++y){
            for(int x=0; x<w; ++x){
                for(int i=0; i<h; ++i){
                    str[num] += torus[(y+i)%h][x];
                    str[num+1] += torus[h-(y+i)%h-1][x];
                }
                num += 2;
            }
        }
        for(int y=0; y<h; ++y){
            for(int x=0; x<w; ++x){
                for(int i=0; i<w; ++i){
                    str[num] += torus[y][(x+i)%w];
                    str[num+1] += torus[y][w-(x+i)%w-1];
                }
                num += 2;
            }
        }
        for(int y=0; y<h; ++y){
            for(int x=0; x<w; ++x){
                for(int i=0; i<cml; ++i){
                    str[num] += torus[(y+i)%h][(x+i)%w];
                    str[num+1] += torus[(y+i)%h][w-(x+i)%w-1];
                    str[num+2] += torus[h-(y+i)%h-1][(x+i)%w];
                    str[num+3] += torus[h-(y+i)%h-1][w-(x+i)%w-1];
                }
                num += 4;
            }
        }


        string result = "";

        sort(str, str+num);

        //徐々に削る
        for(int i=0; i<cml; ++i){
            for(int j=num-1; j>0; --j){
                if(ok[j] && str[j].length() >= i && str[j-1].length() >= i){
                    cout << str[j].substr(0,i) << endl;
                    cout << str[j-1].substr(0,i) << endl;
                    cout << endl;
                    if(str[j].substr(0, i) == str[j-1].substr(0, i)){
                        result = str[j];
                        result.resize(i);
                    }else{
                        ok[j] = false;
                    }
                }
            }
        }

        cout << ((result.length() == 0) ? "0" : result) << endl;

    }

    return 0;
}

C++: #include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;

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

int main(){

  while(true){
    int h, w; cin>> h>> w;
    if(h==0 && w==0) break;
    vector<string> a(h);
    rep(i, h) cin>> a[i];
    string best="";
    set<string> dict;
    const int dx[]={-1, -1, -1,  0, 0,  1, 1, 1};
    const int dy[]={-1,  0,  1, -1, 1, -1, 0, 1};
    rep(i, h)rep(j, w){
      rep(k, 8){
        int x=i, y=j;
        string t="";
        do{
          t+=a[x][y];
          if(dict.count(t)){
            if(best.size()<t.size()){
              best=t;
            }else if(best.size()==t.size()){
              if(t<best) best=t;
            }
          }else if(t.size()>=2){
            dict.insert(t);
          }
          x=(x+h+dx[k])%h;
          y=(y+w+dy[k])%w;
        }while(x!=i || y!=j);
      }
    }

    if(best.size()>=2) cout<< best<< endl;
    else cout<< 0<< endl;
  }

  return 0;
}

C++: #include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

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;

#define x first
#define y second

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

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

int main(void){
    for(int w, h; cin >> h >> w, h;){
        vs strs(h);
        rep(y, h){
            cin >> strs[y];
        }

        set<string> s;
        string res = "0";
        rep(y, h){
            rep(x, w){
                rep(i, 8){
                    string cur;
                    pii next = mp(x, y);

                    do{
                        cur.pb(strs[next.y][next.x]);
                        if(1 < cur.size() && !s.insert(cur).second)
                        {
                            if((res.size() < cur.size()) || 
                               (res.size() == cur.size() && cur < res)){
                                res = cur;
                            }
                        }

                        next.x = (next.x + dx[i] + w) % w;
                        next.y = (next.y + dy[i] + h) % h;
                        
                    } while(next != mp(x, y));
                }
            }
        }

        cout << res << endl;
    }

	return 0;
}