Have you ever played Hanabi? If not, then you've got to try it out! This problem deals with a simplified version of the game.Overall, the game has 25 types of cards (5 distinct colors and 5 distinct values). Borya is holding n cards. The game is somewhat complicated by the fact that everybody sees Borya's cards except for Borya himself. Borya knows which cards he has but he knows nothing about the order they lie in. Note that Borya can have multiple identical cards (and for each of the 25 types of cards he knows exactly how many cards of this type he has).The aim of the other players is to achieve the state when Borya knows the color and number value of each of his cards. For that, other players can give him hints. The hints can be of two types: color hints and value hints. A color hint goes like that: a player names some color and points at all the cards of this color. Similarly goes the value hint. A player names some value and points at all the cards that contain the value.Determine what minimum number of hints the other players should make for Borya to be certain about each card's color and value.

The first line contains integer n (1 ≤ n ≤ 100) — the number of Borya's cards. The next line contains the descriptions of n cards. The description of each card consists of exactly two characters. The first character shows the color (overall this position can contain five distinct letters — R, G, B, Y, W). The second character shows the card's value (a digit from 1 to 5). Borya doesn't know exact order of the cards they lie in.

Print a single integer — the minimum number of hints that the other players should make.

NoteIn the first sample Borya already knows for each card that it is a green three.In the second sample we can show all fours and all red cards.In the third sample you need to make hints about any four colors.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Borya_and_Hanabi
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            int n = int.Parse(reader.ReadLine());
            string[] ss = reader.ReadLine().Split(' ');

            var nn = new int[5,5];

            for (int i = 0; i < n; i++)
            {
                int n2 = ss[i][1] - '1';
                int n1 = -1;
                switch (ss[i][0])
                {
                    case 'R':
                        n1 = 0;
                        break;
                    case 'G':
                        n1 = 1;
                        break;
                    case 'B':
                        n1 = 2;
                        break;
                    case 'Y':
                        n1 = 3;
                        break;
                    case 'W':
                        n1 = 4;
                        break;
                }
                nn[n1, n2] = 1;
            }

            int min = 8;

            for (int i = 0; i < 32; i++)
            {
                int bi = Bitcount(i);
                if (bi >= min)
                    continue;

                for (int j = 0; j < 32; j++)
                {
                    int bj = Bitcount(j);
                    if (bi + bj >= min)
                        continue;

                    var mask = new int[5,5];

                    for (int k = 0; k < 5; k++)
                    {
                        if ((i & (1 << k)) != 0)
                        {
                            for (int l = 0; l < 5; l++)
                            {
                                if (nn[k, l] != 0)
                                {
                                    mask[k, l] |= 1 << (k+6);
                                }
                            }
                        }
                    }

                    for (int k = 0; k < 5; k++)
                    {
                        if ((j & (1 << k)) != 0)
                        {
                            for (int l = 0; l < 5; l++)
                            {
                                if (nn[l, k] != 0)
                                {
                                    mask[l, k] |= 1 << k;
                                }
                            }
                        }
                    }

                    var list = new List<int>();
                    for (int k = 0; k < 5; k++)
                    {
                        for (int l = 0; l < 5; l++)
                        {
                            if (nn[k, l] != 0)
                            {
                                list.Add(mask[k, l]);
                            }
                        }
                    }
                    list.Sort();
                    bool f = false;
                    for (int k = 1; k < list.Count; k++)
                    {
                        if (list[k - 1] == list[k])
                        {
                            f = true;
                            break;
                        }
                    }
                    if (!f)
                    {
                        if (bi + bj < min)
                            min = bi + bj;
                    }
                }
            }

            writer.WriteLine(min);
            writer.Flush();
        }

        private static int Bitcount(int n)
        {
            int count = 0;
            do
            {
                if ((n & 1) == 1)
                    count++;
                n >>= 1;
            } while (n > 0);
            return count;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

// (づ*ω*)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    int BitCount(int x)
    {
        int ret = 0;
        while (x > 0)
        {
            ret++;
            x &= x - 1;
        }
        return ret;
    }

    public object Solve()
    {
        int n = ReadInt();
        var cards = new Tuple<int, int>[n];
        for (int i = 0; i < n; i++)
        {
            var t = ReadToken();
            cards[i] = Tuple.Create("RGBYW".IndexOf(t[0]) + 5, t[1] - '1');
        }
        cards = cards.Distinct().ToArray();
        n = cards.Length;

        int ans = 15;
        for (int k = 0; k < 2 << 10; k++)
        {
            bool ok = true;
            for (int i = 0; i < n && ok; i++)
                for (int j = i + 1; j < n && ok; j++)
                    if (cards[i].ToString() != cards[j].ToString())
                    {
                        ok = false;
                        if (cards[i].Item1 != cards[j].Item1 && ((k >> cards[i].Item1 & 1) == 1 || (k >> cards[j].Item1 & 1) == 1))
                            ok = true;
                        if (cards[i].Item2 != cards[j].Item2 && ((k >> cards[i].Item2 & 1) == 1 || (k >> cards[j].Item2 & 1) == 1))
                            ok = true;
                    }
            if (ok)
                ans = Math.Min(ans, BitCount(k));
        }

        return ans;
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = Console.In;
        writer = new StreamWriter(Console.OpenStandardOutput());
#endif
        try
        {
            var ts = DateTime.Now;
            object result = new Solver().Solve();
            if (result != null)
                writer.WriteLine(result);
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read/Write

    private static Queue<string> currentLineTokens = new Queue<string>();

    private static string[] ReadAndSplitLine()
    {
        return reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public static string ReadToken()
    {
        while (currentLineTokens.Count == 0)
            currentLineTokens = new Queue<string>(ReadAndSplitLine());
        return currentLineTokens.Dequeue();
    }

    public static int ReadInt()
    {
        return int.Parse(ReadToken());
    }

    public static long ReadLong()
    {
        return long.Parse(ReadToken());
    }

    public static double ReadDouble()
    {
        return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
    }

    public static int[] ReadIntArray()
    {
        return ReadAndSplitLine().Select(int.Parse).ToArray();
    }

    public static long[] ReadLongArray()
    {
        return ReadAndSplitLine().Select(long.Parse).ToArray();
    }

    public static double[] ReadDoubleArray()
    {
        return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
    }

    public static int[][] ReadIntMatrix(int numberOfRows)
    {
        int[][] matrix = new int[numberOfRows][];
        for (int i = 0; i < numberOfRows; i++)
            matrix[i] = ReadIntArray();
        return matrix;
    }

    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows);
        int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = new int[numberOfRows];
            for (int j = 0; j < numberOfRows; j++)
                ret[i][j] = matrix[j][i];
        }
        return ret;
    }

    public static string[] ReadLines(int quantity)
    {
        string[] lines = new string[quantity];
        for (int i = 0; i < quantity; i++)
            lines[i] = reader.ReadLine().Trim();
        return lines;
    }

    public static void WriteArray<T>(IEnumerable<T> array)
    {
        writer.WriteLine(string.Join(" ", array));
    }

    #endregion
}

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

public class Test
{
    [Flags]
    enum Card
    {
        R = 1 << 0,
        G = 1 << 1,
        B = 1 << 2,
        Y = 1 << 3,
        W = 1 << 4,
        One = 1 << 5,
        Two = 1 << 6,
        Three = 1 << 7,
        Four = 1 << 8,
        Five = 1 << 9,
    }

    public static void Main()
    {
        int result = Solve();
        Console.WriteLine(result);
    }

    static int Solve()
    {

        // Don't care for n
        Console.ReadLine();

        var input = Console.ReadLine().Split(' ').Distinct().Select(x => ParseCard(x)).ToArray();
        if (input.Length == 1)
        {
            return 0;
        }
        List<Card> diffs = new List<Card>(input.Length * input.Length);
        for(int i = 0; i < input.Length - 1; i++)
        {
            for(int j = i + 1; j < input.Length; j++)
            {
                Card diff = Diff(input[i], input[j]);
                diffs.Add(diff);
            }
        }

        var subsets = Enumerable.Range(0, 1023).Select(x => (Card)x);
        int min = 11;
        foreach(var subset in subsets)
        {
            if(diffs.All(x => CanDistinguish(subset, x)))
            {
                // This is an answer
                min = Math.Min(min, CountBits((int)subset));
            }
        }

        return min;
    }

    static int CountBits(int num)
    {
        int res = 0;
        while(num > 0)
        {
            if ((num & 1) == 1) res++;
            num >>= 1;
        }
        return res;
    }

    static bool CanDistinguish(Card subset, Card diff)
    {
        return (subset & diff) != 0;
    }

    static Card Diff(Card f, Card s)
    {
        return f ^ s;
    }

    static Card ParseCard(string input)
    {
        Card colour = (Card)Enum.Parse(typeof(Card), input[0].ToString());
        Card num = Card.One;
        switch (input[1])
        {
            case '1': num = Card.One;break;
            case '2': num = Card.Two;break;
            case '3': num = Card.Three;break;
            case '4': num = Card.Four;break;
            case '5': num = Card.Five;break;
        }
        return colour | num;
    }
}

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static bool[,] M;
        static int[,] N;
        static bool[] C;

        static void Main()
        {
            M = new bool[5,5];
            N = new int[5,5];
            C = new bool[10];

            string l = "RGBYW";
            int times = int.Parse(Console.ReadLine());
            string[] p = Console.ReadLine().Split();
            for (int i = 0; i < times; ++i)
            {
                string s = p[i];
                int t = -1;
                for (int j = 0; j < 5; ++j)
                {
                    if (s[0] == l[j])
                        t = j;
                }
                M[t,int.Parse(s[1].ToString()) - 1] = true;
            }
            Console.WriteLine(BT(0));
        }

        static int BT(int level)
        {
            if (valid())
                return level;

            int num = (int)Math.Pow(2, level);
            int pistas = 20;
            for (int i = 0; i < 10; ++i)
            {
                if (!C[i])
                {
                    C[i] = true;
                    if (i / 5 == 0)
                    {
                        for (int j = 0; j < 5; ++j)
                        {
                            N[i, j] += num;
                        }
                    }
                    else
                    {
                        for (int j = 0; j < 5; ++j)
                        {
                            N[j , i - 5] += num;
                        }
                    }
                    int cur_pistas = BT(level + 1);

                    if (cur_pistas < pistas)
                        pistas = cur_pistas;

                    C[i] = false;
                    if (i / 5 == 0)
                    {
                        for (int j = 0; j < 5; ++j)
                        {
                            N[i, j] -= num;
                        }
                    }
                    else
                    {
                        for (int j = 0; j < 5; ++j)
                        {
                            N[j, i - 5] -= num;
                        }
                    }

                }
            }
            return pistas;
        }

        static bool valid()
        {
            bool[] q = new bool[4000];
            for (int i = 0; i < 5; ++i)
            {
                for (int j = 0; j < 5; ++j)
                {
                    if (M[i, j])
                    {
                        if (q[N[i, j]])
                            return false;
                        q[N[i, j]] = true;
                    }
                }
            }
            return true;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using Solver.Ex;
using Debug = System.Diagnostics.Debug;
using Watch = System.Diagnostics.Stopwatch;
using StringBuilder = System.Text.StringBuilder;
using System.Numerics;
namespace Solver
{
    public class Solver
    {
        public void Solve()
        {
            var n = sc.Integer();
            var map = new bool[5, 5];
            var col = "RGBYW";
            for (int i = 0; i < n; i++)
            {
                var c = sc.Char();
                var v = sc.Integer() - 1;
                for (int j = 0; j < 5; j++)
                    if (col[j] == c) map[j, v] |= true;
            }
            var max = 10;
            for (int i = 0; i < 1 << 5; i++)
                for (int j = 0; j < 1 << 5; j++)
                {
                    var cost = 0;
                    for (int k = 0; k < 5; k++)
                        cost += (i >> k) % 2 + (j >> k) % 2;
                    var c = new int[5];
                    var v = new int[5];
                    var u = 0;
                    for (int k = 0; k < 5; k++)
                        for (int l = 0; l < 5; l++)
                        {
                            if (!map[k, l]) continue;
                            if ((i >> k) % 2 == 1 && (j >> l) % 2 == 1) continue;
                            else if ((i >> k) % 2 == 1) c[k]++;
                            else if ((j >> l) % 2 == 1) v[l]++;
                            else u++;
                        }
                    if (c.Sum(x => x > 1 ? x : 0) + v.Sum(x => x > 1 ? x : 0) + u <= 1)
                        max = Math.Min(max, cost);
                }
            IO.Printer.Out.WriteLine(max);
        }

        internal IO.StreamScanner sc;
        static T[] Enumerate<T>(int n, Func<int, T> f) { var a = new T[n]; for (int i = 0; i < n; i++) a[i] = f(i); return a; }
    }

    #region Main and Settings
    static class Program
    {
        static void Main(string[] arg)
        {
#if DEBUG
            var errStream = new System.IO.FileStream(@"..\..\dbg.out", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
            Debug.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(errStream, "debugStream"));
            Debug.AutoFlush = false;
            var sw = new Watch(); sw.Start();
            IO.Printer.Out.AutoFlush = true;
            try
            {
#endif

                var solver = new Solver();
                solver.sc = new IO.StreamScanner(Console.OpenStandardInput());
                solver.Solve();
                IO.Printer.Out.Flush();
#if DEBUG
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                Console.Error.WriteLine(ex.StackTrace);
            }
            finally
            {
                sw.Stop();
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Error.WriteLine("Time:{0}ms", sw.ElapsedMilliseconds);
                Debug.Close();
                System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
            }
#endif
        }

    }
    #endregion
}

#region IO Helper
namespace Solver.IO
{
    public class Printer : System.IO.StreamWriter
    {
        static Printer()
        {
            Out = new Printer(Console.OpenStandardOutput()) { AutoFlush = false };
#if DEBUG
            Error = new Printer(Console.OpenStandardError()) { AutoFlush = true };
#else
            Error = new Printer(System.IO.Stream.Null) { AutoFlush = false };
#endif
        }
        public static Printer Out { get; set; }
        public static Printer Error { get; set; }
        public override IFormatProvider FormatProvider { get { return System.Globalization.CultureInfo.InvariantCulture; } }
        public Printer(System.IO.Stream stream) : base(stream, new System.Text.UTF8Encoding(false, true)) { }
        public Printer(System.IO.Stream stream, System.Text.Encoding encoding) : base(stream, encoding) { }
        public void Write<T>(string format, IEnumerable<T> source) { base.Write(format, source.OfType<object>().ToArray()); }
        public void WriteLine<T>(string format, IEnumerable<T> source) { base.WriteLine(format, source.OfType<object>().ToArray()); }
    }
    public class StreamScanner
    {
        public StreamScanner(System.IO.Stream stream) { iStream = stream; }
        private readonly System.IO.Stream iStream;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        private bool eof = false;
        public bool IsEndOfStream { get { return eof; } }
        const byte lb = 33, ub = 126, el = 10, cr = 13;
        public byte read()
        {
            if (eof) throw new System.IO.EndOfStreamException();
            if (ptr >= len) { ptr = 0; if ((len = iStream.Read(buf, 0, 1024)) <= 0) { eof = true; return 0; } }
            return buf[ptr++];
        }
        public char Char() { byte b = 0; do b = read(); while (b < lb || ub < b); return (char)b; }
        public char[] Char(int n) { var a = new char[n]; for (int i = 0; i < n; i++) a[i] = Char(); return a; }
        public char[][] Char(int n, int m) { var a = new char[n][]; for (int i = 0; i < n; i++) a[i] = Char(m); return a; }
        public string Scan()
        {
            if (eof) throw new System.IO.EndOfStreamException();
            StringBuilder sb = null;
            var enc = System.Text.UTF8Encoding.Default;
            do
            {
                for (; ptr < len && (buf[ptr] < lb || ub < buf[ptr]); ptr++) ;
                if (ptr < len) break;
                ptr = 0;
                if ((len = iStream.Read(buf, 0, 1024)) <= 0) { eof = true; return ""; }
            } while (true);
            do
            {
                var f = ptr;
                for (; ptr < len; ptr++)
                    if (buf[ptr] < lb || ub < buf[ptr])
                    //if (buf[ptr] == cr || buf[ptr] == el)
                    {
                        string s;
                        if (sb == null) s = enc.GetString(buf, f, ptr - f);
                        else { sb.Append(enc.GetChars(buf, f, ptr - f)); s = sb.ToString(); }
                        ptr++; return s;
                    }
                if (sb == null) sb = new StringBuilder(enc.GetString(buf, f, len - f));
                else sb.Append(enc.GetChars(buf, f, len - f));
                ptr = 0;

            }
            while (!eof && (len = iStream.Read(buf, 0, 1024)) > 0);
            eof = true; return (sb != null) ? sb.ToString() : "";
        }
        public long Long()
        {
            long ret = 0; byte b = 0; bool isMynus = false;
            const byte zr = 48, nn = 57, my = 45;
            do b = read();
            while (b != my && (b < zr || nn < b));
            if (b == my) { isMynus = true; b = read(); }
            for (; true; b = read())
                if (b < zr || nn < b)
                    return isMynus ? -ret : ret;
                else ret = ret * 10 + b - zr;
        }
        public int Integer()
        {
            int ret = 0; byte b = 0; bool isMynus = false;
            const byte zr = 48, nn = 57, my = 45;
            do b = read();
            while (b != my && (b < zr || nn < b));
            if (b == my) { isMynus = true; b = read(); }
            for (; true; b = read())
                if (b < zr || nn < b)
                    return isMynus ? -ret : ret;
                else ret = ret * 10 + b - zr;
        }
        public double Double() { return double.Parse(Scan(), System.Globalization.CultureInfo.InvariantCulture); }
        public string[] Scan(int n) { var a = new string[n]; for (int i = 0; i < n; i++) a[i] = Scan(); return a; }
        public double[] Double(int n) { var a = new double[n]; for (int i = 0; i < n; i++) a[i] = Double(); return a; }
        public int[] Integer(int n) { var a = new int[n]; for (int i = 0; i < n; i++) a[i] = Integer(); return a; }
        public long[] Long(int n) { var a = new long[n]; for (int i = 0; i < n; i++)a[i] = Long(); return a; }
        public void Flush() { iStream.Flush(); }
    }
}
#endregion
#region Extension
namespace Solver.Ex
{
    static public partial class EnumerableEx
    {
        static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
        static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") { return string.Join(st, ie); }

    }
}

#endregion

using System;
using System.Collections.Generic;
using System.Text;

namespace Codeforces_253_2
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = int.Parse(Console.ReadLine());
            Dictionary<string, int> K = new Dictionary<string, int>();
            Dictionary<char, int> C = new Dictionary<char, int>();
            foreach (string s in Console.ReadLine().Split(' ')) {
                K[s] = 0;
                C[s[0]] = 0;
                C[s[1]] = 0;
            }
            int ret = 0, i;
            int[] u = new int[10];
            List<char> CC = new List<char>();
            foreach (char c in C.Keys) CC.Add(c);
            List<string> KK = new List<string>();
            foreach (string k in K.Keys) KK.Add(k);
            if (1 < K.Count) {
                for (ret = 1; ret < C.Count; ++ret)
                {
                    for (i = 0; i < ret; ++i) u[i] = i;
                    do {
                        List<List<string>> T = new List<List<string>>();
                        T.Add(new List<string>(KK));
                        for (i = 0; i < ret; ++i) {
                            char cc = CC[u[i]];
                            int z = (cc <= '9') ? 1 : 0;
                            for (int j = T.Count - 1; 0 <= j; --j) {
                                List<string> t = new List<string>();
                                for (int k = T[j].Count - 1; 0 <= k; --k) {
                                    if (T[j][k][z] == cc) {
                                        t.Add(T[j][k]);
                                        T[j].RemoveAt(k);
                                    }
                                }
                                if (T[j].Count < 2) T.RemoveAt(j);
                                if (1 < t.Count) T.Add(t);
                            }
                        }
                        if (T.Count < 1) { Console.WriteLine(ret); return; }
                        for (i = ret-1; 0 <= i; --i) if (++u[i] < C.Count-(ret-1) + i) break;
                        if (i < 0) break;
                        for (++i; i < ret; ++i) u[i] = u[i-1] + 1;
                    } while (true);
                }
            }
            Console.WriteLine(ret);
        }
    }
}

// Submitted by Silithus @ Macau
using System;
using System.IO;
using System.Collections.Generic;
using CCF_XOI;

namespace CodeForces
{
	class CF443D
	{
		int N, M, K;
		int[] Num_Cnt, Color_Cnt, Num_Map, Color_Map;
		bool[,] Has_Card;

		int[] count_bit(int n)
		{
			int i = 0;
			List<int> num = new List<int>();

			while (n != 0)
			{
				if ((n & 0x1) == 0x1)
					num.Add(i);
				n >>= 1;
				i++;
			}

			return num.ToArray();
		}

		int try_guess(int num_mask, int color_mask)
		{
			int i, j, tot;
			bool new_move;
			int[] num_cnt, color_cnt, Num, Color;
			bool[] num_show, color_show;
			bool[,] has_card;

			num_cnt = new int[5];
			color_cnt = new int[5];
			num_show = new bool[5];
			color_show = new bool[5];
			has_card = new bool[5, 5];

			Array.Copy(Has_Card, has_card, Has_Card.Length);
			Array.Copy(Num_Cnt, num_cnt, Num_Cnt.Length);
			Array.Copy(Color_Cnt, color_cnt, Color_Cnt.Length);
			Num = count_bit(num_mask);
			Color = count_bit(color_mask);

			if (Num.Length == M - 1)
			{
				for (i = 0; i < M; i++)
					num_show[Num_Map[i]] = true;
			}
			else
			{
				foreach (int m in Num)
					num_show[Num_Map[m]] = true;
			}

			if (Color.Length == K - 1)
			{
				for (i = 0; i < K; i++)
					color_show[Color_Map[i]] = true;
			}
			else
			{
				foreach (int m in Color)
					color_show[Color_Map[m]] = true;
			}

			tot = N;
			do
			{
				new_move = false;
				for (i = 0; i < 5; i++)
				{
					for (j = 0; j < 5; j++)
					{
						if (!has_card[i, j]) continue;

						if ((num_show[i] && color_show[j]) || (num_show[i] && num_cnt[i] == 1) ||
							(color_show[j] && color_cnt[j] == 1) || tot == 1)
						{
							has_card[i, j] = false;
							num_cnt[i]--;
							color_cnt[j]--;
							tot--;
							new_move = true;
						}
					}
				}
			} while (new_move);

			return (tot == 0 ? Num.Length + Color.Length : Int32.MaxValue);
		}

		public void Solve(XOI xoi)
		{
			int i, j, n, k;
			HashSet<string> c = new HashSet<string>();

			Has_Card = new bool[5, 5];
			Num_Cnt = new int[5];
			Color_Cnt = new int[5];
			Num_Map = new int[5];
			Color_Map = new int[5];

			N = xoi.ReadInt();
			for (i = 0; i < N; i++)
				c.Add(xoi.ReadString());

			N = c.Count;
			foreach (string s in c)
			{
				switch (s[0])
				{
					case 'R': k = 0; break;
					case 'G': k = 1; break;
					case 'B': k = 2; break;
					case 'Y': k = 3; break;
					default: k = 4; break;
				}
				n = s[1] - '1';
				Has_Card[n, k] = true;
				Num_Cnt[n]++;
				Color_Cnt[k]++;
			}

			for (i = M = K = 0; i < 5; i++)
			{
				if (Num_Cnt[i] > 0) Num_Map[M++] = i;
				if (Color_Cnt[i] > 0) Color_Map[K++] = i;
			}

			int ans = Int32.MaxValue;
			for (i = 0; i < (1 << M); i++)
				for (j = 0; j < (1 << K); j++)
					ans = Math.Min(ans, try_guess(i, j));

			xoi.o.WriteLine(ans);
		}
	}

	class CodeForcesMain
	{
		static void Main(string[] args)
		{
			(new CF443D()).Solve(new XOI());
		}
	}
}

namespace CCF_XOI
{	// version 2014.06.20
	class XOI
	{
		protected StreamReader sr;
		public StreamWriter o;
		protected Queue<string> buf = new Queue<string>();
		public bool EOF = false;

		public XOI()
		{
			this.sr = new StreamReader(Console.OpenStandardInput());
			this.o = new StreamWriter(Console.OpenStandardOutput());
			this.o.AutoFlush = true;
		}

		public XOI(string in_path, string out_path)
		{
			this.sr = new StreamReader(in_path);
			this.o = new StreamWriter(out_path);
			this.o.AutoFlush = true;
		}

		public int ReadInt()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Int32.Parse(s);
		}

		public long ReadLong()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Int64.Parse(s);
		}

		public double ReadDouble()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Double.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
		}

		public string ReadString()
		{
			string s = this.GetNext();
			return (s == null ? null : s);
		}

		public string ReadLine()
		{	// I will ignore current buffer and read a new line
			string s = "";
			while (s == "" && !this.EOF)
			{
				s = sr.ReadLine();
				this.EOF = (s == null);
			}
			return (this.EOF ? null : s);
		}

		protected string GetNext()
		{
			if (buf.Count == 0)
			{
				while (buf.Count == 0 && !this.EOF)
				{
					string s = sr.ReadLine();
					if (s == null)
						this.EOF = true;
					else
						foreach (string ss in s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
							buf.Enqueue(ss);
				}
			}

			return (this.EOF ? null : buf.Dequeue());
		}
	}
}

// Submitted by Silithus @ Macau
using System;
using System.IO;
using System.Collections.Generic;
using CCF_XOI;

namespace CodeForces
{
	class CF443C
	{
		int count_bit(int n)
		{
			int cnt = 0;
			while (n != 0)
			{
				if ((n & 0x1) == 0x1)
					cnt++;
				n >>= 1;
			}

			return cnt;
		}

		public void Solve(XOI xoi)
		{
			int N, i, j, n, k, num_mask, color_mask, ans = Int32.MaxValue;
			string s, color = "RGBYW";
			bool[,] has_card;
			bool ok;

			has_card = new bool[5, 5];

			N = xoi.ReadInt();
			for (i = 0; i < N; i++)
			{
				s = xoi.ReadString();
				n = s[1] - '1';
				k = color.IndexOf(s[0]);
				has_card[n, k] = true;
			}

			for (num_mask = 0; num_mask < (1 << 5); num_mask++)
			{
				for (color_mask = 0; color_mask < (1 << 5); color_mask++)
				{
					int[,] hints = new int[6, 6];

					for (i = 0; i < 5; i++)
						for (j = 0; j < 5; j++)
							if (has_card[i, j])
							{
								n = ((num_mask & (1 << i)) != 0) ? i : 5;
								k = ((color_mask & (1 << j)) != 0) ? j : 5;
								hints[n, k]++;
							}

					ok = true;
					for (i = 0; i < 6; i++)
						for (j = 0; j < 6; j++)
							ok &= (hints[i, j] <= 1);

					if (ok)
					{
						n = count_bit(num_mask) + count_bit(color_mask);
						ans = Math.Min(ans, n);
					}
				}
			}

			xoi.o.WriteLine(ans);
		}
	}

	class CodeForcesMain
	{
		static void Main(string[] args)
		{
			(new CF443C()).Solve(new XOI());
		}
	}
}

namespace CCF_XOI
{	// version 2014.06.20
	class XOI
	{
		protected StreamReader sr;
		public StreamWriter o;
		protected Queue<string> buf = new Queue<string>();
		public bool EOF = false;

		public XOI()
		{
			this.sr = new StreamReader(Console.OpenStandardInput());
			this.o = new StreamWriter(Console.OpenStandardOutput());
			this.o.AutoFlush = true;
		}

		public XOI(string in_path, string out_path)
		{
			this.sr = new StreamReader(in_path);
			this.o = new StreamWriter(out_path);
			this.o.AutoFlush = true;
		}

		public int ReadInt()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Int32.Parse(s);
		}

		public long ReadLong()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Int64.Parse(s);
		}

		public double ReadDouble()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Double.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
		}

		public string ReadString()
		{
			string s = this.GetNext();
			return (s == null ? null : s);
		}

		public string ReadLine()
		{	// I will ignore current buffer and read a new line
			string s = "";
			while (s == "" && !this.EOF)
			{
				s = sr.ReadLine();
				this.EOF = (s == null);
			}
			return (this.EOF ? null : s);
		}

		protected string GetNext()
		{
			if (buf.Count == 0)
			{
				while (buf.Count == 0 && !this.EOF)
				{
					string s = sr.ReadLine();
					if (s == null)
						this.EOF = true;
					else
						foreach (string ss in s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
							buf.Enqueue(ss);
				}
			}

			return (this.EOF ? null : buf.Dequeue());
		}
	}
}

using System;
using System.Linq;

namespace Task_C
{
    class Program
    {
        private static int CardIndex(string card)
        {
            var num = card[1] - '1';
            int color = 0;
            if (card[0] == 'R')
                color = 0;
            if (card[0] == 'G')
                color = 1;
            if (card[0] == 'B')
                color = 2;
            if (card[0] == 'Y')
                color = 3;
            if (card[0] == 'W')
                color = 4;

            var index = (1 << num) | (1 << (color + 5));
            return index;
        }

        static void Main(string[] args)
        {
            int n = int.Parse(Console.ReadLine());
            var cards = Console.ReadLine().
                Split().
                Distinct().
                Select(x => CardIndex(x)).
                ToList();

            var minSuggest = int.MaxValue;

            var maxSuggest = 1 << 10;
            for (int suggest = 0; suggest < maxSuggest; suggest++)
            {
                var distinctCard = cards.Select(x => x & suggest).Distinct().Count();
                if (distinctCard == cards.Count)
                {
                    var suggestSize = SparseBitcount(suggest);
                    if (suggestSize < minSuggest)
                    {
                        minSuggest = suggestSize;
                    }
                }
            }

            Console.WriteLine(minSuggest);
        }

        static int SparseBitcount(int n)
        {
            int count = 0;
            while (n != 0)
            {
                count++;
                n &= (n - 1);
            }
            return count;
        }
    }
}

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace CF253
{
    struct Card
    {
        public int Color, Num;

        public Card(int color, string num)
        {
            Color = color;
            Num = int.Parse(num) - 1;
        }
    }
    class C
    {
        readonly int[] _bad = { ' ', '\r', '\n' };

        private string NextToken()
        {
            var sb = new StringBuilder();
            int i;

            while (Array.IndexOf(_bad, (i = Console.Read())) != -1)
            {
            }
            sb.Append((char)i);

            while (Array.IndexOf(_bad, (i = Console.Read())) == -1)
            {
                sb.Append((char)i);
            }
            return sb.ToString();
        }

        int NextInt()
        {
            return int.Parse(NextToken());
        }

        private void run()
        {
            var n = NextInt();
            var h = new Dictionary<char, int>();
            h.Add('R', 0);
            h.Add('G', 1);
            h.Add('B', 2);
            h.Add('Y', 3);
            h.Add('W', 4);
            var s = "";
            var pairs = Enumerable.Range(0, n).Select(x => new Card(h[(s = NextToken())[0]], s.Substring(1, 1))).ToArray();
            pairs = pairs.Distinct().ToArray();
            n = pairs.Length;
            var min = 239;
            for (var m1 = 0; m1 < 1 << 5; ++m1)
            {
                var num = Enumerable.Range(0, 5).Select(x => (m1 & (1 << x)) > 0).ToArray();
                for (var m2 = 0; m2 < 1 << 5; ++m2)
                {
                    var color = Enumerable.Range(0, 5).Select(x => (m2 & (1 << x)) > 0).ToArray();
                    var good = true;
                    for (var i = 0; i < n; ++i)
                        for (var j = 0; j < i; ++j)
                        {
                            var g = pairs[i].Color != pairs[j].Color && (color[pairs[i].Color] || color[pairs[j].Color]) ||
                                     pairs[i].Num != pairs[j].Num && (num[pairs[i].Num] || num[pairs[j].Num]);
                            if (!g)
                                good = false;
                        }
                    var sum = num.Sum(x => x ? 1 : 0) + color.Sum(x => x ? 1 : 0);
                    if (good && sum < min)
                        min = sum;
                }
            }
            Console.Write(min);
        }
        static void Main(string[] args)
        {
            new C().run();
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Borya_and_Hanabi
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            int n = int.Parse(reader.ReadLine());
            string[] ss = reader.ReadLine().Split(' ');

            var nn = new int[5,5];

            for (int i = 0; i < n; i++)
            {
                int n2 = ss[i][1] - '1';
                int n1 = -1;
                switch (ss[i][0])
                {
                    case 'R':
                        n1 = 0;
                        break;
                    case 'G':
                        n1 = 1;
                        break;
                    case 'B':
                        n1 = 2;
                        break;
                    case 'Y':
                        n1 = 3;
                        break;
                    case 'W':
                        n1 = 4;
                        break;
                }
                nn[n1, n2] = 1;
            }

            int min = 8;

            for (int i = 0; i < 32; i++)
            {
                int bi = Bitcount(i);
                if (bi >= min)
                    continue;

                for (int j = 0; j < 32; j++)
                {
                    int bj = Bitcount(j);
                    if (bi + bj >= min)
                        continue;

                    var mask = new int[5,5];

                    for (int k = 0; k < 5; k++)
                    {
                        if ((i & (1 << k)) != 0)
                        {
                            for (int l = 0; l < 5; l++)
                            {
                                if (nn[k, l] != 0)
                                {
                                    mask[k, l] = i << 16;
                                }
                            }
                        }
                    }

                    for (int k = 0; k < 5; k++)
                    {
                        if ((j & (1 << k)) != 0)
                        {
                            for (int l = 0; l < 5; l++)
                            {
                                if (nn[l, k] != 0)
                                {
                                    mask[l, k] |= j;
                                }
                            }
                        }
                    }

                    var list = new List<int>();
                    for (int k = 0; k < 5; k++)
                    {
                        for (int l = 0; l < 5; l++)
                        {
                            if (nn[k, l] != 0)
                            {
                                list.Add(mask[k, l]);
                            }
                        }
                    }
                    list.Sort();
                    bool f = false;
                    for (int k = 1; k < list.Count; k++)
                    {
                        if (list[k - 1] == list[k])
                        {
                            f = true;
                            break;
                        }
                    }
                    if (!f)
                    {
                        if (bi + bj < min)
                            min = bi + bj;
                    }
                }
            }

            writer.WriteLine(min);
            writer.Flush();
        }

        private static int Bitcount(int n)
        {
            int count = 0;
            do
            {
                if ((n & 1) == 1)
                    count++;
                n >>= 1;
            } while (n > 0);
            return count;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

// (づ*ω*)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    bool NextPerm(int[] a)
    {
        int n = a.Length;
        int k;
        for (k = n - 2; k >= 0; k--)
            if (a[k] < a[k + 1])
                for (int l = n - 1; l >= 0; l--)
                    if (a[k] < a[l])
                    {
                        Swap(ref a[k], ref a[l]);
                        for (int i = k + 1, j = n - 1; i < j; i++, j--)
                            Swap(ref a[i], ref a[j]);
                        return true;
                    }
        return false;
    }

    void Swap<T>(ref T a, ref T b)
    {
        T t = a;
        a = b;
        b = t;
    }

    public object Solve()
    {
        int n = ReadInt();
        var f = new bool[5,5];
        for (int i = 0; i < n; i++)
        {
            var t = ReadToken();
            f["RGBYW".IndexOf(t[0]), t[1] - '1'] = true;
        }

        int min = int.MaxValue;
        int nmin = -1;
        for (int i = 0; i < 5; i++)
        {
            int c = 0;
            for (int j = 0; j < 5; j++)
                if (f[i, j])
                    c++;
            if (c > 0)
            {
                min = Math.Min(min, c);
                nmin = i;
            }
        }
        var list1 = new List<int>();
        for (int i = 0; i < 5; i++)
        {
            int c = 0;
            for (int j = 0; j < 5; j++)
                if (f[i, j])
                    c++;
            if (c > 0 && i != nmin)
                list1.Add(i);
        }
        min = int.MaxValue;
        nmin = -1;
        for (int i = 0; i < 5; i++)
        {
            int c = 0;
            for (int j = 0; j < 5; j++)
                if (f[j, i])
                    c++;
            if (c > 0)
            {
                min = Math.Min(min, c);
                nmin = i;
            }
        }
        var list2 = new List<int>();
        for (int i = 0; i < 5; i++)
        {
            int c = 0;
            for (int j = 0; j < 5; j++)
                if (f[j, i])
                    c++;
            if (c > 0 && i != nmin)
                list2.Add(i + 5);
        }

        var perm = list1.Concat(list2).ToArray();

        int ans = int.MaxValue;
        do
        {

            var t1 = new int[5,5];
            var t2 = new int[5,5];
            int ri = 1;
            int ci = 1;
            for (int i = 0; i < 5; i++)
                for (int j = 0; j < 5; j++)
                    if (f[i, j])
                        t1[i, j] = t2[i, j] = 1;

            int c = 0;
            int p = 0;
            while (!Check(t1, t2))
            {
                if (perm[p] < 5)
                {
                    ri++;
                    for (int i = 0; i < 5; i++)
                        if (t1[perm[p], i] > 0)
                            t1[perm[p], i] = ri;
                }
                else
                {
                    ci++;
                    for (int i = 0; i < 5; i++)
                        if (t2[i, perm[p] - 5] > 0)
                            t2[i, perm[p] - 5] = ci;
                }
                c++;
                p++;
            }

            ans = Math.Min(c, ans);
        } while (NextPerm(perm));

        return ans;
    }

    bool Check(int[,] t1, int[,] t2)
    {
        var set = new HashSet<int>();
        int c = 0;
        for (int i = 0; i < 5; i++)
            for (int j = 0; j < 5; j++)
                if (t1[i, j] > 0)
                {
                    set.Add(10 * t1[i, j] + t2[i, j]);
                    c++;
                }
        return set.Count == c;
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = Console.In;
        writer = new StreamWriter(Console.OpenStandardOutput());
#endif
        try
        {
            object result = new Solver().Solve();
            if (result != null)
                writer.WriteLine(result);
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read/Write

    private static Queue<string> currentLineTokens = new Queue<string>();

    private static string[] ReadAndSplitLine()
    {
        return reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public static string ReadToken()
    {
        while (currentLineTokens.Count == 0)
            currentLineTokens = new Queue<string>(ReadAndSplitLine());
        return currentLineTokens.Dequeue();
    }

    public static int ReadInt()
    {
        return int.Parse(ReadToken());
    }

    public static long ReadLong()
    {
        return long.Parse(ReadToken());
    }

    public static double ReadDouble()
    {
        return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
    }

    public static int[] ReadIntArray()
    {
        return ReadAndSplitLine().Select(int.Parse).ToArray();
    }

    public static long[] ReadLongArray()
    {
        return ReadAndSplitLine().Select(long.Parse).ToArray();
    }

    public static double[] ReadDoubleArray()
    {
        return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
    }

    public static int[][] ReadIntMatrix(int numberOfRows)
    {
        int[][] matrix = new int[numberOfRows][];
        for (int i = 0; i < numberOfRows; i++)
            matrix[i] = ReadIntArray();
        return matrix;
    }

    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows);
        int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = new int[numberOfRows];
            for (int j = 0; j < numberOfRows; j++)
                ret[i][j] = matrix[j][i];
        }
        return ret;
    }

    public static string[] ReadLines(int quantity)
    {
        string[] lines = new string[quantity];
        for (int i = 0; i < quantity; i++)
            lines[i] = reader.ReadLine().Trim();
        return lines;
    }

    public static void WriteArray<T>(IEnumerable<T> array)
    {
        writer.WriteLine(string.Join(" ", array));
    }

    #endregion
}

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

public class Test
{
    [Flags]
    enum Card
    {
        R = 1 << 0,
        G = 1 << 1,
        B = 1 << 2,
        Y = 1 << 3,
        W = 1 << 4,
        One = 1 << 5,
        Two = 1 << 6,
        Three = 1 << 7,
        Four = 1 << 8,
        Five = 1 << 9,
    }

    public static void Main()
    {
        int result = Solve();
        Console.WriteLine(result);
    }

    static int Solve()
    {

        // Don't care for n
        Console.ReadLine();

        var input = Console.ReadLine().Split(' ').Select(x => ParseCard(x)).ToArray();
        if (input.Length == 1)
        {
            return 0;
        }
        List<Card> diffs = new List<Card>(input.Length * input.Length);
        for(int i = 0; i < input.Length - 1; i++)
        {
            for(int j = i + 1; j < input.Length; j++)
            {
                Card diff = Diff(input[i], input[j]);
                diffs.Add(diff);
            }
        }

        var subsets = Enumerable.Range(0, 1023).Select(x => (Card)x);
        int min = 11;
        foreach(var subset in subsets)
        {
            if(diffs.All(x => CanDistinguish(subset, x)))
            {
                // This is an answer
                min = Math.Min(min, CountBits((int)subset));
            }
        }

        return min;
    }

    static int CountBits(int num)
    {
        int res = 0;
        while(num > 0)
        {
            if ((num & 1) == 1) res++;
            num >>= 1;
        }
        return res;
    }

    static bool CanDistinguish(Card subset, Card diff)
    {
        return (subset & diff) != 0;
    }

    static Card Diff(Card f, Card s)
    {
        return f ^ s;
    }

    static Card ParseCard(string input)
    {
        Card colour = (Card)Enum.Parse(typeof(Card), input[0].ToString());
        Card num = Card.One;
        switch (input[1])
        {
            case '1': num = Card.One;break;
            case '2': num = Card.Two;break;
            case '3': num = Card.Three;break;
            case '4': num = Card.Four;break;
            case '5': num = Card.Five;break;
        }
        return colour | num;
    }
}

// Submitted by Silithus @ Macau
using System;
using System.IO;
using System.Collections.Generic;
using CCF_XOI;

namespace CodeForces
{
	class CF443D
	{
		int N, M, K;
		int[] Num_Cnt, Color_Cnt, Num_Map, Color_Map;
		bool[,] Has_Card;

		int[] count_bit(int n)
		{
			int i = 0;
			List<int> num = new List<int>();

			while (n != 0)
			{
				if ((n & 0x1) == 0x1)
					num.Add(i);
				n >>= 1;
				i++;
			}

			return num.ToArray();
		}

		int try_guess(int num_mask, int color_mask)
		{
			int i, j, tot;
			bool new_move;
			int[] num_cnt, color_cnt, Num, Color;
			bool[] num_show, color_show;
			bool[,] has_card;

			num_cnt = new int[5];
			color_cnt = new int[5];
			num_show = new bool[5];
			color_show = new bool[5];
			has_card = new bool[5, 5];

			Array.Copy(Has_Card, has_card, Has_Card.Length);
			Array.Copy(Num_Cnt, num_cnt, Num_Cnt.Length);
			Array.Copy(Color_Cnt, color_cnt, Color_Cnt.Length);
			Num = count_bit(num_mask);
			Color = count_bit(color_mask);

			if (Num.Length == M - 1)
			{
				for (i = 0; i < M; i++)
					num_show[Num_Map[i]] = true;
			}
			else
			{
				foreach (int m in Num)
					num_show[Num_Map[m]] = true;
			}

			if (Color.Length == K - 1)
			{
				for (i = 0; i < K; i++)
					color_show[Color_Map[i]] = true;
			}
			else
			{
				foreach (int m in Color)
					color_show[Color_Map[m]] = true;
			}

			tot = N;
			do
			{
				new_move = false;
				for (i = 0; i < 5; i++)
				{
					for (j = 0; j < 5; j++)
					{
						if (!has_card[i, j]) continue;

						if ((num_show[i] && color_show[j]) || (num_show[i] && num_cnt[i] == 1) ||
							(color_show[j] && color_cnt[j] == 1) || tot == 1)
						{
							has_card[i, j] = false;
							num_cnt[i]--;
							color_cnt[j]--;
							tot--;
							new_move = true;
						}
					}
				}
			} while (new_move);

			return (tot == 0 ? Num.Length + Color.Length : Int32.MaxValue);
		}

		public void Solve(XOI xoi)
		{
			int i, j, n, k;
			HashSet<string> c = new HashSet<string>();

			Has_Card = new bool[5, 5];
			Num_Cnt = new int[5];
			Color_Cnt = new int[5];
			Num_Map = new int[5];
			Color_Map = new int[5];

			N = xoi.ReadInt();
			for (i = 0; i < N; i++)
				c.Add(xoi.ReadString());

			N = c.Count;
			foreach (string s in c)
			{
				switch (s[0])
				{
					case 'R': k = 0; break;
					case 'G': k = 1; break;
					case 'B': k = 2; break;
					case 'Y': k = 3; break;
					default: k = 4; break;
				}
				n = s[1] - '1';
				Has_Card[n, k] = true;
				Num_Cnt[n]++;
				Color_Cnt[k]++;
			}

			for (i = M = K = 0; i < 5; i++)
			{
				if (Num_Cnt[i] > 0) Num_Map[M++] = i;
				if (Color_Cnt[i] > 0) Color_Map[K++] = i;
			}

			int ans = Int32.MaxValue;
			for (i = 0; i < (1 << (M - 1)); i++)
				for (j = 0; j < (1 << (K - 1)); j++)
					ans = Math.Min(ans, try_guess(i, j));

			xoi.o.WriteLine(ans);
		}
	}

	class CodeForcesMain
	{
		static void Main(string[] args)
		{
			(new CF443D()).Solve(new XOI());
		}
	}
}

namespace CCF_XOI
{	// version 2014.06.20
	class XOI
	{
		protected StreamReader sr;
		public StreamWriter o;
		protected Queue<string> buf = new Queue<string>();
		public bool EOF = false;

		public XOI()
		{
			this.sr = new StreamReader(Console.OpenStandardInput());
			this.o = new StreamWriter(Console.OpenStandardOutput());
			this.o.AutoFlush = true;
		}

		public XOI(string in_path, string out_path)
		{
			this.sr = new StreamReader(in_path);
			this.o = new StreamWriter(out_path);
			this.o.AutoFlush = true;
		}

		public int ReadInt()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Int32.Parse(s);
		}

		public long ReadLong()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Int64.Parse(s);
		}

		public double ReadDouble()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Double.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
		}

		public string ReadString()
		{
			string s = this.GetNext();
			return (s == null ? null : s);
		}

		public string ReadLine()
		{	// I will ignore current buffer and read a new line
			string s = "";
			while (s == "" && !this.EOF)
			{
				s = sr.ReadLine();
				this.EOF = (s == null);
			}
			return (this.EOF ? null : s);
		}

		protected string GetNext()
		{
			if (buf.Count == 0)
			{
				while (buf.Count == 0 && !this.EOF)
				{
					string s = sr.ReadLine();
					if (s == null)
						this.EOF = true;
					else
						foreach (string ss in s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
							buf.Enqueue(ss);
				}
			}

			return (this.EOF ? null : buf.Dequeue());
		}
	}
}

// Submitted by Silithus @ Macau
using System;
using System.IO;
using System.Collections.Generic;
using CCF_XOI;

namespace CodeForces
{
	class CF443D
	{
		int N, M, K;
		int[] Num_Cnt, Color_Cnt, Num_Map, Color_Map;
		bool[,] Has_Card;

		int[] count_bit(int n)
		{
			int i = 0;
			List<int> num = new List<int>();

			while (n != 0)
			{
				if ((n & 0x1) == 0x1)
					num.Add(i);
				n >>= 1;
				i++;
			}

			return num.ToArray();
		}

		int try_guess(int num_mask, int color_mask)
		{
			int i, j, tot;
			bool new_move;
			int[] num_cnt, color_cnt, Num, Color;
			bool[] num_show, color_show;
			bool[,] has_card;

			num_cnt = new int[5];
			color_cnt = new int[5];
			num_show = new bool[5];
			color_show = new bool[5];
			has_card = new bool[5, 5];

			Array.Copy(Has_Card, has_card, Has_Card.Length);
			Array.Copy(Num_Cnt, num_cnt, Num_Cnt.Length);
			Array.Copy(Color_Cnt, color_cnt, Color_Cnt.Length);
			Num = count_bit(num_mask);
			Color = count_bit(color_mask);

			if (Num.Length == M - 1)
			{
				for (i = 0; i < M; i++)
					num_show[Num_Map[i]] = true;
			}
			else
			{
				foreach (int m in Num)
					num_show[Num_Map[m]] = true;
			}

			if (Color.Length == K - 1)
			{
				for (i = 0; i < K; i++)
					color_show[Color_Map[i]] = true;
			}
			else
			{
				foreach (int m in Color)
					color_show[Color_Map[m]] = true;
			}

			tot = N;
			do
			{
				new_move = false;
				for (i = 0; i < 5; i++)
				{
					for (j = 0; j < 5; j++)
					{
						if (!has_card[i, j]) continue;

						if ((num_show[i] && color_show[j]) || (num_show[i] && num_cnt[i] == 1) ||
							(color_show[j] && color_cnt[j] == 1))
						{
							has_card[i, j] = false;
							num_cnt[i]--;
							color_cnt[j]--;
							tot--;
							new_move = true;
						}
					}
				}
			} while (new_move);

			if (tot == 0)
				return (Num.Length + Color.Length);
			else
				return Int32.MaxValue;
		}

		public void Solve(XOI xoi)
		{
			int i, j, n, k;
			HashSet<string> c = new HashSet<string>();

			Has_Card = new bool[5, 5];
			Num_Cnt = new int[5];
			Color_Cnt = new int[5];
			Num_Map = new int[5];
			Color_Map = new int[5];

			N = xoi.ReadInt();
			for (i = 0; i < N; i++)
				c.Add(xoi.ReadString());

			N = c.Count;
			foreach (string s in c)
			{
				switch (s[0])
				{
					case 'R': k = 0; break;
					case 'G': k = 1; break;
					case 'B': k = 2; break;
					case 'Y': k = 3; break;
					default: k = 4; break;
				}
				n = s[1] - '1';
				Has_Card[n, k] = true;
				Num_Cnt[n]++;
				Color_Cnt[k]++;
			}

			for (i = M = K = 0; i < 5; i++)
			{
				if (Num_Cnt[i] > 0) Num_Map[M++] = i;
				if (Color_Cnt[i] > 0) Color_Map[K++] = i;
			}

			int ans = Int32.MaxValue;
			for (i = 0; i < (1 << (M - 1)); i++)
				for (j = 0; j < (1 << (K - 1)); j++)
					ans = Math.Min(ans, try_guess(i, j));

			xoi.o.WriteLine(ans);
		}
	}

	class CodeForcesMain
	{
		static void Main(string[] args)
		{
			(new CF443D()).Solve(new XOI());
		}
	}
}

namespace CCF_XOI
{	// version 2014.06.20
	class XOI
	{
		protected StreamReader sr;
		public StreamWriter o;
		protected Queue<string> buf = new Queue<string>();
		public bool EOF = false;

		public XOI()
		{
			this.sr = new StreamReader(Console.OpenStandardInput());
			this.o = new StreamWriter(Console.OpenStandardOutput());
			this.o.AutoFlush = true;
		}

		public XOI(string in_path, string out_path)
		{
			this.sr = new StreamReader(in_path);
			this.o = new StreamWriter(out_path);
			this.o.AutoFlush = true;
		}

		public int ReadInt()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Int32.Parse(s);
		}

		public long ReadLong()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Int64.Parse(s);
		}

		public double ReadDouble()
		{
			string s = this.GetNext();
			if (s == null) return -1;
			else return Double.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
		}

		public string ReadString()
		{
			string s = this.GetNext();
			return (s == null ? null : s);
		}

		public string ReadLine()
		{	// I will ignore current buffer and read a new line
			string s = "";
			while (s == "" && !this.EOF)
			{
				s = sr.ReadLine();
				this.EOF = (s == null);
			}
			return (this.EOF ? null : s);
		}

		protected string GetNext()
		{
			if (buf.Count == 0)
			{
				while (buf.Count == 0 && !this.EOF)
				{
					string s = sr.ReadLine();
					if (s == null)
						this.EOF = true;
					else
						foreach (string ss in s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
							buf.Enqueue(ss);
				}
			}

			return (this.EOF ? null : buf.Dequeue());
		}
	}
}

using System;
using System.Linq;

namespace Task_C
{
    class Program
    {
        private static int CardIndex(string card)
        {
            var num = card[1] - '0';
            int color = 0;
            if (card[0] == 'R')
                color = 0;
            if (card[0] == 'G')
                color = 1;
            if (card[0] == 'B')
                color = 2;
            if (card[0] == 'Y')
                color = 3;
            if (card[0] == 'W')
                color = 4;

            var index = (1 << num) | (1 << (color + 5));
            return index;
        }

        static void Main(string[] args)
        {
            int n = int.Parse(Console.ReadLine());
            var cards = Console.ReadLine().
                Split().
                Distinct().
                Select(x => CardIndex(x)).
                ToList();

            var minSuggest = int.MaxValue;

            var maxSuggest = 1 << 10;
            for (int suggest = 0; suggest < maxSuggest; suggest++)
            {
                var distinctCard = cards.Select(x => x & suggest).Distinct().Count();
                if (distinctCard == cards.Count)
                {
                    var suggestSize = SparseBitcount(suggest);
                    if (suggestSize < minSuggest)
                    {
                        minSuggest = suggestSize;
                    }
                }
            }

            Console.WriteLine(minSuggest);
        }

        static int SparseBitcount(int n)
        {
            int count = 0;
            while (n != 0)
            {
                count++;
                n &= (n - 1);
            }
            return count;
        }
    }
}