暴力枚举,再KMP!
import java.awt.color.CMMException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MaximizeAction;
public class Main {
public static void main(String[] args) throws IOException{
InputReader in = new InputReader(System.in) ;
StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(System.out);
int n = in.nextInt() ;
while((n--) > 0){
out.println( new Task().solve(in.nextInt() , in) ) ;
// out.flush() ;
}
out.flush() ;
}
}
class Task{
String[] str ;
public String solve(int n , InputReader in){
str = new String[n] ;
for(int i = 0 ; i < n ; i++) str[i] = in.next() ;
Arrays.sort(str, new Comparator<String>(){
public int compare(String o1, String o2) {
return o1.length() - o2.length() ;
}
}
);
String result = null ;
for(int len = 3 , m = str[0].length() ; len <= m ; len++){
String now = null ;
for(int i = 0 ; i + len <= m ; i++){
String word = str[0].substring(i, i + len) ;
KMP kmp = new KMP(word.toCharArray() ) ;
int k ;
for(k = 1 ; k < n ; k++){
if(! kmp.searchForm(str[k].toCharArray())) break ;
}
if(k == n){
if(now == null || now.compareTo(word) > 0){
now = word ;
}
}
}
if(now != null) result = now ;
}
if(result == null) return "no significant commonalities" ;
else return result ;
}
}
class KMP{
int m ;
char[] p ;
int[] fail ;
KMP(char[] p){
m = p.length ;
this.p = p ;
fail = new int[m+1] ;
int crt = fail[0] = -1 ;
for(int i = 1 ; i <= m ; i++){
while(crt >= 0 && p[crt] != p[i-1]) crt = fail[crt] ;
fail[i] = ++ crt ;
}
}
public int Power(){
if(m % (m - fail[m]) == 0) return m / (m - fail[m]) ;
return 1 ;
}
public ArrayList<Integer> PrefixandSuffix(){
ArrayList<Integer> g = new ArrayList<Integer>();
int k = m ;
while(fail[k] != -1){
g.add(k) ;
k = fail[k] ;
}
Collections.sort(g) ;
return g ;
}
public boolean searchForm(char[] txt){
int n = txt.length , count = 0 ;
for(int i = 0 , j = 0 ; i < n ; i++){
while(j >= 0 && txt[i] != p[j]) j = fail[j] ;
if(++j == m){
return true ;
//count++ ;
//j = fail[j] ;
//j = 0 ;
}
}
return false ;
}
}
class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
}