#[macro_use] #[allow(dead_code, unused_macros, non_upper_case_globals)] mod io { macro_rules! p { ($x:expr) => { println!("{}", $x); }; ($x:expr, $($y:expr),+) => { print!("{} ", $x); p!($($y),+); }; } macro_rules! dump { ($($a:expr),+) => {{ if USE_DUMP { use std::io::*; write!(stderr(), "{}:{}\t", file!(), line!()).unwrap(); dump!(A $($a),+); write!(stderr(), " = ").unwrap(); dump!(B $($a),+); writeln!(stderr(), "").unwrap(); } }}; (A $x:expr) => { write!(stderr(), "{}", stringify!($x)).unwrap(); }; (A $x:expr, $($y:expr),+) => { write!(stderr(), "{}, ", stringify!($x)).unwrap(); dump!(A $($y),+); }; (B $x:expr) => { write!(stderr(), "{:?}", $x).unwrap(); }; (B $x:expr, $($y:expr),+) => { write!(stderr(), "{:?}, ", $x).unwrap(); dump!(B $($y),+); }; } pub trait Scan { fn scan() -> T; } macro_rules! scan_primitive { ($t: ty) => { impl Scan<$t> for $t { fn scan() -> $t { get_word().expect("EOF?").parse() .unwrap_or_else(|e| panic!("Cannot parse {}", e)) } } }; ($t: ty, $($u: ty),+) => { scan_primitive!($t); scan_primitive!($($u),+); }; } macro_rules! scan_tuple { ($($t: ident),*) => { impl< $($t: Scan<$t>),* > Scan< ( $($t),* ) > for ( $($t),* ) { fn scan() -> ( $($t),* ) { ( $( $t::scan()),* ) } } }; } scan_primitive!(u8, u16, u32, u64, i8, i16, i32, i64, f32, f64, usize, isize, bool, String); scan_tuple!(A, B); scan_tuple!(A, B, C); scan_tuple!(A, B, C, D); pub fn get>() -> T { T::scan() } pub fn get_vec>(n: usize) -> Vec { (0..n).map(|_| get()).collect() } pub fn get_mat>(r: usize, c: usize) -> Vec> { (0..r).map(|_| get_vec(c)).collect() } pub fn get_vec_char() -> Vec { get_word().unwrap().chars().collect() } pub fn get_mat_char(h: usize) -> Vec> { (0..h).map(|_| get_vec_char()).collect() } pub fn get_line() -> String { get_line_wrapped().unwrap() } fn get_word() -> Option { let mut res = String::with_capacity(16); while let Some(c) = get_u8() { let d = c as char; if !d.is_whitespace() { res.push(d); } else if res.len() != 0 { unget_u8(c); break; } } if res.len() == 0 { None } else { Some(res) } } pub fn get_line_wrapped() -> Option { let c = get_u8(); if c.is_none() { return None; } let mut line = String::with_capacity(20); line.push(c.unwrap() as char); loop { let c = get_u8(); if c.is_none() || c.unwrap() == b'\n' { // コメントはC++等での仕様 // if c.is_some() { // self.unget_u8(b'\n'); // } return Some(line); } line.push(c.unwrap() as char); } } static mut idx: usize = 0; static mut len: usize = 0; static mut buf: [u8; 65536] = [0; 65536]; fn get_u8() -> Option { unsafe { use std::io::{stdin, Read}; if idx == len { match stdin().read(&mut buf) { Ok(l) if l > 0 => { idx = 0; len = l; } _ => return None, } } idx += 1; Some(buf[idx - 1]) } } fn unget_u8(c: u8) { unsafe { idx -= 1; buf[idx] = c; } } pub fn has_next() -> bool { loop { let c = get_u8(); if c.is_none() { return false; } let c = c.unwrap(); if !(c as char).is_whitespace() { unget_u8(c); return true; } } } pub const USE_DUMP: bool = true; } use io::*; fn main() { while has_next() { let f = || { let mut size = 0; let mut next = [26; 26]; let mut cs = vec![]; let n = get(); for _ in 0..n { let s = get_vec_char().iter() .map(|c| *c as usize - b'A' as usize).collect::>(); for i in 1..s.len() { next[s[i-1]] = s[i] } for &c in s.iter() { cs.push(c); } size += s.len(); } (size, next, cs) }; let mut ok = true; let (sz1, next1, cs1) = f(); let (sz2, next2, cs2) = f(); let mut cs = cs1.iter().chain(cs2.iter()).collect::>(); cs.sort(); cs.dedup(); ok &= sz1 == sz2; let next = (0..26).map(|i| { if next1[i] == 26 { next2[i] } else if next2[i] == 26 { next1[i] } else if next1[i] == next2[i] { next1[i] } else { ok = false; 100 } }).collect::>(); let mut out = false; if ok { for &x in cs.iter() { let mut res = vec![]; let mut c = *x; while c != 26 { res.push(c); c = next[c]; } if res.len() == sz1 { p!(res.iter().map(|c| (*c + b'A' as usize) as u8 as char) .collect::()); out = true; } } //dump!(res); } if !ok || !out { p!(-1); } } }