Problem:
Score : 400 points

Problem Statement

We have a board with a 2 \times N grid.
Snuke covered the board with N dominoes without overlaps.
Here, a domino can cover a 1 \times 2 or 2 \times 1 square.

Then, Snuke decided to paint these dominoes using three colors: red, cyan and green.
Two dominoes that are adjacent by side should be painted by different colors.
Here, it is not always necessary to use all three colors.

Find the number of such ways to paint the dominoes, modulo 1000000007.

The arrangement of the dominoes is given to you as two strings S_1 and S_2 in the following manner:

Each domino is represented by a different English letter (lowercase or uppercase).

The j-th character in S_i represents the domino that occupies the square at the i-th row from the top and j-th column from the left.

Constraints

1 \leq N \leq 52

|S_1| = |S_2| = N

S_1 and S_2 consist of lowercase and uppercase English letters.

S_1 and S_2 represent a valid arrangement of dominoes.

Input

Input is given from Standard Input in the following format:

N
S_1
S_2

Output

Print the number of such ways to paint the dominoes, modulo 1000000007.

Sample Input 1

3
aab
ccb

Sample Output 1

6

There are six ways as shown below:

Sample Input 2

1
Z
Z

Sample Output 2

3

Note that it is not always necessary to use all the colors.

Sample Input 3

52
RvvttdWIyyPPQFFZZssffEEkkaSSDKqcibbeYrhAljCCGGJppHHn
RLLwwdWIxxNNQUUXXVVMMooBBaggDKqcimmeYrhAljOOTTJuuzzn

Sample Output 3

958681902

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Math;
using static System.Console;
using static CS_Contest.Utils;
using System.IO;
//using static CS_Contest.Library;

namespace CS_Contest {
	using Li = List<int>;
	using LLi = List<List<int>>;
	using Ls = List<string>;
	using Ll = List<long>;
	using LLl = List<List<long>>;
	using cc = Tuple<char, char>;
	class Program {
		static void Main(string[] args) {
			var sw = new StreamWriter(OpenStandardOutput()) { AutoFlush = false };
			SetOut(sw);
			new Calc().Solve();
			Out.Flush();
			return;
        }

		private class Calc {
			public void Solve() {
				int N = ReadInt();
				string S1 = ReadLine(), S2 = ReadLine();
				List<cc> docked = new List<cc>();
				for (int i = 0; i < S1.Length; i++) {
					docked.Add(new cc(S1[i], S2[i]));
				}

				long ans;
				//0が縦 1が横
				int before;
				if (docked[0].Item1 == docked[0].Item2) { ans = 3; before = 0; }
				else { ans = 6; docked.RemoveAt(0); before = 1; }
				docked.RemoveAt(0);
				for (int i=0;i<docked.Count;i++) {
					var item = docked[i];
					if (before==0) {
						//一つ前が縦
						//次が＝に並ぶ奴
						if (item.Item2 != item.Item1) {
							ans = Mod(ans * 2);
							i++;
							before = 1;
						}
						//次も｜
						else {
							ans = Mod(ans * 2);
						}
					}
					else {
						//一つ前が＝
						//次も＝
						if (item.Item1 != item.Item2) {
							ans = Mod(ans * 3);
							i++;
						}
						//次が｜
						else {
							ans = Mod(ans * 1);
							before = 0;
						}
					}
				}
				Mod(ans).WL();
				return;
			}
			
		}
	}


	public static class Utils {
		public static int ModValue = (int)(1000000007);
		public static long INF = long.MaxValue;
		public static long Mod(long x) => x % ModValue;
		public static long ModPow(long x,long n) { long tmp = 1; while (n != 0) { if (n % 2 == 1) { tmp = Mod(tmp * x); }x = Mod(x * x);n /= 2; }return tmp; }
		public static long DivMod(long x, long y) => Mod(x * ModPow(y, (long)(1e9 + 5)));
        public static void WL(this object obj) => WriteLine(obj);
        public static void WL(this string obj) => WriteLine(obj);
        public static void WL<T>(this IEnumerable<T> list) => list.ToList().ForEach(x => x.WL());
		public static int ReadInt() => int.Parse(ReadLine());
		public static List<int> ReadInt(char s) => ReadLine().Split(s).Where(x=>x!="").Select(int.Parse).ToList();
		public static long ReadLong() => long.Parse(ReadLine());
		public static List<long> ReadLong(char s) => ReadLine().Split(s).Select(long.Parse).ToList();
		public static void ReadMulti(out int x, out int y) {
			var i = ReadInt(' ');
			x = i[0]; y = i[1];

		}
		public static void ReadMulti(out long x, out long y) {
			var i = ReadLong(' ');
			x = i[0];y = i[1];
		}
		public static void ReadMulti(out int x, out int y, out int z) {
			var i = ReadInt(' ');
			x = i[0];y = i[1];z = i[2];
		}
		public static void ReadMulti(out int x, out int y, out int z, out int v) {
			var i = ReadInt(' ');
			x = i[0]; y = i[1]; z = i[2];v = i[3];
		}



		public static long GCD(long m,long n) {
			long tmp;
			if (m < n) { tmp = n;n = m;m = tmp; }
			while(m%n!=0) {
				tmp = n;
				n = m % n;
				m = tmp;
			}
			return n;
		}
		public static long LCM(long m, long n) => m * (n / GCD(m, n));

		public static void REP(int n,Action<int> act) {
			for (int i = 0; i < n; i++) {
				act(i);
			}
		}
		public static void RREP(int n,Action<int> act) {
			for (int i = n-1; i >=0; i--) {
				act(i);
			}
		}
		public static void REP(long n, Action<int> act) => REP((int)n, act);
		public static void RREP(long n, Action<int> act) => RREP((int)n, act);

		public static void Yes() => "Yes".WL();
		public static void No() => "No".WL();
		public static void YES() => "YES".WL();
		public static void NO() => "NO".WL();


		public static int ManhattanDistance(int x1, int y1, int x2, int y2) => Abs(x2 - x1) + Abs(y2 - y1);


		public class Vector2 {
			public int X { get; set; }
			public int Y { get; set; }
			public Vector2() { X = 0; Y = 0; }
			public Vector2(int x, int y) { X = x; Y = y; }
			public int ManhattanDistance(Vector2 v2) {
				return Utils.ManhattanDistance(X, Y, v2.X, v2.Y);
			}
			public static int ManhattanDistance(Vector2 v1, Vector2 v2) => v2.ManhattanDistance(v2);
			public double Distance(Vector2 v2) => Sqrt(Pow(X - v2.X, 2) + Pow(Y - v2.Y, 2));
			public static Vector2 Zero { get { return new Vector2(); } }
			public void Clear() { X = 0; Y = 0; }
		}


	}
}