import java.util.Collections;
import java.util.InputMismatchException;
import java.math.BigInteger;
import java.util.Stack;
import java.util.*;
import java.util.Set;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.Comparator;
import java.io.*;
import java.util.Iterator;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.Arrays;

/**
 * Generated by Contest helper plug-in
 * Actual solution is at the bottom
 */
public class Main {
	public static void main(String[] args) {
		InputReader in = new StreamInputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);
		run(in, out);
	}

	public static void run(InputReader in, PrintWriter out) {
		Solver solver = new TaskE();
		solver.solve(1, in, out);
		Exit.exit(in, out);
	}
}

abstract class InputReader {
	private boolean finished = false;

	public abstract int read();

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuffer res = new StringBuffer();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	private boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}

	public void setFinished(boolean finished) {
		this.finished = finished;
	}

	public abstract void close();
}

class StreamInputReader extends InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar, numChars;

	public StreamInputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	@Override
	public void close() {
		try {
			stream.close();
		} catch (IOException ignored) {
		}
	}
}

class Exit {
	private Exit() {
	}

	public static void exit(InputReader in, PrintWriter out) {
		in.setFinished(true);
		in.close();
		out.close();
	}
}

interface Solver {
	public void solve(int testNumber, InputReader in, PrintWriter out);
}

class Pair<U, V> {

	public final U first;
	public final V second;

	public static<U, V> Pair<U, V> makePair(U first, V second) {
		return new Pair<U, V>(first, second);
	}

	private Pair(U first, V second) {
		this.first = first;
		this.second = second;
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;

		Pair pair = (Pair) o;

		return !(first != null ? !first.equals(pair.first) : pair.first != null) && !(second != null ? !second.equals(pair.second) : pair.second != null);

	}

	@Override
	public int hashCode() {
		int result = first != null ? first.hashCode() : 0;
		result = 31 * result + (second != null ? second.hashCode() : 0);
		return result;
	}

	@Override
	public String toString() {
		return "(" + first + "," + second + ")";
	}
}

interface Edge {
	public int getSource();
	public int getDestination();
	public long getCapacity();
	public void pushFlow(long flow);
	public Edge getReverseEdge();
}

class Graph {
	private final int size;
	private final List<Edge>[] edges;

	public Graph(int size) {
		this.size = size;
		//noinspection unchecked
		edges = new List[size];
		for (int i = 0; i < size; i++)
			edges[i] = new ArrayList<Edge>();
	}

	public int getSize() {
		return size;
	}

	public List<Edge> getIncident(int vertex) {
		return edges[vertex];
	}

	public void add(Edge edge) {
		edges[edge.getSource()].add(edge);
		edge = edge.getReverseEdge();
		if (edge != null)
			edges[edge.getSource()].add(edge);
	}

	}

class GraphAlgorithms {
	public static long dinic(Graph graph, int source, int destination) {
		long totalFlow = 0;
		int vertexCount = graph.getSize();
		int[] nextEdge = new int[vertexCount];
		while (true) {
			long[] distance = edgeDistances(graph, source).getDistances();
			if (distance[destination] == Long.MAX_VALUE)
				break;
			Arrays.fill(nextEdge, 0);
			totalFlow += dinicImpl(graph, source, destination, Long.MAX_VALUE, distance, nextEdge);
		}
		return totalFlow;
	}

	private static DistanceResult edgeDistances(Graph graph, int source) {
		int size = graph.getSize();
		Deque<Integer> queue = new ArrayDeque<Integer>(size);
		boolean[] processed = new boolean[size];
		boolean[] notReached = new boolean[size];
		Arrays.fill(notReached, true);
		long[] distance = new long[size];
		int[] last = new int[size];
		Arrays.fill(distance, Long.MAX_VALUE);
		distance[source] = 0;
		last[source] = -1;
		queue.add(source);
		notReached[source] = false;
		int iterationCount = 0;
		while (!queue.isEmpty()) {
			iterationCount++;
			if (iterationCount / size / size / size != 0)
				return null;
			int current = queue.poll();
			processed[current] = true;
			for (Edge edge : graph.getIncident(current)) {
				if (edge.getCapacity() == 0)
					continue;
				int next = edge.getDestination();
				long weight = 1;
				if (distance[next] > distance[current] + weight) {
					distance[next] = distance[current] + weight;
					last[next] = current;
					if (notReached[next]) {
						notReached[next] = false;
						queue.add(next);
					} else if (processed[next]) {
						processed[next] = false;
						queue.addFirst(next);
					}
				}
			}
		}
		return new DistanceResult(distance, last);
	}

	private static long dinicImpl(Graph graph, int source, int destination, long flow, long[] distance, int[] nextEdge) {
		if (source == destination)
			return flow;
		if (flow == 0 || distance[source] == distance[destination])
			return 0;
		List<Edge> incident = graph.getIncident(source);
		int incidentSize = incident.size();
		int totalPushed = 0;
		for (int i = nextEdge[source]; i < incidentSize; i++) {
			Edge edge = incident.get(i);
			int nextDestination = edge.getDestination();
			if (distance[nextDestination] != distance[source] + 1)
				continue;
			long pushed = dinicImpl(graph, nextDestination, destination, Math.min(flow, edge.getCapacity()),
				distance, nextEdge);
			if (pushed != 0) {
				edge.pushFlow(pushed);
				flow -= pushed;
				totalPushed += pushed;
				if (flow == 0) {
					nextEdge[source] = i;
					return totalPushed;
				}
			}
		}
		nextEdge[source] = incidentSize;
		return totalPushed;
	}

	public static class DistanceResult {
		private final long[] distances;
		private final int[] last;

		public DistanceResult(long[] distances, int[] last) {
			this.distances = distances;
			this.last = last;
		}

		public long[] getDistances() {
			return distances;
		}

		}

	}

class SimpleEdge implements Edge {
	protected final int source;
	protected final int destination;

	public SimpleEdge(int source, int destination) {
		this.source = source;
		this.destination = destination;
	}

	public int getSource() {
		return source;
	}

	public int getDestination() {
		return destination;
	}

	public long getCapacity() {
		return 0;
	}

	public void pushFlow(long flow) {
		throw new UnsupportedOperationException();
	}

	public Edge getReverseEdge() {
		return null;
	}

	}

class FlowEdge extends SimpleEdge {
	private long capacity;
	private long flow = 0;
	private Edge reverseEdge;

	public FlowEdge(int source, int destination, long capacity) {
		super(source, destination);
		this.capacity = capacity;
		reverseEdge = new ReverseEdge();
	}

	@Override
	public long getCapacity() {
		return capacity;
	}

	@Override
	public void pushFlow(long flow) {
		if (flow > 0) {
			if (this.capacity < flow)
				throw new IllegalArgumentException();
		} else {
			if (this.flow < -flow)
				throw new IllegalArgumentException();
		}
		capacity -= flow;
		this.flow += flow;
	}

	@Override
	public Edge getReverseEdge() {
		return reverseEdge;
	}

	private class ReverseEdge implements Edge {
		public int getSource() {
			return destination;
		}

		public int getDestination() {
			return source;
		}

		public long getCapacity() {
			return flow;
		}

		public void pushFlow(long flow) {
			FlowEdge.this.pushFlow(-flow);
		}

		public Edge getReverseEdge() {
			return FlowEdge.this;
		}
	}
}

class IOUtils {

	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}

	public static char[][] readTable(InputReader in, int rowCount, int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}

	}

class MiscUtils {
	public static final int[] DX_4_CONNECTED = {1, 0, -1, 0};
	public static final int[] DY_4_CONNECTED = {0, -1, 0, 1};

	}

class TaskE implements Solver {
	public void solve(int testNumber, InputReader in, PrintWriter out) {
		int size = in.readInt();
		int time = in.readInt();
		char[][] scientists = IOUtils.readTable(in, size, size);
		char[][] rescue = IOUtils.readTable(in, size, size);
		Graph graph = new Graph(2 * size * size + 2);
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				if (Character.isDigit(scientists[i][j]))
					graph.add(new FlowEdge(2 * size * size, i * size + j, scientists[i][j] - '0'));
				if (Character.isDigit(rescue[i][j]))
					graph.add(new FlowEdge(size * size + i * size + j, 2 * size * size + 1, rescue[i][j] - '0'));
			}
		}
		int badRow = -1;
		int badColumn = -1;
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				if (rescue[i][j] == 'Z') {
					badRow = i;
					badColumn = j;
				}
			}
		}
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				if (Character.isDigit(scientists[i][j]) && scientists[i][j] != '0') {
					if (rescue[i][j] != '0')
						graph.add(new FlowEdge(i * size + j, size * size + i * size + j, Integer.MAX_VALUE));
					Set<Pair<Integer, Integer>> canBe = new HashSet<Pair<Integer, Integer>>();
					canBe.add(Pair.makePair(i, j));
					Set<Pair<Integer, Integer>> caNtBe = new HashSet<Pair<Integer, Integer>>();
					caNtBe.add(Pair.makePair(badRow, badColumn));
					for (int k = 0; k < time; k++) {
						Set<Pair<Integer, Integer>> nextCanBe = new HashSet<Pair<Integer, Integer>>();
						for (Pair<Integer, Integer> cell : canBe) {
							for (int l = 0; l < 4; l++) {
								int newRow = cell.first + MiscUtils.DX_4_CONNECTED[l];
								int newColumn = cell.second + MiscUtils.DY_4_CONNECTED[l];
								if (newRow >= 0 && newColumn >= 0 && newRow < size && newColumn < size && Character.isDigit(scientists[newRow][newColumn])) {
									Pair<Integer, Integer> next = Pair.makePair(newRow, newColumn);
									if (!caNtBe.contains(next)) {
										if (rescue[newRow][newColumn] != '0')
											graph.add(new FlowEdge(i * size + j, size * size + newRow * size + newColumn, Integer.MAX_VALUE));
										nextCanBe.add(next);
									}
								}
							}
						}
						Set<Pair<Integer, Integer>> nextCaNtBe = new HashSet<Pair<Integer, Integer>>();
						for (Pair<Integer, Integer> cell : caNtBe) {
							nextCaNtBe.add(cell);
							for (int l = 0; l < 4; l++) {
								int newRow = cell.first + MiscUtils.DX_4_CONNECTED[l];
								int newColumn = cell.second + MiscUtils.DY_4_CONNECTED[l];
								if (newRow >= 0 && newColumn >= 0 && newRow < size && newColumn < size && Character.isDigit(scientists[newRow][newColumn])) {
									Pair<Integer, Integer> next = Pair.makePair(newRow, newColumn);
									nextCaNtBe.add(next);
								}
							}
						}
						canBe = nextCanBe;
						caNtBe = nextCaNtBe;
						canBe.removeAll(caNtBe);
					}
				}
			}
		}
		out.println(GraphAlgorithms.dinic(graph, 2 * size * size, 2 * size * size + 1));
	}
}


import static java.lang.Math.*;
import static java.lang.System.currentTimeMillis;
import static java.lang.System.exit;
import static java.lang.System.arraycopy;
import static java.util.Arrays.sort;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.fill;
import java.util.*;
import java.io.*;

public class Main {

	public static void main(String[] args) throws IOException {
		try {
			if (new File("input.txt").exists())
				System.setIn(new FileInputStream("input.txt"));
		} catch (SecurityException e) {
		}
		new Thread(null, new Runnable() {
			public void run() {
				try {
					new Main().run();
				} catch (Throwable e) {
					e.printStackTrace();
					exit(999);
				}
			}
		}, "1", 1 << 23).start();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");

	int n, T;
	boolean f[][];
	int start[][];
	int end[][];

	Q qu;

	void get(int m[][]) throws IOException{
		for(int i = 0; i < n; i++){
			char s[] = nextToken().toCharArray();
			for(int j = 0; j < n; j++){
				switch(s[j]){
				case 'Z' :
					if(qu.isEmpty())
						qu.push(i, j, 0);
					f[i][j] = false;
					break;
				case 'Y':
					f[i][j] = false;
					break;
				default:
					m[i][j] = s[j] - '0';
				}
			}
		}
	}
	int ttd[][]; //time to die
	boolean used[][];

	int dx[] = {-1, 0, 1 , 0};
	int dy[] = {0, 1, 0 , -1};

	int inf = -1;
	int cap[][];
	int fl[][];
	int m;

	void compute_ttd(){
		for(boolean i[] : used)
			fill(i, false);

		for(boolean i[] : used)
			fill(i, false);
		while(!qu.isEmpty()){

			P e = qu.pop();
			int x = e.x, y = e.y, t = e.t;
			ttd[x][y] = t;
			used[x][y] = true;
			for(int k = 0; k < 4; k++){
				int nx = x + dx[k];
				int ny = y + dy[k];
				if(valid(nx, ny)){
					used[nx][ny] = true;
					qu.push(nx, ny, t + 1);
				}
			}
		}
	}

	boolean valid(int x, int y){
		if(x < 0 || y < 0 || x >= n || y >= n || !f[x][y] || used[x][y])
			return false;
		return true;
	}

	List<Integer> g[];
	void setG(int vert){
		for(boolean i[] : used)
			fill(i, false);

		while(!qu.isEmpty()){
			P e = qu.pop();
			int x = e.x, y = e.y, t = e.t;
			used[x][y] = true;

			if(t <= ttd[x][y] && t <= T){
				cap[vert][m + 2 + x * n + y] = inf;
				g[vert].add(m + 2 + x * n + y);
				g[m + 2 + x * n + y].add(vert);
			}
			if(t >= ttd[x][y] || t >= T)
				continue;
			for(int k = 0; k < 4; k++)
				if(valid(x + dx[k], y + dy[k])){
					used[x + dx[k]][y + dy[k]] = true;
					qu.push(x + dx[k], y + dy[k], t + 1);
				}
		}
	}
	int path[];
	boolean lu[];
	QL ql;
	boolean find_path(int start, int end){
		fill(lu, false);

		ql.clear();
		ql.push(start);
		lu[start] = true;
		while(!ql.isEmpty()){
			int v = ql.pop();
			if(v == end)
				return true;
			for(int e : g[v]){
				if(lu[e])
					continue;
				if(cap[v][e] > fl[v][e]){
					lu[e] = true;
					path[e] = v;
					ql.push(e);
				}
			}
		}
		return false;
	}

	private void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		n = nextInt();
		T = nextInt();

		inf = n * n + n + 100;

		f = new boolean[n][n];
		start = new int[n][n];
		end = new int[n][n];
		for(boolean []i : f)
			fill(i, true);

		qu = new Q(n * n + 1);//

		get(start);
		get(end);

		ttd = new int[n][n];
		used = new boolean[n][n];

		for(int i[] : ttd)
			fill(i, inf << 1);

		compute_ttd();

		m = n * n;

		cap = new int[m + m + 2][m + m + 2];
		fl = new int[m + m + 2][m + m + 2];

		g = new ArrayList[m + m + 2];
		for(int i = 0; i < m + m + 2; i++)
			g[i] = new ArrayList<Integer>();

		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++){
				qu.clear();
				qu.push(i, j, 0);
				setG(n * i + j);
				cap[n * i + j][n * i + j] = inf;
			}

//		for(int i = 0; i < n; i++)
//			System.err.println(Arrays.toString(ttd[i]));
//		for(int i = 0; i < m; i++)
//			System.err.println(Arrays.toString(cap[i]));
//
//		for(int ii = 0; ii < n; ii++)
//			for(int jj = 0; jj < n; jj++)
//		for(int i = 0; i < n; i++)
//			for(int j = 0; j < n; j++)
//						if(cap[ii * n + jj][i * n + j] != 0)
//							System.err.println(ii + " " + jj + " | " + i + " " + j);

		// m - from   m+1 - to
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++){
				cap[m][i * n + j] = start[i][j];
				g[m].add(i * n + j);
				cap[m + 2 + i * n + j][m+1] = end[i][j];
				g[m + 2 + i * n + j].add(m + 1);
			}

		path = new int[m + m + 2];
		lu = new boolean[m + m + 2];
		ql = new QL(m + m + 2);
		int ans = 0;

		while(true){
			if(!find_path(m , m + 1)){
				break;
			}

			int mf = inf;
			{
				int i = m + 1;
				do{
					int j = path[i];
					mf = min(mf, cap[j][i] - fl[j][i]);
					i = j;
				}while(i != m);
			}
			ans += mf;
			{
				int i = m + 1;
				do{
					int j = path[i];
					fl[j][i] += mf;
					fl[i][j] -= mf;
					i = j;
				}while(i != m);
			}
		}

		out.println(ans);
		in.close();
		out.close();
	}

	class Q{
		P m[];
		int h, t;
		Q(int size){
			m = new P[size];
			for(int i = 0; i < size; i++)
				m[i] = new P(0,0,0);
			h = t = 0;
		}
		void clear(){
			h = t = 0;
		}
		void push(int x, int y, int tt){
//			System.err.println(x + " " + y);
			m[t++].set(x, y, tt);
		}
		void push(P e){
			m[t++].set(e);
		}
		P pop(){
			return m[h++];
		}
		boolean isEmpty(){
			return h == t;
		}
	}
	class QL{
		int m[];
		int h, t;
		QL(int size){
			m = new int[size];
			h = t = 0;
		}
		void push(int x){
//			System.err.println(x);
			m[t++] = x;
		}
		int pop(){
			return m[h++];
		}
		boolean isEmpty(){
			return h == t;
		}
		void clear(){
			h = t = 0;
		}
	}
	class P{
		int x, y, t;
		P(int xx, int yy, int tt){
			x = xx;
			y = yy;
			t = tt;
		}
		void set(int xx, int yy, int tt){
			x = xx;
			y = yy;
			t = tt;
		}
		void set(P e){
			x = e.x;
			y = e.y;
			t = e.t;
		}
		public String toString(){
			return x + " " + y  + " " + t + " |";
		}
	}
	void chk(boolean b) {
		if (b)
			return;
		System.out.println(new Error().getStackTrace()[1]);
		exit(999);
	}
	void deb(String fmt, Object... args) {
		System.out.printf(Locale.US, fmt + "%n", args);
	}
	String nextToken() throws IOException {
		while (!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}
	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}
	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}
	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}
	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}
}


import java.io.BufferedReader;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.List;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author AlexFetisov
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    private static final int INF = (int) 1e9;
    int n;
    int timeExplode;
    boolean[][] hasWall;
    int badStartX, badStartY;
    int[][] numberOfScientists;
    int[][] numberOfReactors;
    int[][] becomeBad;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        n = in.nextInt();
        timeExplode = in.nextInt();
        hasWall = new boolean[n][n];
        numberOfScientists = new int[n][n];
        numberOfReactors = new int[n][n];
        for (int i = 0; i < n; ++i) {
            String line = in.nextString();
            for (int j = 0; j < n; ++j) {
                char c = line.charAt(j);
                if (c == 'Z') {
                    badStartX = i;
                    badStartY = j;
                    hasWall[i][j] = true;
                } else if (c == 'Y') {
                    hasWall[i][j] = true;
                } else {
                    numberOfScientists[i][j] = c - '0';
                }
            }
        }
        for (int i = 0; i < n; ++i) {
            String line = in.nextString();
            for (int j = 0; j < n; ++j) {
                char c = line.charAt(j);
                if (Character.isDigit(c)) {
                    numberOfReactors[i][j] = c - '0';
                }
            }
        }

        becomeBad = new int[n][n];
        ArrayUtils.fill(becomeBad, INF);
        becomeBad[badStartX][badStartY] = 0;
        int[] qx = new int[n * n];
        int[] qy = new int[n * n];
        int qSize = 1;
        qx[0] = badStartX;
        qy[0] = badStartY;
        for (int qi = 0; qi < qSize; ++qi) {
            int cx = qx[qi];
            int cy = qy[qi];
            for (int d = 0; d < dx.length; ++d) {
                int nx = cx + dx[d];
                int ny = cy + dy[d];
                if (isValid(nx, ny, n)) {
                    if (!hasWall[nx][ny]) {
                        if (becomeBad[nx][ny] == INF) {
                            becomeBad[nx][ny] = becomeBad[cx][cy] + 1;
                            qx[qSize] = nx;
                            qy[qSize] = ny;
                            ++qSize;
                        }
                    }
                }
            }
        }

        Graph maxFlowGraph = new Graph();
        maxFlowGraph.initGraphWithFlow(n * n * 2 + 2, n * n * n * n * 4 * 3 + 10 * n * n + 100);

        int source = 0;
        int shiftForPerson = 1;
        int shiftForReactor = n * n + 1;
        int dest = n * n + n * n + 1;

        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (numberOfScientists[i][j] > 0) {
                    maxFlowGraph.addFlowEdge(source, i * n + j + shiftForPerson, numberOfScientists[i][j]);
                }
            }
        }
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (numberOfReactors[i][j] > 0) {
                    maxFlowGraph.addFlowEdge(i * n + j + shiftForReactor, dest, numberOfReactors[i][j]);
                }
            }
        }

        for (int xPerson = 0; xPerson < n; ++xPerson) {
            for (int yPerson = 0; yPerson < n; ++yPerson) {
                if (numberOfScientists[xPerson][yPerson] > 0) {
                    boolean[][] canReach = new boolean[n][n];
                    boolean[][] marked = new boolean[n][n];
                    boolean[][] newMarked = new boolean[n][n];
                    marked[xPerson][yPerson] = true;
                    canReach[xPerson][yPerson] = true;
                    for (int curTime = 0; curTime < timeExplode; ++curTime) {
                        for (int i = 0; i < n; ++i) {
                            for (int j = 0; j < n; ++j) {
                                if (marked[i][j]) {
                                    for (int d = 0; d < 4; ++d) {
                                        int ni = i + dx[d];
                                        int nj = j + dy[d];
                                        if (isValid(ni, nj, n)) {
                                            if (!hasWall[ni][nj]) {
                                                if (curTime + 1 <= becomeBad[ni][nj]) {
                                                    canReach[ni][nj] = true;
                                                }
                                                if (curTime + 1 < becomeBad[ni][nj]) {
                                                    newMarked[ni][nj] = true;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        for (int i = 0; i < n; ++i) {
                            for (int j = 0; j < n; ++j) {
                                marked[i][j] = newMarked[i][j];
                                newMarked[i][j] = false;
                            }
                        }
                    }
                    for (int xReactor = 0; xReactor < n; ++xReactor) {
                        for (int yReactor = 0; yReactor < n; ++yReactor) {
                            if (numberOfReactors[xReactor][yReactor] > 0) {
                                if (canReach[xReactor][yReactor]) {
                                    maxFlowGraph.addFlowEdge(xPerson * n + yPerson + shiftForPerson, xReactor * n + yReactor + shiftForReactor, INF);
                                }
                            }
                        }
                    }
                }
            }
        }
        long flow = MaxFlowDinic.dinic(maxFlowGraph, source, dest);
        out.println(flow);
    }

    private boolean isValid(int x, int y, int n) {
        return x >= 0 && y >= 0 && x < n && y < n;
    }

    int[] dx = new int[] {1, 0, -1, 0};
    int[] dy = new int[] {0, 1, 0, -1};
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(nextString());
    }

}

class ArrayUtils {

    public static void fill(int[][] f, int value) {
        for (int i = 0; i < f.length; ++i) {
            Arrays.fill(f[i], value);
        }
    }

}

class Graph {
    public int[] from;
    public int[] to;
    public int[] first;
    public int[] next;
    public int[] cost;
    public int[] capacity;
    public long[] flow;
    public int[] last;
    public int nVertex;
    public int nEdges;
    int[] reverseEdge;
    public int curEdge;

    public Graph() {}

    public void initGraphWithFlow(int n, int m) {
        curEdge = 0;
        nVertex = n;
        nEdges = m;
        from = new int[m * 2];
        to = new int[m * 2];
        first = new int[n];
        next = new int[m * 2];
        cost = new int[m * 2];
        capacity = new int[m * 2];
        flow = new long[m * 2];
        reverseEdge = new int[m * 2];
        last = new int[m * 2];
        Arrays.fill(first, -1);
        Arrays.fill(last, -1);
    }

    public void addFlowEdge(int a, int b, int f) {
//        System.err.println("Added edge " + a + " - " + b + " with flow: " + f);
        next[curEdge] = first[a];
        first[a] = curEdge;
        to[curEdge] = b;
        from[curEdge] = a;
        capacity[curEdge] = f;
        flow[curEdge] = 0;
        reverseEdge[curEdge] = curEdge + 1;
        ++curEdge;

        next[curEdge] = first[b];
        first[b] = curEdge;
        to[curEdge] = a;
        from[curEdge] = b;
        capacity[curEdge] = 0;
        flow[curEdge] = 0;
        reverseEdge[curEdge] = curEdge - 1;
        ++curEdge;
    }

    public final void pushFlow(int id, long fl) {
        if (fl == 0) {
            return;
        }
        flow[id] += fl;
        flow[id^1] -= fl;
    }

}

class MaxFlowDinic {
    private final Graph graph;
    private int source;
    private int dest;
    private int[] queue;
    private int[] distance;
    private int[] nextEdge;

    public MaxFlowDinic(Graph graph, int source, int dest) {
        this.graph = graph;
        this.source = source;
        this.dest = dest;
        int n = graph.nVertex;
        queue = new int[n];
        distance = new int[n];
        nextEdge = new int[n];
    }

    public static long dinic(Graph graph, int source, int destination) {
        return new MaxFlowDinic(graph, source, destination).dinic();
    }

    private long dinic() {
        long totalFlow = 0;
        while (true) {
            edgeDistances();
            if (distance[dest] == -1)
                break;
            Arrays.fill(nextEdge, -2);
            totalFlow += dinicImpl(source, Long.MAX_VALUE);
        }
        return totalFlow;
    }

    private void edgeDistances() {
        Arrays.fill(distance, -1);
        distance[source] = 0;
        int size = 1;
        queue[0] = source;
        for (int i = 0; i < size; i++) {
            int cur = queue[i];
            for (int id = graph.first[cur]; id != -1; id = graph.next[id]) {
                if (graph.capacity[id] > graph.flow[id]) {
                    int next = graph.to[id];
                    if (distance[next] == -1) {
                        distance[next] = distance[cur] + 1;
                        queue[size++] = next;
                    }
                }
            }
        }
    }

    private long dinicImpl(int source, long flow) {
        if (source == dest) {
            return flow;
        }
        if (flow == 0 || distance[source] == distance[dest]) {
            return 0;
        }
        int id = nextEdge[source];
        if (id == -2) {
            nextEdge[source] = id = graph.first[source];
        }
        long totalPushed = 0;
        while (id != -1) {
            int nextDestinationID = graph.to[id];
            if (graph.capacity[id] > graph.flow[id] && distance[nextDestinationID] == distance[source] + 1) {
                long pushed = dinicImpl(nextDestinationID, Math.min(flow, graph.capacity[id] - graph.flow[id]));
                if (pushed != 0) {
                    graph.pushFlow(id, pushed);
                    flow -= pushed;
                    totalPushed += pushed;
                    if (flow == 0)
                        return totalPushed;
                }
            }
            nextEdge[source] = id = graph.next[id];
        }
        return totalPushed;
    }

}


import java.lang.*;
import java.math.BigInteger;
import java.io.*;
import java.util.*;

public class Solution implements Runnable{
    public static BufferedReader br;
    public static PrintWriter out;
    public static StringTokenizer stk;
    public static boolean isStream = true;

    public static void main(String[] args) throws IOException {
    	if (isStream) {
            br = new BufferedReader(new InputStreamReader(System.in));
        } else {
            br = new BufferedReader(new FileReader("in.txt"));
        }
        out = new PrintWriter(System.out);
        new Thread(new Solution()).start();
    }

    public void loadLine() {
        try {
            stk = new StringTokenizer(br.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String nextLine() {
        try {
            return br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    public String nextWord() {
        while (stk==null||!stk.hasMoreTokens()) loadLine();
        return stk.nextToken();
    }

    public Integer nextInt() {
        while (stk==null||!stk.hasMoreTokens()) loadLine();
        return Integer.valueOf(stk.nextToken());
    }

    public Long nextLong() {
        while (stk==null||!stk.hasMoreTokens()) loadLine();
        return Long.valueOf(stk.nextToken());
    }

    public Double nextDouble() {
        while (stk==null||!stk.hasMoreTokens()) loadLine();
        return Double.valueOf(stk.nextToken());
    }

    public Float nextFloat() {
        while (stk==null||!stk.hasMoreTokens()) loadLine();
        return Float.valueOf(stk.nextToken());
    }

    int n;
    int t;
    int[][][] isBad;
    int[][][][][] can;

    int[] dx = new int[] {-1,1,0,0};
    int[] dy = new int[] {0,0,1,-1};

    int[][] map, flow;

    int INF = 1000000;

    int findFlow() {
    	int m = n*n*2+2;
    	int[] from = new int[m];
    	while (true) {
    		Arrays.fill(from, -1);
    		from[m-2] = -2;
	    	LinkedList<Integer> list = new LinkedList<Integer>();
	    	list.addFirst(m-2);
	    	while (list.size() != 0) {
	    		int cur = list.removeLast();
	    		for (int next = 0; next < m; next++) {
	    			if (map[cur][next] != -1 && from[next] == -1 && map[cur][next]-flow[cur][next] > 0) {
	    				from[next] = cur;
	    				list.addFirst(next);
	    			}
	    		}
	    	}
	    	if (from[m-1] != -1) {
	    		int min = Integer.MAX_VALUE;
	    		int pos = m-1;
	    		while (from[pos] != -2) {
	    			min = Math.min(min, map[from[pos]][pos]-flow[from[pos]][pos]);
	    			pos = from[pos];
	    		}
	    		pos = m-1;
	    		while (from[pos] != -2) {
	    			flow[from[pos]][pos] += min;
	    			flow[pos][from[pos]] -= min;
	    			pos = from[pos];
	    		}
	    	} else {
	    		break;
	    	}
    	}
    	int ans = 0;
    	for (int i = 0; i < m; i++) {
    		if (map[i][m-1] != -1) {
    			ans += flow[i][m-1];
    		}
    	}
    	return ans;
    }

    public void run() {
    	n = nextInt();
    	t = nextInt();
    	String[] ss1 = new String[n];
    	for (int i = 0; i < n; i++) {
    		ss1[i] = nextWord();
    	}
    	String[] ss2 = new String[n];
    	for (int i = 0; i < n; i++) {
    		ss2[i] = nextWord();
    	}

    	isBad = new int[t+1][n][n];
    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < n; j++) {
        		if (ss1[i].charAt(j) == 'Y') {
        			isBad[0][i][j] = 1;
        		}
        		if (ss1[i].charAt(j) == 'Z') {
        			isBad[0][i][j] = 2;
        		}
        	}
    	}
    	for (int tt = 1; tt <= t; tt++) {
    		for (int i = 0; i < n; i++) {
        		for (int j = 0; j < n; j++) {
        			isBad[tt][i][j] = isBad[tt-1][i][j];
        			if (isBad[tt][i][j] == 0) {
	            		for (int d = 0; d < 4; ++d) {
	            			if (i+dx[d] >= 0 && i+dx[d] < n && j+dy[d] >= 0 && j+dy[d] < n) {
		            			if (isBad[tt-1][i+dx[d]][j+dy[d]] == 2) {
		            				isBad[tt][i][j] = 2;
		            			}
	            			}
	            		}
        			}
            	}
        	}
    	}

    	can = new int[n][n][t+1][n][n];
    	for (int si = 0; si < n; si++) {
    		for (int sj = 0; sj < n; sj++) {
        		if (ss1[si].charAt(sj) >= '1' && ss1[si].charAt(sj) <= '9') {
        			can[si][sj][0][si][sj] = 1;
        			for (int tt = 1; tt <= t; tt++) {
        	    		for (int i = 0; i < n; i++) {
        	        		for (int j = 0; j < n; j++) {
        	        			if (isBad[tt-1][i][j] == 0) {
        		            		for (int d = 0; d < 4; ++d) {
        		            			if (i+dx[d] >= 0 && i+dx[d] < n && j+dy[d] >= 0 && j+dy[d] < n) {
	        		            			if (can[si][sj][tt-1][i+dx[d]][j+dy[d]] == 1 && isBad[tt-1][i+dx[d]][j+dy[d]] == 0) {
	        		            				can[si][sj][tt][i][j] = 1;
	        		            			}
        		            			}
        		            		}
        	        			}
        	            	}
        	        	}
        	    	}
        		}
        	}
    	}

    	map = new int[2*n*n+2][2*n*n+2];
    	flow = new int[2*n*n+2][2*n*n+2];
    	for (int i = 0; i < map.length; i++) {
    		Arrays.fill(map[i], -1);
    	}
    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < n; j++) {
        		if (ss1[i].charAt(j) >= '1' && ss1[i].charAt(j) <= '9') {
        			for (int ri = 0; ri < n; ri++) {
        	    		for (int rj = 0; rj < n; rj++) {
        	    			if (ss2[ri].charAt(rj) >= '1' && ss2[ri].charAt(rj) <= '9') {
	        	    			boolean f = false;
	        	    			for (int tt = 0; tt <= t; tt++) {
	        	    				if (can[i][j][tt][ri][rj] == 1) {
	        	    					f = true;
	        	    				}
	        	    			}
	        	        		if (f) {
	        	        			map[i*n+j][n*n+ri*n+rj] = INF;
	        	        			map[n*n+ri*n+rj][i*n+j] = 0;
	        	        		}
        	    			}
        	        	}
        	    	}
        		}
        	}
    	}

    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < n; j++) {
        		if (ss1[i].charAt(j) >= '1' && ss1[i].charAt(j) <= '9') {
        			map[n*n*2][i*n+j] = ss1[i].charAt(j) - '0';
        			map[i*n+j][n*n*2] = 0;
        		}
    		}
    	}

    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < n; j++) {
        		if (ss2[i].charAt(j) >= '1' && ss2[i].charAt(j) <= '9') {
        			map[n*n+i*n+j][n*n*2+1] = ss2[i].charAt(j) - '0';
        			map[n*n*2+1][n*n+i*n+j] = 0;
        		}
    		}
    	}

    	out.println(findFlow());

    	out.flush();
    }
}


import java.util.*;

public class Main {

	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);

		int N = sc.nextInt();
		int T = sc.nextInt();

		int[][] scientists = new int[N][N];
		int[][] capsules = new int[N][N];

		/* Create the graph:
		 * 		Bipartite graph with scientists U and capsules V
		 * 		Sink connecting to each scientist, Source connecting each capsule
		 * 		Edge between U and V if a scientist can reach a given capsule block
		 * 		at any time t.
		 *  */
		Node src = new Node(-1, -1); /* Defective reactor */
		Node sink = new Node(-1, -1);

		/* First matrix */
		Set<Node> U = new HashSet<Node>();

		for(int i = 0 ; i < N; i++){
			String line = sc.next();
			for(int j = 0 ; j < N; j++){
				if(line.charAt(j) == 'Y'){
					scientists[i][j] = -2;
				}
				else if(line.charAt(j) == 'Z'){
					scientists[i][j] = -1;
					src.x = i;
					src.y = j;
				}
				else if(line.charAt(j) != '0'){/* Create a node for the block. Add an edge from src to node with capacity = # of scientists */
					scientists[i][j] = (int)(line.charAt(j) -'0');
					Node temp = new Node(i, j);
					src.addEdge(new Edge(src, temp, scientists[i][j], 0));
					U.add(temp);
				}
			}
		}
		/* Second matrix */
		Set<Node> V = new HashSet<Node>();
		for(int i = 0 ; i < N; i++){
			String line = sc.next();
			for(int j = 0 ; j < N; j++){
				if(line.charAt(j) == 'Y'){
					capsules[i][j] = -2;
				}
				else if(line.charAt(j) == 'Z'){
					capsules[i][j] = -1;
				}
				else if(line.charAt(j) != '0'){/* Create a node for the block. Add an edge from node to sink with capacity = # of capsules */
					capsules[i][j] = (int)(line.charAt(j) - '0');
					Node temp = new Node(i, j);
					temp.addEdge(new Edge(temp, sink, capsules[i][j], 0));
					V.add(temp);
				}
			}
		}
		sc.close();

		/* Create a mapping for all the nodes in the graph for easy access as needed */
		Map<String, Node> U_map = new HashMap<String, Node>();
		for(Node s : U){
			U_map.put(s.x+"|"+s.y, s);
		}
		Map<String, Node> V_map = new HashMap<String, Node>();
		for(Node c : V){
			V_map.put(c.x+"|"+c.y, c);
		}

		/* BFS */
		// 1. Create a graph. The only way to access this graph is through set S
		Node z = null;
		Map<String, Node> mapping = new HashMap<String, Node>();
		Set<Node> S = new HashSet<Node>();
		for(int i = 0; i < N; i++){
			for(int j = 0; j < N; j++){
				Node n;
				if(mapping.containsKey(i+"|"+j)){
					n = mapping.get(i+"|"+j);
				}
				else{
					n = new Node(i, j);
					mapping.put(i+"|"+j, n);
				}
				Node right = null;
				Node down = null;
				//right node
				if(j+1 < N){
					right = mapping.get(i+"|"+(j+1));
					if(right == null){
						right = new Node(i, j+1);
					}
					n.edges.add(new Edge(n, right));
					right.edges.add(new Edge(right, n));
					mapping.put(i+"|"+(j+1), right);
				}
				//bottom node
				if(i+1 < N){
					down = mapping.get((i+1)+"|"+j);
					if(down == null){
						down = new Node(i+1, j);
					}
					n.edges.add(new Edge(n, down));
					down.edges.add(new Edge(down, n));
					mapping.put((i+1)+"|"+j, down);
				}
				if(scientists[i][j] == -1){
					n.scratch = -1;
					z = n;
				}
				else if(scientists[i][j] == -2){
					n.scratch = -2;
				}
				else if(scientists[i][j] == 0){
					n.scratch = 0;
				}
				else{
					S.add(n); //need to go through scientists to bfs
					n.scratch = 0;
				}
			}
		}

		Graph g1 = new Graph(null, null, new HashSet<Node>(mapping.values()));
		/* Find all the reachable nodes */

		/* Mark at which time the node was poisoned and mark at which time the bfs reached that block.
		 * If bfs reached it <= the time there then we know it's possible!!! */
		/* If scientists are already positioned at capsules, mark them as reachable */
		Set<Node> frontier_of_poison = new HashSet<Node>();
		frontier_of_poison.add(z);
		z.poisoned = 0;
		Set<String> visited_ = new HashSet<String>(); //optimization
		for(int t = 1; t<= T; t++){
			Set<Node> next = new HashSet<Node>();
			for(Node p : frontier_of_poison){
				for(Edge e : p.edges)
				{
					Node adj = e.v;
					if(adj.scratch >= 0 && !visited_.contains(adj.x+"|"+adj.y)){ /* mark all the reachable capsules with the time they are poisoned, all non-poisonable capsules are -1 */
						Node to_poison = V_map.get(adj.x+"|"+adj.y);
						adj.poisoned = t; //poison so that when we bfs, we check if the node visiting has been poisoned at an earlier time
						next.add(adj);
						if(to_poison != null){
							to_poison.poisoned = t;
						}
					}
					visited_.add(adj.x+"|"+adj.y);
				}
			}
			frontier_of_poison = next;
		}

		for(Node c : V){
			Node s = U_map.get(c.x+"|"+c.y);
			if(s != null){
				s.reachable_capsules.put(c.x+"|"+c.y, 0);
			}
		}
		for(Node s : S){
			Map<String, Integer> visited = new HashMap<String, Integer>(); //marks t (distance)
			Queue<Node> q = new LinkedList<Node>();

			Node original = U_map.get(s.x+"|"+s.y);

			q.add(s);
			visited.put(s.x+"|"+s.y, 0);
			while(!q.isEmpty()){
				Node curr = q.remove();
				int t_at_curr = visited.get(curr.x+"|"+curr.y);
				if(t_at_curr > T) break;
				for(Edge e : curr.edges){
					Node adj = e.v;
					if(!visited.containsKey(adj.x+"|"+adj.y) && adj.scratch >=0 ){
						visited.put(adj.x+"|"+adj.y, (t_at_curr + 1)); /* adj is reachable at curr's t + 1 */
						if(adj.poisoned >= (t_at_curr + 1) || adj.poisoned == -1){
							if(adj.poisoned != t_at_curr + 1) q.add(adj);
							if(capsules[adj.x][adj.y] > 0 && t_at_curr < T){ /* Only mark as reachable if there is even a capsule at that block */
								original.reachable_capsules.put(adj.x+"|"+adj.y, (t_at_curr + 1) ); /* All of this for this one line ^^; */
							}
						}
					}
				}
			}
		}

		/*Now supposedly we have marked all the nodes where they can visit. */

		//Add edges from s to c
		for(Node s: U){
			for(Node c : V){
				Integer time_reached = s.reachable_capsules.get(c.x+"|"+c.y);
				if(time_reached != null ){
					Edge e = new Edge(s, c, Integer.MAX_VALUE, 0);
					s.edges.add(e);
				}
			}
		}

		//now create the maxflow graph
		U.addAll(V);
		//create a backward edge --> current_flow value useless
		for(Node u: U){
			for(Edge e: u.edges){
				Edge x = new Edge(e.v, e.u, 0, 0, true);
				e.v.edges.add(x);
				e.ref = x;
			}
		}
		Graph g = new Graph(src, sink, U);
		int max = g.ford_fulkerson();
		System.out.println(max);
	}

	/* create a graph with matrix. Do bfs from */
	public static class Node{
		int x; /* Indicate the position of the block */
		int y;
		Map<String, Integer> reachable_capsules; /* all the capsules the scientist can reach at time t */
		int scratch;
		int poisoned;
		boolean visited; /* used to compute the max flow */
		ArrayList<Edge> edges;

		public Node(int x, int y){
			this.x = x;
			this.y = y;
			poisoned = -1; /* -1 --> never poisoned, 0 <= t <= 60 time poisoned */
			visited = false;
			edges = new ArrayList<Edge>();
			reachable_capsules = new HashMap<String, Integer>();
		}

		public void addEdge(Edge e){
			this.edges.add(e);
		}
	}

	public static class Edge{
		Node u, v;
		int remaining_capacity;
		boolean back;
		Edge ref;

		public Edge(Node u, Node v, int c, int f){
			this.u = u;
			this.v = v;
			this.remaining_capacity = c;
			back = false;
			ref = null;
		}
		public Edge(Node u, Node v, int c, int f, boolean b){
			this.u = u;
			this.v = v;
			this.remaining_capacity = c;
			back = b;
			ref = null;
		}
		/*For the simple graph to bfs */
		public Edge(Node u, Node v){
			this.u = u;
			this.v = v;
		}
	}

	public static class Graph{
		private Node s;
		private Node t;
		private Set<Node> nodes;
		public Graph(Node s, Node t, Set<Node> nodes){
			this.s = s;
			this.t = t;
			this.nodes = nodes;
		}

		public void clearVisited(){
			for(Node n : nodes)
				n.visited = false;
			s.visited = false;
			t.visited = false;
		}

		public int ford_fulkerson(){
			int max_flow = 0;
		    int f;
		    int x =1;
			while ((f = get_augmenting_path(s, Integer.MAX_VALUE)) != 0){
				clearVisited();
				max_flow += f;
			}
		    return max_flow;
		}

		/* Finds an augmenting s-t path using dfs and adjusts the flow using the bottleneck found along that path*/
		public int get_augmenting_path(Node n, int bottleneck){
			if(n == t) //base case
				return bottleneck;
			if(n.visited){
				return 0;
			}
			n.visited = true;

			int b;
			for(Edge adj: n.edges){
		    	  if((adj.remaining_capacity > 0) && !adj.v.visited){
		    		    if(bottleneck > adj.remaining_capacity)
		    		    	bottleneck = adj.remaining_capacity;
			            b = get_augmenting_path(adj.v, bottleneck);
			            if(b > 0){
			    			augment(adj, b);
				            return b;
			            }
		    	  }
		      }
		      return 0;
		}

		public void augment(Edge e, int bottleneck){
			e.remaining_capacity -= bottleneck;
			if(e.ref != null) e.ref.remaining_capacity += bottleneck;
		}

	}

}


import java.util.Scanner;

public class Main{
    public static void main (String[] args){
        Scanner scanner = new Scanner(System.in);
        int n= scanner.nextInt();
        String str = scanner.next();
        int count =0;
        if(str.length()>1) {
            for (int i = 0; i < str.length() - 1; i++) {
                if (str.charAt(i) != str.charAt(i + 1)) {
                    i++;
                }
                count++;
            }
            if (str.length()>2) {
                if (str.charAt(str.length() - 1) == str.charAt(str.length() - 2)|| str.charAt(str.length() - 2) != str.charAt(str.length() - 3)) {
                    System.out.print(count + 1);
                }else {
                    System.out.print(count);
                }
            }else {
                System.out.print(count);
            }
        }else {
            System.out.print(1);
        }
    }
}


import java.util.Scanner;

public class a {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		long hpy = in.nextInt();
		long atky = in.nextInt();
		long defy = in.nextInt();
		long hpm = in.nextInt();
		long atkm = in.nextInt();
		long defm = in.nextInt();
		long h = in.nextInt();
		long a = in.nextInt();
		long d = in.nextInt();
		long min = Long.MAX_VALUE;
		for(int def = 0; true;def++){
			long dps = Math.max(0, atkm-defy-def);
			for(int atk = 0; true;atk++){
				long mydps = Math.max(0, atky+atk-defm);
				if(mydps==0)continue;
				long secondsToKill = (hpm+mydps-1)/mydps;
				long hpneeded = Math.max(0,(secondsToKill)*dps+1-hpy);
				long cost = h*hpneeded+a*atk+d*def;
				if(cost<min){
					min = cost;
				}
				if(secondsToKill==1)break;
			}
			if(dps==0)break;
		}
		System.out.println(min);
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class solution {
    public static void merge(long arr[], int l, int m, int r) {
        int n1 = m - l + 1;
        int n2 = r - m;
        long L[] = new long[n1];
        long R[] = new long[n2];
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];

        int i = 0, j = 0;

        int k = l;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    public static void sort(long arr[], int l, int r) {
        if (l < r) {
            int m = (l + r) / 2;

            sort(arr, l, m);
            sort(arr, m + 1, r);

            merge(arr, l, m, r);
        }
    }

    public static boolean check(int n) {
        String s = "";
        s += n;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) != '4' && s.charAt(i) != '7') {
                return false;
            }
        }
        return true;
    }

    public static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        } else {
            return gcd(b, a % b);
        }
    }

    public static long findTrailingZeros(long n) {
        // Initialize result
        long count = 0;

        // Keep dividing n by powers
        // of 5 and update count
        for (long i = 5; n / i >= 1; i *= 5)
            count += n / i;

        return count;
    }

    public static int ceilSearch(long arr[], int low, int high, long x) {
        int mid;

        if (x <= arr[low])
            return low;
        if (x > arr[high])
            return -1;

        mid = (low + high) / 2;

        if (arr[mid] == x)
            return mid;

        else if (arr[mid] < x) {
            if (mid + 1 <= high && x <= arr[mid + 1])
                return mid + 1;
            else
                return ceilSearch(arr, mid + 1, high, x);
        } else {
            if (mid - 1 >= low && x > arr[mid - 1])
                return mid;
            else
                return ceilSearch(arr, low, mid - 1, x);
        }
    }

    public static double dis(double x, double x1, double y, double y1) {
        double dis = Math.sqrt(Math.pow((x - x1), 2) + Math.pow((y - y1), 2));
        return dis;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        StringBuilder s1 = new StringBuilder(s).reverse();
        if (!s.equals(s1.toString())) {
            System.out.println(s.length());
        } else {
            int count = 0;
            HashSet<Character> H = new HashSet<>();
            for (int i = 0; i < s.length(); i++) {
                H.add(s.charAt(i));
            }
            if (H.size() == 1) {
                System.out.println(0);
            }
            else{
                System.out.println(s.length()-1);
            }
        }
    }
}


import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
/**
 * Erasyl Abenov
 *
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
            try (PrintWriter out = new PrintWriter(outputStream)) {
                Task solver = new Task();
                solver.solve(1, in, out);
            }
    }
}

class Task {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int m = in.nextInt();
        int g[][] = new int[n + 1][n + 1];
        int c[] = new int[n + 1];
        for(int i = 1; i <= n; ++i){
            g[i][i] = 1;
        }
        for(int i = 0; i < m; ++i){
            int x = in.nextInt();
            int y = in.nextInt();
            g[x][y] = 1;
            g[y][x] = 1;
            c[x]++;
            c[y]++;
        }
        char ans[] = new char[n + 1];
        Arrays.fill(ans, ' ');
        int f = 0;
        for(int i = 1; i <= n; ++i){
            if(c[i] == n - 1) ans[i] = 'b';
        }
        for(int i = 1; i <= n; ++i){
            if(ans[i] == ' '){
                ans[i] = 'a';
                for(int j = 1; j <= n; ++j){
                    if(ans[j] == ' '){
                        if(g[i][j] == 1) ans[j] = 'a';
                        else ans[j] = 'c';
                    }
                }
            }
        }
        for(int i = 1; i <= n; ++i){
            for(int j = 1; j <= n; ++j){
                if(i != j){
                    if(Math.abs(ans[i] - ans[j]) == 2 && g[i][j] == 1 ||
                            (Math.abs(ans[i] - ans[j]) < 2 && g[i][j] == 0)){
                        out.println("No");
                        return;
                    }
                }
            }
        }
        out.println("Yes");
        for(int i = 1; i <= n; ++i) out.print(ans[i]);
    }

}

class InputReader {
    private final BufferedReader reader;
    private StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(nextLine());
        }
        return tokenizer.nextToken();
    }
    public double nextDouble() {
        return Double.valueOf(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }
    public long nextLong() {
        return Long.parseLong(next());
    }
    public BigInteger nextBig() {
        return new BigInteger(next());
    }
}
 class IOUtils {
    public static void readIntArrays(InputReader in, int[]... arrays) {
        for (int i = 0; i < arrays[0].length; i++) {
            for (int[] array : arrays) {
                array[i] = in.nextInt();
            }
        }
    }
}


import java.io.*;
import java.util.Comparator;
import java.util.Scanner;

public class Z {

	Scanner in;
	PrintWriter out;

	private class line {
		int x1, y1, x2, y2;
		line(int x1, int y1, int x2, int y2) {
			this.x1 = x1; this.y1 = y1;
			this.x2 = x2; this.y2 = y2;
		}
	}

	void run() throws IOException {
		//in = new Scanner(new File("input.txt"));
		//out = new PrintWriter("output.txt");
		in = new Scanner(System.in);
		out = new PrintWriter(System.out);

		line[] ln = new line[4];

		for(int i = 0; i < 4; i++) {
			ln[i] = new line(in.nextInt(), in.nextInt(), in.nextInt(), in.nextInt());
		}

		for(int i = 0; i < 4; i++)
			for(int j = 0; j < 4; j++)
				for(int k = 0; k < 4; k++)
					for(int h = 0; h < 4; h++) {
						if(i == j || i == k || i == h || j == k || j == h || k == h)
							continue;
						if(ln[i].y1 != ln[i].y2 || ln[j].x1 != ln[j].x2 || ln[k].x1 != ln[k].x2 || ln[h].y1 != ln[h].y2)
							continue;
						if(((ln[i].x1 == ln[h].x1) && (ln[i].y1 == ln[h].y1)) || ((ln[i].x1 == ln[h].x2) && (ln[i].y1 == ln[h].y2)))
							continue;
if(((ln[j].x1 == ln[k].x1) && (ln[j].y1 == ln[k].y1)) || ((ln[j].x1 == ln[k].x2) && (ln[j].y1 == ln[k].y2)))
							continue;
						int flag = 0;
						if((ln[i].x1 == ln[j].x1) && (ln[i].y1 == ln[j].y1) && (ln[h].x1 == ln[j].x2) && (ln[h].y1 == ln[j].y2) || (ln[i].x1 == ln[j].x2) && (ln[i].y1 == ln[j].y2) && (ln[h].x1 == ln[j].x1) && (ln[h].y1 == ln[j].y1))
							flag++;
						if((ln[i].x2 == ln[j].x1) && (ln[i].y2 == ln[j].y1) && (ln[h].x1 == ln[j].x2) && (ln[h].y1 == ln[j].y2) || (ln[i].x2 == ln[j].x2) && (ln[i].y2 == ln[j].y2) && (ln[h].x1 == ln[j].x1) && (ln[h].y1 == ln[j].y1))
							flag++;
						if((ln[i].x1 == ln[j].x1) && (ln[i].y1 == ln[j].y1) && (ln[h].x2 == ln[j].x2) && (ln[h].y2 == ln[j].y2) || (ln[i].x1 == ln[j].x2) && (ln[i].y1 == ln[j].y2) && (ln[h].x2 == ln[j].x1) && (ln[h].y2 == ln[j].y1))
							flag++;
						if((ln[i].x2 == ln[j].x1) && (ln[i].y2 == ln[j].y1) && (ln[h].x2 == ln[j].x2) && (ln[h].y2 == ln[j].y2) || (ln[i].x2 == ln[j].x2) && (ln[i].y2 == ln[j].y2) && (ln[h].x2 == ln[j].x1) && (ln[h].y2 == ln[j].y1))
							flag++;
						if(flag == 0)
							continue;
						flag = 0;
						if((ln[i].x1 == ln[k].x1) && (ln[i].y1 == ln[k].y1) && (ln[h].x1 == ln[k].x2) && (ln[h].y1 == ln[k].y2) || (ln[i].x1 == ln[k].x2) && (ln[i].y1 == ln[k].y2) && (ln[h].x1 == ln[k].x1) && (ln[h].y1 == ln[k].y1))
							flag++;
						if((ln[i].x2 == ln[k].x1) && (ln[i].y2 == ln[k].y1) && (ln[h].x1 == ln[k].x2) && (ln[h].y1 == ln[k].y2) || (ln[i].x2 == ln[k].x2) && (ln[i].y2 == ln[k].y2) && (ln[h].x1 == ln[k].x1) && (ln[h].y1 == ln[k].y1))
							flag++;
						if((ln[i].x1 == ln[k].x1) && (ln[i].y1 == ln[k].y1) && (ln[h].x2 == ln[k].x2) && (ln[h].y2 == ln[k].y2) || (ln[i].x1 == ln[k].x2) && (ln[i].y1 == ln[k].y2) && (ln[h].x2 == ln[k].x1) && (ln[h].y2 == ln[k].y1))
							flag++;
						if((ln[i].x2 == ln[k].x1) && (ln[i].y2 == ln[k].y1) && (ln[h].x2 == ln[k].x2) && (ln[h].y2 == ln[k].y2) || (ln[i].x2 == ln[k].x2) && (ln[i].y2 == ln[k].y2) && (ln[h].x2 == ln[k].x1) && (ln[h].y2 == ln[k].y1))
							flag++;
						if(flag == 0)
							continue;
						out.print("YES");
						out.flush();
						return;
					}
		out.print("NO");
		out.flush();
	}

	public static void main(String[] args) throws IOException {
		new Z().run();
	}

}


import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.io.*;

public class Equalizing_by_Division_easy_version {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int k = Integer.parseInt(st.nextToken());
		Integer[] arr = new Integer[n];
		st = new StringTokenizer(br.readLine());
		int idx = 0;
		int max = -1;
		for (int i = 0; i < n; i++) {
			int x = Integer.parseInt(st.nextToken());
			arr[i] = x;
			max = Math.max(max, x);
		}
		int num = 0;
		int count = 0;
		int ans = Integer.MAX_VALUE;
		Arrays.sort(arr);

		for (int i = 1; i <= max; i++) {
			int steps=0;
			for (int j = 0; j < n; j++) {
				count=0;
				if (arr[j] == i) {
					num++;
					if (num == k) {
						break;
					}
					continue;
				} else {
					int x = arr[j];
					while (x > i) {
						x /= 2;
						count++;
					}
					if (x == i) {
						num++;
						steps+=count;
					}
				}
				if (num == k) {
					break;
				}
			}
			//System.out.println(count);
			if (num == k) {
				ans = Math.min(ans, steps);
			}
			num = 0;
			count = 0;
		}
		pw.println(ans);
		pw.flush();
		pw.close();

	}
}


import java.io.Writer;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.*;
import java.io.*;
import java.math.*;
import java.util.concurrent.TimeUnit;
public class check {
    public static int find(ArrayList<Integer> inp, int n, int target){
        Collections.sort(inp);
        Collections.reverse(inp);
        int res = 0;
        int num = n;
        for(int i = 0;i<n && num>0;i++){
            int curr = inp.get(i);
            int times = target/curr;
            if(target%curr != 0)
                times++;
            if(times*curr<=target)
                times++;
            if(times>num)
                return res;
            num = num-times;
            res++;
        }
        return res;
    }

    public static void main(String args[]) throws java.lang.Exception{
        Scanner in;
        try{
            in = new Scanner(new FileReader("./input.txt"));
        }
        catch(Exception e){
            in = new Scanner(System.in);
        }
        int n = in.nextInt();
        n = n-1;

        if(n == 0){
            System.out.println(3);
            return;
        }
        if(n == 1){
            System.out.println(5);
            return;
        }

        long gp = (n-2)/3;
        long pos = (n-2)%3;

        long base = 5+gp*4;
        if(pos == 0){
            base = base+2;
        }
        else if(pos == 1)
            base = base+3;
        else
            base = base+4;

        System.out.println(base);
    }
}


import java.io.*;

import java.awt.geom.Point2D;
import java.text.*;
import java.math.*;
import java.util.*;

public class Main implements Runnable {

	final String filename = "";

	public void solve() throws Exception {
		int n = iread();
		if(n%2==0) {
			out.write(0+"");
		}
		else {
			out.write(1+"");
		}

	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new BufferedWriter(new OutputStreamWriter(System.out));
			// in = new BufferedReader(new FileReader(filename+".in"));
			// out = new BufferedWriter(new FileWriter(filename+".out"));
			solve();
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	public int iread() throws Exception {
		return Integer.parseInt(readword());
	}

	public double dread() throws Exception {
		return Double.parseDouble(readword());
	}

	public long lread() throws Exception {
		return Long.parseLong(readword());
	}

	BufferedReader in;

	BufferedWriter out;

	public String readword() throws IOException {
		StringBuilder b = new StringBuilder();
		int c;
		c = in.read();
		while (c >= 0 && c <= ' ')
			c = in.read();
		if (c < 0)
			return "";
		while (c > ' ') {
			b.append((char) c);
			c = in.read();
		}
		return b.toString();
	}

	public static void main(String[] args) {
		try {
			Locale.setDefault(Locale.US);
		} catch (Exception e) {

		}
		// new Thread(new Main()).start();
		new Thread(null, new Main(), "1", 1 << 25).start();
	}
}


import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;

/*
br = new BufferedReader(new FileReader("input.txt"));
pw = new PrintWriter(new BufferedWriter(new FileWriter("output.txt")));
br = new BufferedReader(new InputStreamReader(System.in));
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
 */

public class Main {
  private static BufferedReader br;
  private static StringTokenizer st;
  private static PrintWriter pw;

  public static void main(String[] args) throws IOException {
    br = new BufferedReader(new InputStreamReader(System.in));
    pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    //int qq = 1;
    int qq = Integer.MAX_VALUE;
    //int qq = readInt();
    for(int casenum = 1; casenum <= qq; casenum++)  {
      int n = readInt();
      int k = readInt();
      int[] p = new int[n];
      int[] e = new int[n];
      for(int i = 0; i < n; i++) {
        p[i] = readInt();
        e[i] = readInt();
      }
      int ret = Integer.MAX_VALUE;
      for(int mask = 0; mask < 1 << n; mask++) {
        int points = Integer.bitCount(mask);
        int loser = n;
        int effort = 0;
        for(int i = 0; i < n; i++) {
          if((mask&(1<<i)) != 0) {
            effort += e[i];
          }
          else {
            p[i]++;
          }
          if(points > p[i] || (points == p[i] && (mask&(1<<i)) != 0)) {
            loser--;
          }
          if((mask&(1<<i)) == 0) {
            p[i]--;
          }
        }
        if(loser < k) {
          ret = Math.min(ret, effort);
        }
      }
      if(ret == Integer.MAX_VALUE) {
        ret = -1;
      }
      pw.println(ret);
    }
    pw.close();
  }

  private static void exitImmediately() {
    pw.close();
    System.exit(0);
  }

  private static long readLong() throws IOException {
    return Long.parseLong(nextToken());
  }

  private static double readDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }

  private static int readInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

  private static String nextToken() throws IOException  {
    while(st == null || !st.hasMoreTokens())  {
      if(!br.ready()) {
        exitImmediately();
      }
      st = new StringTokenizer(br.readLine().trim());
    }
    return st.nextToken();
  }
}


/**
 * DA-IICT
 * Author : Savaliya Sagar
 */
import java.io.*;
import java.math.*;
import java.util.*;

public class B900 {
	void solve() {
		int a = ni();
		int b = ni();
		int c = ni();
		HashSet<Integer> h = new HashSet<>();
		int p = 1;
		while(true) {
			a *= 10;
			if(a/b==c) {
				out.println(p);
				return;
			}
			a = a%b;
			if(!h.add(a)) {
				out.print(-1);
				return;
			}
			p++;
		}
	}

	void run() throws Exception {
		out = new PrintWriter(System.out);
		reader = new BufferedReader(new InputStreamReader(System.in), 32768);
		tokenizer = null;
		solve();
		out.flush();
	}

	BufferedReader reader;
	StringTokenizer tokenizer;
	PrintWriter out;

	public static void main(String[] args) throws Exception {
		new B900().run();
	}
	public int ni() {
		return Integer.parseInt(next());
	}
	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}
}


import java.util.*;
public class a {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        int[] dp = new int[n+1];
        for(int i = 1; i<=n; i++)
        {
            dp[i] = 2 + dp[i-1];
            if(i == 1) dp[i]--;
            if(i > 1) dp[i] += dp[i-2];
            dp[i] %= 1000000007;
        }
        System.out.println(dp[n]);
    }
}


import java.awt.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.List;

import static java.lang.Math.max;
import static java.lang.Math.min;

public class B implements Runnable{

    // SOLUTION!!!
    // HACK ME PLEASE IF YOU CAN!!!
    // PLEASE!!!
    // PLEASE!!!
    // PLEASE!!!

    private final static Random rnd = new Random();
    private final static String fileName = "";

    private final static String ENTER = "+", EXIT = "-";

    private void solve() {
        int n = readInt();
        int m = readInt();

        boolean[] canBeLeader = new boolean[n];
        Arrays.fill(canBeLeader, true);

        class Event {
            boolean enter;
            int index;

            public Event(String type, int index) {
                this.enter = ENTER.equals(type);
                this.index = index;
            }
        }

        Event[] inputEvents = new Event[m];
        for (int i = 0; i < m; ++i) {
            inputEvents[i] = new Event(readString(), readInt() - 1);
        }

        int startMeetingSize = 0;

        Set<Integer> wasBefore = new HashSet<>();

        boolean[] used = new boolean[n];
        for (Event inputEvent : inputEvents) {
            if (!inputEvent.enter && !used[inputEvent.index]) {
                wasBefore.add(inputEvent.index);
            }

            used[inputEvent.index] = true;
        }

        SortedSet<Integer> zeros = new TreeSet<>();

        int meetingSize = wasBefore.size();
        for (Event event : inputEvents) {
            if (event.enter) {
                if (meetingSize != 0) {
                    canBeLeader[event.index] = false;
                } else {
                    zeros.add(event.index);
                }

                ++meetingSize;
            } else {
                --meetingSize;

                if (meetingSize != 0) {
                    canBeLeader[event.index] = false;
                } else {
                    zeros.add(event.index);
                }
            }
        }

        if (zeros.size() > 1) {
            for (int index : zeros) {
                canBeLeader[index] = false;
            }
        } else if (zeros.size() == 1){
            int zeroEnter = zeros.first();

            if (wasBefore.size() > 0 && !wasBefore.contains(zeroEnter)) {
                canBeLeader[zeroEnter] = false;
            }
        }

        List<Integer> possibleLeaders = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            if (canBeLeader[i]) possibleLeaders.add(i);
        }

        out.println(possibleLeaders.size());
        for (int leader : possibleLeaders) {
            out.print((leader + 1) + " ");
        }
        out.println();
    }

    /////////////////////////////////////////////////////////////////////

    private final static boolean FIRST_INPUT_STRING = false;
    private final static boolean MULTIPLE_TESTS = true;
    private final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

    private final static int MAX_STACK_SIZE = 128;

    private final static boolean OPTIMIZE_READ_NUMBERS = false;

    /////////////////////////////////////////////////////////////////////

    public void run(){
        try{
            timeInit();
            Locale.setDefault(Locale.US);

            init();

            if (ONLINE_JUDGE) {
                solve();
            } else {
                do {
                    try {
                        timeInit();
                        solve();
                        time();

                        out.println();
                    } catch (NumberFormatException e) {
                        break;
                    } catch (NullPointerException e) {
                        if (FIRST_INPUT_STRING) break;
                        else throw e;
                    }
                } while (MULTIPLE_TESTS);
            }

            out.close();
            time();
        }catch (Exception e){
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private BufferedReader in;
    private OutputWriter out;
    private StringTokenizer tok = new StringTokenizer("");

    public static void main(String[] args){
        new Thread(null, new B(), "", MAX_STACK_SIZE * (1L << 20)).start();
    }

    /////////////////////////////////////////////////////////////////////

    private void init() throws FileNotFoundException{
        Locale.setDefault(Locale.US);

        if (ONLINE_JUDGE){
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new OutputWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new OutputWriter(fileName + ".out");
            }
        }else{
            in = new BufferedReader(new FileReader("input.txt"));
            out = new OutputWriter("output.txt");
        }
    }

    ////////////////////////////////////////////////////////////////

    private long timeBegin;

    private void timeInit() {
        this.timeBegin = System.currentTimeMillis();
    }

    private void time(){
        long timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    private void debug(Object... objects){
        if (ONLINE_JUDGE){
            for (Object o: objects){
                System.err.println(o.toString());
            }
        }
    }

    /////////////////////////////////////////////////////////////////////

    private String delim = " ";

    private String readLine() {
        try {
            return in.readLine();
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private String readString() {
        try {
            while(!tok.hasMoreTokens()){
                tok = new StringTokenizer(readLine());
            }

            return tok.nextToken(delim);
        } catch (NullPointerException e) {
            return null;
        }
    }

    /////////////////////////////////////////////////////////////////

    private final char NOT_A_SYMBOL = '\0';

    private char readChar() {
        try {
            int intValue = in.read();

            if (intValue == -1){
                return NOT_A_SYMBOL;
            }

            return (char) intValue;
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        }
    }

    private char[] readCharArray() {
        return readLine().toCharArray();
    }

    private char[][] readCharField(int rowsCount) {
        char[][] field = new char[rowsCount][];
        for (int row = 0; row < rowsCount; ++row) {
            field[row] = readCharArray();
        }

        return field;
    }

    /////////////////////////////////////////////////////////////////

    private long optimizedReadLong() {
        int sign = 1;
        long result = 0;
        boolean started = false;
        while (true) {
            try {
                int j = in.read();
                if (-1 == j) {
                    if (started) return sign * result;
                    throw new NumberFormatException();
                }

                if (j == '-') {
                    if (started) throw new NumberFormatException();
                    sign = -sign;
                }

                if ('0' <= j && j <= '9') {
                    result = result * 10 + j - '0';
                    started = true;
                } else if (started) {
                    return sign * result;
                }
            } catch (IOException e) {
                throw new RuntimeIOException(e);
            }
        }
    }

    private int readInt() {

        if (!OPTIMIZE_READ_NUMBERS) {
            return Integer.parseInt(readString());
        } else {
            return (int) optimizedReadLong();
        }
    }

    private int[] readIntArray(int size) {
        int[] array = new int[size];

        for (int index = 0; index < size; ++index){
            array[index] = readInt();
        }

        return array;
    }

    private int[] readSortedIntArray(int size) {
        Integer[] array = new Integer[size];

        for (int index = 0; index < size; ++index) {
            array[index] = readInt();
        }
        Arrays.sort(array);

        int[] sortedArray = new int[size];
        for (int index = 0; index < size; ++index) {
            sortedArray[index] = array[index];
        }

        return sortedArray;
    }

    private int[] readIntArrayWithDecrease(int size) {
        int[] array = readIntArray(size);

        for (int i = 0; i < size; ++i) {
            array[i]--;
        }

        return array;
    }

    ///////////////////////////////////////////////////////////////////

    private int[][] readIntMatrix(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArray(columnsCount);
        }

        return matrix;
    }

    private int[][] readIntMatrixWithDecrease(int rowsCount, int columnsCount) {
        int[][] matrix = new int[rowsCount][];

        for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
            matrix[rowIndex] = readIntArrayWithDecrease(columnsCount);
        }

        return matrix;
    }

    ///////////////////////////////////////////////////////////////////

    private long readLong() {
        if (!OPTIMIZE_READ_NUMBERS) {
            return Long.parseLong(readString());
        } else {
            return optimizedReadLong();
        }
    }

    private long[] readLongArray(int size) {
        long[] array = new long[size];

        for (int index = 0; index < size; ++index){
            array[index] = readLong();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private double readDouble() {
        return Double.parseDouble(readString());
    }

    private double[] readDoubleArray(int size) {
        double[] array = new double[size];

        for (int index = 0; index < size; ++index){
            array[index] = readDouble();
        }

        return array;
    }

    ////////////////////////////////////////////////////////////////////

    private BigInteger readBigInteger() {
        return new BigInteger(readString());
    }

    private BigDecimal readBigDecimal() {
        return new BigDecimal(readString());
    }

    /////////////////////////////////////////////////////////////////////

    private Point readPoint() {
        int x = readInt();
        int y = readInt();
        return new Point(x, y);
    }

    private Point[] readPointArray(int size) {
        Point[] array = new Point[size];

        for (int index = 0; index < size; ++index){
            array[index] = readPoint();
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    @Deprecated
    private List<Integer>[] readGraph(int vertexNumber, int edgeNumber) {
        @SuppressWarnings("unchecked")
        List<Integer>[] graph = new List[vertexNumber];

        for (int index = 0; index < vertexNumber; ++index){
            graph[index] = new ArrayList<>();
        }

        while (edgeNumber-- > 0){
            int from = readInt() - 1;
            int to = readInt() - 1;

            graph[from].add(to);
            graph[to].add(from);
        }

        return graph;
    }

    private static class GraphBuilder {

        final int size;
        final List<Integer>[] edges;

        static GraphBuilder createInstance(int size) {
            List<Integer>[] edges = new List[size];
            for (int v = 0; v < size; ++v) {
                edges[v] = new ArrayList<>();
            }

            return new GraphBuilder(edges);
        }

        private GraphBuilder(List<Integer>[] edges) {
            this.size = edges.length;
            this.edges = edges;
        }

        public void addEdge(int from, int to) {
            addDirectedEdge(from, to);
            addDirectedEdge(to, from);
        }

        public void addDirectedEdge(int from, int to) {
            edges[from].add(to);
        }

        public int[][] build() {
            int[][] graph = new int[size][];
            for (int v = 0; v < size; ++v) {
                List<Integer> vEdges = edges[v];
                graph[v] = castInt(vEdges);
            }

            return graph;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IntIndexPair {

        static Comparator<IntIndexPair> increaseComparator = new Comparator<B.IntIndexPair>() {

            @Override
            public int compare(B.IntIndexPair indexPair1, B.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return value1 - value2;

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        static Comparator<IntIndexPair> decreaseComparator = new Comparator<B.IntIndexPair>() {

            @Override
            public int compare(B.IntIndexPair indexPair1, B.IntIndexPair indexPair2) {
                int value1 = indexPair1.value;
                int value2 = indexPair2.value;

                if (value1 != value2) return -(value1 - value2);

                int index1 = indexPair1.index;
                int index2 = indexPair2.index;

                return index1 - index2;
            }
        };

        int value, index;

        IntIndexPair(int value, int index) {
            super();
            this.value = value;
            this.index = index;
        }

        int getRealIndex() {
            return index + 1;
        }
    }

    private IntIndexPair[] readIntIndexArray(int size) {
        IntIndexPair[] array = new IntIndexPair[size];

        for (int index = 0; index < size; ++index) {
            array[index] = new IntIndexPair(readInt(), index);
        }

        return array;
    }

    /////////////////////////////////////////////////////////////////////

    private static class OutputWriter extends PrintWriter {

        final int DEFAULT_PRECISION = 12;

        private int precision;
        private String format, formatWithSpace;

        {
            precision = DEFAULT_PRECISION;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        OutputWriter(OutputStream out) {
            super(out);
        }

        OutputWriter(String fileName) throws FileNotFoundException {
            super(fileName);
        }

        int getPrecision() {
            return precision;
        }

        void setPrecision(int precision) {
            precision = max(0, precision);
            this.precision = precision;

            format = createFormat(precision);
            formatWithSpace = format + " ";
        }

        String createFormat(int precision){
            return "%." + precision + "f";
        }

        @Override
        public void print(double d){
            printf(format, d);
        }

        void printWithSpace(double d){
            printf(formatWithSpace, d);
        }

        void printAll(double...d){
            for (int i = 0; i < d.length - 1; ++i){
                printWithSpace(d[i]);
            }

            print(d[d.length - 1]);
        }

        @Override
        public void println(double d){
            printlnAll(d);
        }

        void printlnAll(double... d){
            printAll(d);
            println();
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class RuntimeIOException extends RuntimeException {

        /**
         *
         */
        private static final long serialVersionUID = -6463830523020118289L;

        RuntimeIOException(Throwable cause) {
            super(cause);
        }
    }

    /////////////////////////////////////////////////////////////////////
    //////////////// Some useful constants and functions ////////////////
    /////////////////////////////////////////////////////////////////////

    private static final int[][] steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    private static final int[][] steps8 = {
            {-1, 0}, {1, 0}, {0, -1}, {0, 1},
            {-1, -1}, {1, 1}, {1, -1}, {-1, 1}
    };

    private static boolean checkCell(int row, int rowsCount, int column, int columnsCount) {
        return checkIndex(row, rowsCount) && checkIndex(column, columnsCount);
    }

    private static boolean checkIndex(int index, int lim){
        return (0 <= index && index < lim);
    }

    /////////////////////////////////////////////////////////////////////

    private static boolean checkBit(int mask, int bit){
        return (mask & (1 << bit)) != 0;
    }
    private static boolean checkBit(long mask, int bit){
        return (mask & (1L << bit)) != 0;
    }

    /////////////////////////////////////////////////////////////////////

    private static long getSum(int[] array) {
        long sum = 0;
        for (int value: array) {
            sum += value;
        }

        return sum;
    }

    private static Point getMinMax(int[] array) {
        int min = array[0];
        int max = array[0];

        for (int index = 0, size = array.length; index < size; ++index, ++index) {
            int value = array[index];

            if (index == size - 1) {
                min = min(min, value);
                max = max(max, value);
            } else {
                int otherValue = array[index + 1];

                if (value <= otherValue) {
                    min = min(min, value);
                    max = max(max, otherValue);
                } else {
                    min = min(min, otherValue);
                    max = max(max, value);
                }
            }
        }

        return new Point(min, max);
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] getPrimes(int n) {
        boolean[] used = new boolean[n];
        used[0] = used[1] = true;

        int size = 0;
        for (int i = 2; i < n; ++i) {
            if (!used[i]) {
                ++size;
                for (int j = 2 * i; j < n; j += i) {
                    used[j] = true;
                }
            }
        }

        int[] primes = new int[size];
        for (int i = 0, cur = 0; i < n; ++i) {
            if (!used[i]) {
                primes[cur++] = i;
            }
        }

        return primes;
    }

    /////////////////////////////////////////////////////////////////////

    private static long lcm(long a, long b) {
        return a / gcd(a, b) * b;
    }

    private static long gcd(long a, long b) {
        return (a == 0 ? b : gcd(b % a, a));
    }

    /////////////////////////////////////////////////////////////////////

    private static class MultiSet<ValueType> {

        public static <ValueType> MultiSet<ValueType> createMultiSet() {
            Map<ValueType, Integer> multiset = new HashMap<>();
            return new MultiSet<>(multiset);
        }

        private final Map<ValueType, Integer> multiset;
        private int size;

        public MultiSet(Map<ValueType, Integer> multiset) {
            this.multiset = multiset;
            this.size = 0;
        }

        public int size() {
            return size;
        }

        public void inc(ValueType value) {
            int count = get(value);
            multiset.put(value, count + 1);

            ++size;
        }

        public void dec(ValueType value) {
            int count = get(value);
            if (count == 0) return;

            if (count == 1) multiset.remove(value);
            else multiset.put(value, count - 1);

            --size;
        }

        public int get(ValueType value) {
            Integer count = multiset.get(value);
            return (count == null ? 0 : count);
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static class IdMap<KeyType> extends HashMap<KeyType, Integer> {

        /**
         *
         */
        private static final long serialVersionUID = -3793737771950984481L;

        public IdMap() {
            super();
        }

        int getId(KeyType key) {
            Integer id = super.get(key);
            if (id == null) {
                super.put(key, id = size());
            }

            return id;
        }
    }

    /////////////////////////////////////////////////////////////////////

    private static int[] castInt(List<Integer> list) {
        int[] array = new int[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }

    private static long[] castLong(List<Long> list) {
        long[] array = new long[list.size()];
        for (int i = 0; i < array.length; ++i) {
            array[i] = list.get(i);
        }

        return array;
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class A {
	BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

    int ans = Integer.MAX_VALUE/2;
	public void solve() throws IOException {
        int N = nextInt();
		String[] ss = reader.readLine().split(" ");
		int[][] cards = new int[ss.length][];
        for (int i = 0; i < cards.length; i++) {
            int color = -1;
            switch (ss[i].charAt(0)) {
                case 'R':
                    color = 0;
                    break;
                case 'G':
                    color = 1;
                    break;
                case 'B':
                    color = 2;
                    break;
                case 'Y':
                    color = 3;
                    break;
                case 'W':
                    color = 4;
                    break;
            }
            cards[i] = new int[] {color, Character.getNumericValue(ss[i].charAt(1)) - 1};
        }

        dfs(cards, 0, 0, new boolean[5], new boolean[5]);
        out.println(ans);
	}

    public void dfs(int[][] cards, int colorIndex, int numIndex, boolean[] pColors, boolean[] pNums) {
        boolean OK = true;
        out: for (int i = 0; i < cards.length; i++) {
            for (int j = i+1; j < cards.length; j++) {
                if (cards[i][0] == cards[j][0] && cards[i][1] == cards[j][1]) continue;
                if (cards[i][0] != cards[j][0]) {
                    if (pColors[cards[i][0]] || pColors[cards[j][0]]) continue;
                }
                if (cards[i][1] != cards[j][1]) {
                    if (pNums[cards[i][1]] || pNums[cards[j][1]]) continue;
                }
                OK = false;
                break out;
            }
        }
        if (OK) {
            int tmpAns = 0;
            for (int i = 0; i < 5; i++) {
                if (pColors[i]) tmpAns++;
                if (pNums[i]) tmpAns++;
            }
            ans = Math.min(ans, tmpAns);
            return;
        }

        if (numIndex == 5) {
            return;
        }

        if (colorIndex == 5) {
            dfs(cards, colorIndex, numIndex+1, pColors, pNums);
            pNums[numIndex] = true;
            dfs(cards, colorIndex, numIndex+1, pColors, pNums);
            pNums[numIndex] = false;
        } else {
            dfs(cards, colorIndex+1, numIndex, pColors, pNums);
            pColors[colorIndex] = true;
            dfs(cards, colorIndex+1, numIndex, pColors, pNums);
            pColors[colorIndex] = false;
        }
    }

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new A().run();
	}

	public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            out = new PrintWriter(System.out);
            solve();
            reader.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }

}


// package CodeForces;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.InputMismatchException;

public class FlexingOP3A {

	public static long max_val = (long)1e10;

	public static void solve() {
		int w = s.nextInt();
		long m = s.nextLong();
		if(w == 2) {
			out.println("YES");
			return;
		}
		if(w >= 4) {
			//BruteForces
			int max = 0;
			long curr = 1;
			while(max_val/w > curr) {
				max++;
				curr *= (long)w;
			}
			powers = new long[max + 1];
			powers[0] = 1;
			for(int i = 1; i < max + 1; i++) {
				powers[i] = powers[i - 1] * (long)w;
			}
			boolean ok = Recur(0, max + 1, m, 0);
			if(ok) {
				out.println("YES");
			}else {
				out.println("NO");
			}
			return;
		}
		//Meet in the middle
		int max = 10;
		first = new HashSet<Long>();
		second = new HashSet<Long>();
		powerof3 = new long[21];
		powerof3[0] = 1;
		for(int i = 1; i <= 20; i++) {
			powerof3[i] = powerof3[i - 1] * 3L;
		}
		Recur(0, max, true, 0);
		Recur(max + 1, 20, false, 0);
		if(first.contains(m) || second.contains(m)) {
			out.println("YES");
			return;
		}
		for(Long x : first) {
			if(second.contains(x - m) || second.contains(x + m)) {
				out.println("YES");
				return;
			}
		}
		out.println("NO");
	}

	public static HashSet<Long> first;
	public static HashSet<Long> second;
	public static long[] powerof3;

	public static void Recur(int power, int max, boolean type, long answer) {
		if(power == max + 1) {
			if(type) first.add(answer);
			else second.add(answer);
			return;
		}
		long curr = powerof3[power];
		Recur(power + 1, max, type, answer + curr);
		Recur(power + 1, max, type, answer);
		Recur(power + 1, max, type, answer - curr);
	}

	public static long[] powers;
	public static boolean Recur(int power, int max, long m, long curr) {
		if(m == curr) {
			return true;
		}
		if(power == max) {
			return false;
		}
		boolean ok = false;
		long cur = powers[power];
		ok |= Recur(power + 1, max, m, curr + cur);
		ok |= Recur(power + 1, max, m, curr - cur);
		ok |= Recur(power + 1, max, m, curr);
		return ok;
	}

	public static void main(String[] args) {
		new Thread(null, null, "Thread", 1 << 27) {
			public void run() {
				try {
					out = new PrintWriter(new BufferedOutputStream(System.out));
					s = new FastReader(System.in);
					solve();
					out.close();
				} catch (Exception e) {
					e.printStackTrace();
					System.exit(1);
				}
			}
		}.start();
	}

	public static PrintWriter out;
	public static FastReader s;

	public static class FastReader {

		private InputStream stream;
		private byte[] buf = new byte[4096];
		private int curChar, snumChars;

		public FastReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (snumChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException E) {
					throw new InputMismatchException();
				}
			}
			if (snumChars <= 0) {
				return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int number = 0;
			do {
				number *= 10;
				number += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return number * sgn;
		}

		public long nextLong() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			long sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long number = 0;
			do {
				number *= 10L;
				number += (long) (c - '0');
				c = read();
			} while (!isSpaceChar(c));
			return number * sgn;
		}

		public int[] nextIntArray(int n) {
			int[] arr = new int[n];
			for (int i = 0; i < n; i++) {
				arr[i] = this.nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n) {
			long[] arr = new long[n];
			for (int i = 0; i < n; i++) {
				arr[i] = this.nextLong();
			}
			return arr;
		}

		public String next() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndofLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public boolean isEndofLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

	}

}