We had a string s consisting of n lowercase Latin letters. We made k copies of this string, thus obtaining k identical strings s1, s2, ..., sk. After that, in each of these strings we swapped exactly two characters (the characters we swapped could be identical, but they had different indices in the string).

You are given k strings s1, s2, ..., sk, and you have to restore any string s so that it is possible to obtain these strings by performing aforementioned operations. Note that the total length of the strings you are given doesn't exceed 5000 (that is, k·n ≤ 5000).

Input

The first line contains two integers k and n (1 ≤ k ≤ 2500, 2 ≤ n ≤ 5000, k · n ≤ 5000) — the number of strings we obtained, and the length of each of these strings.

Next k lines contain the strings s1, s2, ..., sk, each consisting of exactly n lowercase Latin letters.

Output

Print any suitable string s, or -1 if such string doesn't exist.

Examples

Input

3 4
abac
caab
acba


Output

acab


Input

3 4
kbbu
kbub
ubkb


Output

kbub


Input

5 4
abcd
dcba
acbd
dbca
zzzz


Output

-1

Note

In the first example s1 is obtained by swapping the second and the fourth character in acab, s2 is obtained by swapping the first and the second character, and to get s3, we swap the third and the fourth character.

In the second example s1 is obtained by swapping the third and the fourth character in kbub, s2 — by swapping the second and the fourth, and s3 — by swapping the first and the third.

In the third example it's impossible to obtain given strings by aforementioned operations.
#include <bits/stdc++.h>
using namespace std;
const long long llmax = 9223372036854775807;
const long long llmin = -9223372036854775808;
const int intmin = -2147483648;
const int intmax = 2147483647;
const int mod = 1e9 + 7;
long long gcd(long long a, long long b) {
  if (a == 0 || b == 0)
    return a + b;
  else
    return gcd(b, a % b);
}
template <typename A, typename B>
inline A fexp(A x, B p) {
  A ans = 1;
  for (; p; p >>= 1, x = 1LL * x * x % mod)
    if (p & 1) ans = 1LL * ans * x % mod;
  return ans;
}
template <typename T>
inline void read(T& x) {
  x = 0;
  T f = 1;
  char ch;
  do {
    ch = getchar();
    if (ch == '-') f = -1;
  } while (ch < '0' || ch > '9');
  do x = x * 10 + ch - '0', ch = getchar();
  while (ch <= '9' && ch >= '0');
  x *= f;
}
class ST {
  struct Node {
    int l, r;
    long long sm, bjc, bjj;
    long long min;
    long long max;
    long long oor;
    long long andd;
  };
  vector<long long> A;
  vector<Node> T;

 public:
  ST(vector<long long>& AA) {
    A.emplace_back(0);
    for (int i = 0; i < AA.size(); i++) A.emplace_back(AA[i]);
    T.resize(A.size() << 2);
    build(1, 1, (int)A.size() - 1);
  }
  long long QuerySum(int l, int r) { return querySum(1, l, r); }
  long long QueryOr(int l, int r) { return queryOr(1, l, r); }
  long long QueryAnd(int l, int r) { return queryAnd(1, l, r); }
  long long QueryMax(int l, int r) { return queryMax(1, l, r); }
  long long QueryMin(int l, int r) { return queryMin(1, l, r); }
  void Add(int l, int r, long long x) { add(1, l, r, x); }
  void Mul(int l, int r, long long x) { mul(1, l, r, x); }

 private:
  void pushup(int i) {
    T[i].sm = T[i << 1].sm + T[i << 1 | 1].sm;
    T[i].min = min(T[i << 1].min, T[i << 1 | 1].min);
    T[i].max = max(T[i << 1].max, T[i << 1 | 1].max);
    T[i].oor = (T[i << 1].oor) | (T[i << 1 | 1].oor);
    T[i].andd = (T[i << 1].andd) & (T[i << 1 | 1].andd);
  }
  void mul(int i, long long x) {
    T[i].sm *= x;
    T[i].bjc *= x;
    T[i].bjj *= x;
  }
  void add(int i, long long x) {
    T[i].sm += x * (T[i].r - T[i].l + 1);
    T[i].bjj += x;
  }
  void pushdown(int i) {
    mul(i << 1, T[i].bjc);
    mul(i << 1 | 1, T[i].bjc);
    T[i].bjc = 1;
    add(i << 1, T[i].bjj);
    add(i << 1 | 1, T[i].bjj);
    T[i].bjj = 0;
  }
  void build(int i, int l, int r) {
    T[i].l = l;
    T[i].r = r;
    T[i].bjc = 1;
    if (l == r) {
      T[i].sm = A[l];
      T[i].min = A[l];
      T[i].max = A[l];
      T[i].oor = A[l];
      T[i].andd = A[l];
      return;
    }
    int M = l + r >> 1;
    build(i << 1, l, M);
    build(i << 1 | 1, M + 1, r);
    pushup(i);
  }
  long long querySum(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].sm;
    int M = T[i].l + T[i].r >> 1;
    long long ans = 0;
    pushdown(i);
    if (l <= M) ans += querySum(i << 1, l, r);
    if (r > M) ans += querySum(i << 1 | 1, l, r);
    return ans;
  }
  long long queryOr(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].oor;
    int M = T[i].l + T[i].r >> 1;
    long long ans = 0;
    pushdown(i);
    if (l <= M) ans = queryOr(i << 1, l, r);
    if (r > M) ans |= queryOr(i << 1 | 1, l, r);
    return ans;
  }
  long long queryAnd(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].andd;
    int M = T[i].l + T[i].r >> 1;
    long long ans = 0;
    pushdown(i);
    bool set = false;
    if (l <= M) ans = queryAnd(i << 1, l, r), set = true;
    if (r > M)
      ans =
          set ? (ans & queryAnd(i << 1 | 1, l, r)) : queryAnd(i << 1 | 1, l, r);
    return ans;
  }
  long long queryMax(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].max;
    int M = T[i].l + T[i].r >> 1;
    long long ans = llmin;
    pushdown(i);
    if (l <= M) ans = max(ans, queryMax(i << 1, l, r));
    if (r > M) ans = max(ans, queryMax(i << 1 | 1, l, r));
    return ans;
  }
  long long queryMin(int i, int l, int r) {
    if (l <= T[i].l && T[i].r <= r) return T[i].min;
    int M = T[i].l + T[i].r >> 1;
    long long ans = llmax;
    pushdown(i);
    if (l <= M) ans = min(ans, queryMin(i << 1, l, r));
    if (r > M) ans = min(ans, queryMin(i << 1 | 1, l, r));
    return ans;
  }
  void add(int i, int l, int r, long long x) {
    if (l <= T[i].l && T[i].r <= r) {
      add(i, x);
      return;
    }
    int M = T[i].l + T[i].r >> 1;
    pushdown(i);
    if (l <= M) add(i << 1, l, r, x);
    if (r > M) add(i << 1 | 1, l, r, x);
    pushup(i);
  }
  void mul(int i, int l, int r, long long x) {
    if (l <= T[i].l && T[i].r <= r) {
      mul(i, x);
      return;
    }
    int M = T[i].l + T[i].r >> 1;
    pushdown(i);
    if (l <= M) mul(i << 1, l, r, x);
    if (r > M) mul(i << 1 | 1, l, r, x);
    pushup(i);
  }
};
struct trip {
  trip(int _len, int _l, int _r) : len(_len), l(_l), r(_r){};
  int len;
  int l;
  int r;
};
struct MyClassLessThan {
  bool operator()(const trip& left, const trip& right) {
    return left.len < right.len;
  }
};
bool same2more = false;
bool isPossible(string& st1, string& st2) {
  vector<int> dif;
  for (int i = (0); i <= (st1.size() - 1); i++) {
    if (st1[i] != st2[i]) {
      dif.emplace_back(i);
    }
  }
  if (dif.size() == 0 && same2more)
    return true;
  else if (dif.size() == 2 && st1[dif[0]] == st2[dif[1]] &&
           st1[dif[1]] == st2[dif[0]])
    return true;
  else
    return false;
}
int freq[26];
int main() {
  bool test = false;
  if (test) freopen("/Users/aj/code/HackerRank/input.txt", "r", stdin);
  long long k, n;
  cin >> k >> n;
  vector<string> sts;
  for (int i = (1); i <= (k); i++) {
    string st;
    cin >> st;
    sts.emplace_back(st);
  }
  string& st1 = sts[0];
  vector<int> dif;
  int next = 1;
  for (int i = (1); i <= (st1.size()); i++) {
    freq[st1[i - 1] - 'a']++;
    if (freq[st1[i - 1] - 'a'] > 1) same2more = true;
  }
  while (next < k && dif.size() == 0) {
    string& st2 = sts[next];
    for (int i = (0); i <= (st1.size() - 1); i++) {
      if (st1[i] != st2[i]) {
        dif.emplace_back(i);
      }
    }
    next++;
  }
  vector<string> possiblests;
  if (dif.size() == 0) {
    swap(st1[0], st1[1]);
    cout << st1;
    return 0;
  } else if (dif.size() == 1) {
    cout << -1;
    return 0;
  } else if (dif.size() >= 2 && dif.size() <= 4) {
    possiblests.emplace_back(st1);
    for (int i = (0); i <= (dif.size() - 1); i++) {
      for (int j = (0); j <= (n - 1); j++) {
        int id1 = dif[i];
        int id2 = j;
        if (id1 == id2) continue;
        string st2 = st1;
        swap(st2[id1], st2[id2]);
        possiblests.emplace_back(st2);
      }
    }
  } else {
    cout << -1;
    return 0;
  }
  for (int s = (0); s <= (possiblests.size() - 1); s++) {
    string st = possiblests[s];
    bool good = true;
    for (int j = (1); j <= (k); j++) {
      if (!isPossible(st, sts[j - 1])) {
        good = false;
        break;
      }
    }
    if (good) {
      cout << st;
      return 0;
    }
  }
  cout << -1;
  return 0;
}
