#include <bits/stdc++.h>
namespace Quick {
class InStream {
 private:
  char buf[1 << 21], *p1, *p2, failed;
  inline char getc() {
    return p1 == p2 &&
                   (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
               ? EOF
               : *p1++;
  }
  template <class Type>
  inline int read(Type &x) {
    bool k = false;
    char c = getc();
    for (; !isdigit(c); c = getc()) {
      k |= (c == '-');
      if (c == EOF) return 0;
    }
    x = 0;
    for (; isdigit(c); c = getc()) x = (x << 1) + (x << 3) + (c ^ 48);
    return 1;
  }
  inline int read(char *a) {
    *a = getc();
    for (; isspace(*a) || *a == EOF; *a = getc())
      if (*a == EOF) return 0;
    for (; !isspace(*a) && *a != EOF; *a = getc()) a++;
    *a = '\0';
    return 1;
  }

 public:
  operator int() const { return ~failed; }
  InStream() {
    p1 = p2 = buf;
    failed = 0x00;
  }
  ~InStream() {}
  template <class Type>
  InStream &operator>>(Type &&x) {
    if (read(x))
      failed = 0x00;
    else
      failed = 0xff;
    return *this;
  }
} cin;
class OutStream {
 private:
  char buf[1 << 21];
  int p1;
  const int p2 = 1 << 21;
  inline void flush() {
    fwrite(buf, 1, p1, stdout);
    p1 = 0;
  }
  inline void putc(const char &c) {
    if (p1 == p2) flush();
    buf[p1++] = c;
  }
  template <class Type>
  inline void write(Type x) {
    static char buf[25];
    int p = -1;
    if (x < 0) {
      x *= -1;
      putc('-');
    }
    if (x == 0)
      putc('0');
    else
      for (; x; x /= 10) buf[++p] = x % 10 + 48;
    while (~p) putc(buf[p--]);
  }
  inline void write(char *a) {
    for (; *a; a++) putc(*a);
  }
  inline void write(const char *a) {
    for (; *a; a++) putc(*a);
  }
  inline void write(const char &c) { putc(c); }

 public:
  OutStream() { p1 = 0; }
  ~OutStream() { flush(); }
  template <class Type>
  OutStream &operator<<(const Type &x) {
    write(x);
    return *this;
  }
} cout;
const char endl('\n');
template <class Type>
inline Type max(const Type &a, const Type &b) {
  if (a < b) return b;
  return a;
}
template <class Type>
inline Type min(const Type &a, const Type &b) {
  if (a < b) return a;
  return b;
}
template <class Type>
inline void swap(Type &a, Type &b) {
  static Type tmp;
  tmp = a;
  a = b;
  b = tmp;
}
template <class Type>
inline Type abs(const Type &a) {
  return a >= 0 ? a : -a;
}
}  // namespace Quick
using namespace Quick;
const int maxn(1e5 + 10), maxm(1 << 9), inf(0x3f3f3f3f);
char s[maxn];
int n, a[maxn];
int posd[maxn][8], alpd[8][8];
void Bfs(const int &p) {
  static std::queue<int> q;
  for (int i(1); i <= n; i++)
    if (a[i] != p)
      posd[i][p] = inf;
    else
      q.push(i);
  while (!q.empty()) {
    int u(q.front());
    q.pop();
    if (posd[u + 1][p] == inf) {
      posd[u + 1][p] = posd[u][p] + 1;
      q.push(u + 1);
    }
    if (posd[u - 1][p] == inf) {
      posd[u - 1][p] = posd[u][p] + 1;
      q.push(u - 1);
    }
  }
}
int mask[maxn];
int cnt[8][maxm];
int ansval;
long long anscnt;
inline void update(const int &val, const long long &cnt) {
  if (val == ansval)
    anscnt += cnt;
  else if (val > ansval)
    ansval = val, anscnt = cnt;
}
int main(void) {
  cin >> n >> (s + 1);
  for (int i(1); i <= n; i++) a[i] = s[i] - 'a';
  for (int i(0); i < 8; i++) Bfs(i);
  memset(alpd, 0x3f, sizeof alpd);
  for (int i(0); i < 8; i++) alpd[i][i] = 0;
  for (int k(1); k <= n; k++)
    for (int i(0); i < 8; i++)
      for (int j(0); j < 8; j++)
        alpd[i][j] = min(alpd[i][j], posd[k][i] + posd[k][j]);
  for (int k(0); k < 8; k++)
    for (int i(0); i < 8; i++)
      for (int j(0); j < 8; j++)
        alpd[i][j] = min(alpd[i][j], alpd[i][k] + alpd[k][j] + 1);
  for (int i(1); i <= n; i++)
    for (int j(0); j < 8; j++)
      for (int k(0); k < 8; k++)
        posd[i][k] = min(posd[i][k], posd[i][j] + alpd[j][k] + 1);
  for (int i(1); i <= n; i++)
    for (int j(0); j < 8; j++) mask[i] |= (posd[i][j] - alpd[a[i]][j]) << j;
  for (int i(1); i <= n; i++)
    for (int j(max(1, i - 15)); j < i; j++) {
      int dist(i - j);
      for (int c(0); c < 8; c++) dist = min(dist, posd[i][c] + posd[j][c] + 1);
      update(dist, 1);
    }
  for (int i(17); i <= n; i++) {
    cnt[a[i - 16]][mask[i - 16]]++;
    for (int c(0); c < 8; c++)
      for (int st(0); st < 256; st++)
        if (cnt[c][st]) {
          int dist(inf);
          for (int k(0); k < 8; k++)
            dist = min(dist, posd[i][k] + alpd[c][k] + ((st >> k) & 1) + 1);
          update(dist, cnt[c][st]);
        }
  }
  cout << ansval << ' ' << anscnt << endl;
  return 0;
}
