#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MIN_L = 3;
const int MAX_L = 10;
const int MAX_C = 62;
const int MOD = 998244353;
int char_to_int(char c) {
  if (c >= 'a' && c <= 'z') return c - 'a';
  if (c >= 'A' && c <= 'Z') return 26 + c - 'A';
  return 52 + c - '0';
}
struct node {
  bool is_end;
  node *children[MAX_C];
  bool find(string &s, int index) {
    if (index == s.size()) return is_end;
    int char_index = char_to_int(s[index]);
    if (children[char_index] == nullptr) return false;
    return children[char_index]->find(s, index + 1);
  }
  void insert(string &s, int index) {
    if (index == s.size()) {
      is_end = true;
      return;
    }
    int char_index = char_to_int(s[index]);
    if (children[char_index] == nullptr) children[char_index] = new node();
    children[char_index]->insert(s, index + 1);
  }
};
int n;
vector<string> words[MAX_L + 1];
node trie;
int cnt[MAX_L + 1][MAX_C][MAX_C];
ll triplet[MAX_L + 1][MAX_C][MAX_C][MAX_C];
int fact[5] = {1, 1, 2, 6, 24};
int cmp(string &s, int l) {
  for (int i = 0; i < l; ++i) {
    int a = char_to_int(s[i]);
    int b = char_to_int(s[l - i - 1]);
    if (a < b) return -1;
    if (a > b) return 1;
  }
  return 0;
}
bool is_palindrome(string &s, int l) {
  for (int i = 0; i < l; ++i)
    if (s[i] != s[l - i - 1]) return false;
  return true;
}
ll get_triplets(int l, int a, int b, int c, int d) {
  ll r1 = triplet[l][a][b][c] * triplet[l][a][b][d];
  ll r2 = triplet[l][a][c][d] * triplet[l][b][c][d];
  if (r1 >= MOD) r1 %= MOD;
  if (r2 >= MOD) r2 %= MOD;
  int k = 1, tmp = 1;
  if (a == b) ++tmp;
  if (b == c)
    ++tmp;
  else {
    k *= fact[tmp];
    tmp = 1;
  }
  if (c == d) ++tmp;
  k *= fact[tmp];
  k = fact[4] / k;
  ll r = r1 * r2;
  if (r >= MOD) r %= MOD;
  r *= k;
  if (r >= MOD) r %= MOD;
  return r;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  for (int i = 0; i < n; ++i) {
    string tmp;
    cin >> tmp;
    words[tmp.length()].push_back(tmp);
  }
  ll ans = 0LL;
  for (int l = MIN_L; l <= MAX_L; ++l) {
    for (int i = 0; i < words[l].size(); ++i) {
      int a = char_to_int(words[l][i][0]), b = char_to_int(words[l][i][l - 1]);
      int c = cmp(words[l][i], l);
      if (c == 1) reverse(words[l][i].begin(), words[l][i].end());
      if (trie.find(words[l][i], 0)) continue;
      cnt[l][a][b]++;
      if (c != 0) cnt[l][b][a]++;
      trie.insert(words[l][i], 0);
    }
    for (int i = 0; i < MAX_C; ++i)
      for (int j = i; j < MAX_C; ++j)
        for (int k = j; k < MAX_C; ++k)
          for (int c = 0; c < MAX_C; ++c) {
            triplet[l][i][j][k] +=
                (ll)cnt[l][c][i] * cnt[l][c][j] * cnt[l][c][k];
            if (triplet[l][i][j][k] >= MOD) triplet[l][i][j][k] %= MOD;
          }
    for (int a = 0; a < MAX_C; ++a)
      for (int b = a; b < MAX_C; ++b)
        for (int c = b; c < MAX_C; ++c)
          for (int d = c; d < MAX_C; ++d) {
            ans += get_triplets(l, a, b, c, d);
            if (ans >= MOD) ans %= MOD;
          }
  }
  cout << ans << "\n";
  return 0;
}
