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>
#include<vector>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(n) rep(i,n)
#define all(n) n.begin(),n.end()
#define foreach(c,it) for(typeof(c.begin()) it=c.begin();it!=c.end();++it)

int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1};
int dy[] = {1, 1, 1, 0, 0, -1, -1, -1};
const int MAXH = 10, MAXW = 20;
char tile[MAXW][MAXH];
int checked[MAXW][MAXH];
typedef pair<int, string> p;
int main()
{
    int w, h;
    while(cin >> h >> w && h)
    {
        rep(j,h)rep(i,w){ cin >> tile[i][j];}
        
        vector<p> ans;
        rep(sx,w)rep(sy,h)rep(v,8)
        {
            memset(checked, 0, sizeof(checked));
            int x = sx, y = sy;
            string s;
            while(!checked[x][y])
            {
                //cout << x << " " << y << endl;
                s += tile[x][y];
                ans.push_back(p( -s.size(), s));
                checked[x][y] = 1;
                x += dx[v]; y += dy[v];
                if(x == w) x = 0;
                if(x == -1) x = w - 1;
                if(y == h) y = 0;
                if(y == -1) y = h - 1;

            }
        }
        sort(all(ans));
        int found = 0;
        for(int i = 0; i < ans.size() - 1; i++)if(ans[i] == ans[i + 1] && ans[i].first <= -2)
        {
            cout << ans[i].second << endl;
            found = 1;
            break;
        }
        if(!found) cout << 0 << endl;

    }
    return 0;
}