Problem:
Score : 200 points

Problem Statement

You are given a string S of length N consisting of lowercase English letters.
We will cut this string at one position into two strings X and Y.
Here, we would like to maximize the number of different letters contained in both X and Y.
Find the largest possible number of different letters contained in both X and Y when we cut the string at the optimal position.

Constraints

2 \leq N \leq 100

|S| = N

S consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the largest possible number of different letters contained in both X and Y.

Sample Input 1

6
aabbca

Sample Output 1

2

If we cut the string between the third and fourth letters into X = aab and Y = bca, the letters contained in both X and Y are a and b.
There will never be three or more different letters contained in both X and Y, so the answer is 2.

Sample Input 2

10
aaaaaaaaaa

Sample Output 2

1

However we divide S, only a will be contained in both X and Y.

Sample Input 3

45
tgxgdqkyjzhyputjjtllptdfxocrylqfqjynmfbfucbir

Sample Output 3

9

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;

namespace Contest
{
  class Program
  {
    static void Main(string[] args)
    {
      ABC098.B();
    }
    class ABC102
    {
      public static void A()
      {
        var N = Read.Long();
        Console.WriteLine(N % 2 == 0 ? N : N * 2);
      }
      public static void B()
      {
        var N = Read.Int();
        var A = Read.LongN();
        Console.WriteLine(A.Max() - A.Min());
      }
    }
    class ABC101
    {
      public static void A()
      {
        var S = Read.Str();
        Console.WriteLine(S.Count(x => x == '+') * 2 - 4);
      }
      public static void B()
      {
        var N = Read.Long();
        long k = 0;
        long v = N;
        while (v > 0) { k += v % 10;v /= 10; }
        Console.WriteLine(N % k == 0 ? "Yes" : "No");
      }
    }
    class ABC098
    {
      public static void A()
      {
        var A = Read.Int();
        var B = Read.Int();
        Console.WriteLine(Math.Max(A + B, Math.Max(A - B, A * B)));
      }
      public static void B()
      {
        var N = Read.Int();
        var S = Read.Str();
        int max = 0;
        for(int i = 1; i < N; ++i)
        {
          var f1 = Util.Frequency(S.Substring(0, i).ToArray());
          var f2 = Util.Frequency(S.Substring(i).ToArray());
          int count = Enumerable.Range(0, 26).Count(j => f1.ContainsKey((char)('a' + j)) && f2.ContainsKey((char)('a' + j)));
          max = Math.Max(max, count);
        }
        Console.WriteLine(max);
      }
    }
    class ABC097
    {
      public static void A()
      {
        var A = Read.Int();
        var B = Read.Int();
        var C = Read.Int();
        var D = Read.Int();
        Console.WriteLine(Math.Abs(A - C) <= D || (Math.Abs(A - B) <= D && Math.Abs(B - C) <= D) ? "Yes" : "No");
      }
      public static void B()
      {
        var X = Read.Int();
        HashSet<int> beki = new HashSet<int>();
        beki.Add(1);
        for(int i = 2; i <= 32; ++i)
        {
          var v = i * i;
          while (v <= 1000)
          {
            if (!beki.Contains(v)) { beki.Add(v); }
            v *= i;
          }
        }
        for(int i = X; i > 0; --i)
        {
          if (beki.Contains(i)) { Console.WriteLine(i); return; }
        }
      }
    }
    class ABC095
    {
      public static void A()
      {
        var S = Read.Str();
        Console.WriteLine(700 + S.Count(x => x == 'o') * 100);
      }
      public static void B()
      {
        var N = Read.Int();
        var X = Read.Int();
        var M = Enumerable.Range(0, N).Select(i => Read.Int()).ToArray();
        var sum = M.Sum();
        var min = M.Min();
        Console.WriteLine(N + (X - sum) / min);
      }
    }
    class ABC094
    {
      public static void A()
      {
        var A = Read.Int();
        var B = Read.Int();
        var X = Read.Int();
        Console.WriteLine(A <= X && X <= A + B ? "YES" : "NO");
      }
      public static void B()
      {
        var N = Read.Int();
        var M = Read.Int();
        var X = Read.Int();
        var A = Read.IntN();
        int c1 = 0, c2 = 0;
        foreach(var a in A)
        {
          if (a < X) { c1++; } else { c2++; }
        }
        Console.WriteLine(Math.Min(c1, c2));
      }
    }
    class ABC093
    {
      public static void A()
      {
        var S = Read.Str();
        Console.WriteLine(S.Contains("a") && S.Contains("b") && S.Contains("c") ? "Yes" : "No");
      }
      public static void B()
      {
        var A = Read.Int();
        var B = Read.Int();
        var K = Read.Int();
        HashSet<int> hash = new HashSet<int>();
        for(int i = 0; i < K; ++i)
        {
          var a = A + i;
          if(!hash.Contains(a) && a <= B) { hash.Add(a); }
          var b = B - i;
          if(!hash.Contains(b) && A <= b) { hash.Add(b); }
        }
        Console.WriteLine(String.Join(Environment.NewLine, hash.OrderBy(x => x)));
      }
    }
    class ABC092
    {
      public static void A()
      {
        var A = Read.Int();
        var B = Read.Int();
        var C = Read.Int();
        var D = Read.Int();
        Console.WriteLine(Math.Min(A, B) + Math.Min(C, D));
      }
      public static void B()
      {
        var N = Read.Int();
        var D = Read.Int();
        var X = Read.Int();
        var A = Enumerable.Range(0, N).Select(i => Read.Int()).ToArray();
        int ans = X;
        for(int i = 0; i < D; ++i)
        {
          foreach(var a in A)
          {
            if (i % a == 0) { ans++; }
          }
        }
        Console.WriteLine(ans);
      }
    }
    class ABC091
    {
      public static void A()
      {
        var A = Read.Int();
        var B = Read.Int();
        var C = Read.Int();
        Console.WriteLine(A + B >= C ? "Yes" : "No");
      }
      public static void B()
      {
        var N = Read.Int();
        var S = Enumerable.Range(0, N).Select(i => Read.Str()).ToArray();
        var M = Read.Int();
        var T = Enumerable.Range(0, M).Select(i => Read.Str()).ToArray();
        int max = 0;
        foreach(var s in S)
        {
          var score = S.Count(x => x == s) - T.Count(x => x == s);
          max = Math.Max(max, score);
        }
        Console.WriteLine(max);
      }
    }
    class ABC090
    {
      public static void A()
      {
        var C1 = Read.Str();
        var C2 = Read.Str();
        var C3 = Read.Str();
        Console.WriteLine("{0}{1}{2}", C1[0], C2[1], C3[2]);
      }
      public static void B()
      {
        var A = Read.Int();
        var B = Read.Int();
        Func<int, bool> isPar = X =>
        {
          var S = X.ToString();
          return S[0] == S[4] && S[1] == S[3];
        };
        Console.WriteLine(Enumerable.Range(A, B - A + 1).Count(x => isPar(x)));
      }
    }
    class ABC087
    {
      public static void A()
      {
        var X = Read.Int();
        var A = Read.Int();
        var B = Read.Int();
        Console.WriteLine((X - A) % B);
      }
      public static void B()
      {
        var A = Read.Int();
        var B = Read.Int();
        var C = Read.Int();
        var X = Read.Int();
        int count = 0;
        for(int i = 0; i <= A; ++i)
        {
          for(int j = 0; j <= B; ++j)
          {
            var res = X - i * 500 - j * 100;
            if(0<=res && res <= C * 50) { count++; }
          }
        }
        Console.WriteLine(count);
      }
    }
    class ABC086
    {
      public static void A()
      {
        var A = Read.Int();
        var B = Read.Int();
        Console.WriteLine(A * B % 2 == 0 ? "Even" : "Odd");
      }
      public static void B()
      {
        var A = Read.Str();
        var B = Read.Str();
        var X = Convert.ToInt32(A + B);
        for(int i = 0; i < 400; ++i)
        {
          if (i * i == X) { Console.WriteLine("Yes");return; }
        }
        Console.WriteLine("No");
      }
    }
    class ABC083
    {
      public static void A()
      {
        var A = Read.Int();
        var B = Read.Int();
        var C = Read.Int();
        var D = Read.Int();
        var X = A + B - C - D;
        Console.WriteLine(X > 0 ? "Left" : X < 0 ? "Right" : "Balanced");
      }
      public static void B()
      {
        var N = Read.Int();
        var A = Read.Int();
        var B = Read.Int();
        Func<int, int> keta = X =>
        {
          int x = 0;
          while (X > 0) { x += X % 10; X /= 10; }
          return x;
        };
        int sum = 0;
        for(int i = 1; i <= N; ++i)
        {
          var k = keta(i);
          sum += A <= k && k <= B ? i : 0;
        }
        Console.WriteLine(sum);
      }
    }
    class ABC082
    {
      public static void A()
      {
        var A = Read.Int();
        var B = Read.Int();
        Console.WriteLine((A + B + 1) / 2);
      }
      public static void B()
      {
        var S = Read.Str();
        var T = Read.Str();
        S = new string(S.ToArray().OrderBy(x => x).ToArray());
        T = new string(T.ToArray().OrderBy(x => -x).ToArray());
        Console.WriteLine(S.CompareTo(T) < 0 ? "Yes" : "No");
      }
    }
    class ABC081
    {
      public static void A()
      {
        var S = Read.Str();
        Console.WriteLine(S.Count(x => x == '1'));
      }
      public static void B()
      {
        var N = Read.Int();
        var A = Read.IntN();
        Func<int, int> pow2 = X =>
        {
          int count = 0;
          while (X % 2 == 0) { count++; X /= 2; }
          return count;
        };
        Console.WriteLine(A.Select(x => pow2(x)).Min());
      }
    }

    class Util
    {
      public static Dictionary<T, long> Frequency<T>(T[] array)
      {
        var dict = new Dictionary<T, long>();
        foreach (var a in array)
        {
          if (!dict.ContainsKey(a)) { dict.Add(a, 0); }
          dict[a]++;
        }
        return dict;
      }
    }

    static class Read
{
static Queue<string> queue = new Queue<string>();
static void Enqueue() { var ss = Console.ReadLine().Split(' '); foreach (var s in ss) { queue.Enqueue(s); } }
public static int Int() { if (queue.Count == 0) { Enqueue(); } return Convert.ToInt32(queue.Dequeue()); }
public static long Long() { if (queue.Count == 0) { Enqueue(); } return Convert.ToInt64(queue.Dequeue()); }
public static string Str() { if (queue.Count == 0) { Enqueue(); } return queue.Dequeue(); }
public static int[] IntN() { return Console.ReadLine().Split(' ').Select(s => Convert.ToInt32(s)).ToArray(); }
public static long[] LongN() { return Console.ReadLine().Split(' ').Select(s => Convert.ToInt64(s)).ToArray(); }
public static ulong[] ULongN() { return Console.ReadLine().Split(' ').Select(s => Convert.ToUInt64(s)).ToArray(); }
public static string[] StrN() { return Console.ReadLine().Split(' '); }
public static Tuple<int, int>[] TupleInt(int n) { List<Tuple<int, int>> list = new List<Tuple<int, int>>(); for (int i = 0; i < n; ++i) { var ab = Read.IntN(); list.Add(new Tuple<int, int>(ab[0], ab[1])); } return list.ToArray(); }
public static Tuple<long, long>[] TupleLong(int n) { List<Tuple<long, long>> list = new List<Tuple<long, long>>(); for (int i = 0; i < n; ++i) { var ab = Read.LongN(); list.Add(new Tuple<long, long>(ab[0], ab[1])); } return list.ToArray(); }
public static Tuple<string, string>[] TupleStr(int n) { List<Tuple<string, string>> list = new List<Tuple<string, string>>(); for (int i = 0; i < n; ++i) { var ab = Read.StrN(); list.Add(new Tuple<string, string>(ab[0], ab[1])); } return list.ToArray(); }
public static Tuple<double, double>[] TupleDouble(int n) { List<Tuple<double, double>> list = new List<Tuple<double, double>>(); for (int i = 0; i < n; ++i) { var ab = Read.LongN(); list.Add(new Tuple<double, double>(ab[0], ab[1])); } return list.ToArray(); }
public static long[,] LongMatrix(int r, int c) { var mat = new long[r, c]; for (int i = 0; i < r; ++i) { var x = Read.LongN(); for (int j = 0; j < c; ++j) { mat[i, j] = x[j]; } } return mat; }
public static Dictionary<int, HashSet<int>> AdjacencyList(int N, int M, bool isDirectional = false)
{
Dictionary<int, HashSet<int>> dict = new Dictionary<int, HashSet<int>>();
for (int i = 0; i <= N; ++i) { dict.Add(i, new HashSet<int>()); }
        for (int i = 0; i < M; ++i) { var ab = Read.IntN(); if (!dict[ab[0]].Contains(ab[1])) { dict[ab[0]].Add(ab[1]); } if (!isDirectional && !dict[ab[1]].Contains(ab[0])) { dict[ab[1]].Add(ab[0]); } }
        return dict;
}
public static Dictionary<int, Dictionary<int, long>> AdjacencyListWithWeight(int N, int M)
{
Dictionary<int, Dictionary<int, long>> dict = new Dictionary<int, Dictionary<int, long>>(); for (int i = 0; i <= N; ++i) { dict.Add(i, new Dictionary<int, long>()); }
for (int i = 0; i < M; ++i) { var ab = Read.IntN(); dict[ab[0]].Add(ab[1], ab[2]); dict[ab[1]].Add(ab[0], ab[2]); }
return dict;
}
}
    }
}