A substring of some string is called the most frequent, if the number of its occurrences is not less than number of occurrences of any other substring.

You are given a set of strings. A string (not necessarily from this set) is called good if all elements of the set are the most frequent substrings of this string. Restore the non-empty good string with minimum length. If several such strings exist, restore lexicographically minimum string. If there are no good strings, print "NO" (without quotes).

A substring of a string is a contiguous subsequence of letters in the string. For example, "ab", "c", "abc" are substrings of string "abc", while "ac" is not a substring of that string.

The number of occurrences of a substring in a string is the number of starting positions in the string where the substring occurs. These occurrences could overlap.

String a is lexicographically smaller than string b, if a is a prefix of b, or a has a smaller letter at the first position where a and b differ.

Input

The first line contains integer n (1 ≤ n ≤ 105) — the number of strings in the set.

Each of the next n lines contains a non-empty string consisting of lowercase English letters. It is guaranteed that the strings are distinct.

The total length of the strings doesn't exceed 105.

Output

Print the non-empty good string with minimum length. If several good strings exist, print lexicographically minimum among them. Print "NO" (without quotes) if there are no good strings.

Examples

Input

4
mail
ai
lru
cf


Output

cfmailru


Input

3
kek
preceq
cheburek


Output

NO

Note

One can show that in the first sample only two good strings with minimum length exist: "cfmailru" and "mailrucf". The first string is lexicographically minimum.
#include <bits/stdc++.h>
class AcyclicCharPathWithMultipleComponents {
 public:
  bool isCorrupted() { return corrupted; }
  bool addLeaf(char c) { return addEdge(c, EOS); }
  bool addEdge(char from, char to) {
    char root;
    if (notInGraph(from)) {
      root = from;
      roots.insert(root);
    } else
      root = forward[from].r;
    if (notInGraph(from))
      forward[from] = charNroot{to, root};
    else if (forward[from].c == EOS) {
      forward[from].c = to;
      forward[from].r = root;
    } else if (forward[from].c != to && to != EOS) {
      corrupted = true;
      std::cerr << "Branching: '" << from << "' leads to '" << forward[from].c
                << "' and to '" << to << "'" << std::endl;
    }
    if (isInGraph(to)) {
      char tosRoot = forward[to].r;
      if (tosRoot != root)
        if (to != tosRoot) {
          corrupted = true;
          std::cerr << "Intersection: '" << root << "' intersects '" << tosRoot
                    << "' in '" << to << "'" << std::endl;
        } else {
          roots.erase(tosRoot);
          backward[to] = from;
          char lfrom = to;
          do {
            forward[lfrom].r = root;
            lfrom = forward[lfrom].c;
          } while (lfrom != EOS);
        }
      else if (to == tosRoot) {
        corrupted = true;
        std::cerr << "Cycle: '" << from << "' leads to root '" << tosRoot << "'"
                  << std::endl;
      } else if (backward[to] != from) {
        corrupted = true;
        std::cerr << "Self-intersection: '" << root << "' selfintersects in '"
                  << from << "' leading to '" << to << "'" << std::endl;
      }
    } else if (to != EOS) {
      backward[to] = from;
      forward[to] = charNroot{EOS, root};
    }
    return corrupted;
  }
  void printMin() {
    if (corrupted) {
      std::cout << "NO";
      return;
    }
    for (auto root = roots.begin(); root != roots.end(); ++root) {
      char from = *root, to;
      do {
        to = forward[from].c;
        std::cout << from;
        from = to;
      } while (from != EOS);
    }
  }

 private:
  struct charNroot {
    char c;
    char r;
  };
  std::map<char, charNroot> forward;
  std::map<char, char> backward;
  std::set<char> roots;
  bool corrupted = false;
  static constexpr char EOS = '1';
  bool notInGraph(char c) { return forward.find(c) == forward.end(); }
  bool isInGraph(char c) { return !notInGraph(c); }
};
int main() {
  AcyclicCharPathWithMultipleComponents graph;
  int n;
  std::cin >> n;
  std::string str;
  for (int i = 0; i < n; ++i) {
    std::cin >> str;
    if (!graph.isCorrupted()) {
      char key = str[0], value;
      std::string::iterator it;
      for (it = str.begin() + 1; it != str.end(); ++it) {
        value = *it;
        if (graph.addEdge(key, value)) break;
        key = value;
      }
      graph.addLeaf(key);
    }
  }
  graph.printMin();
  return 0;
}
