#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

typedef long long  Weight;
struct Edge {
	int src, dest;
	int cap, rev;
	Weight weight;
	bool operator < (const Edge &rhs) const { return weight > rhs.weight; }
};

const int V = 4000;
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
Weight h[V];                //ポテンシャル
Weight dist[V];             //最短距離
int prevv[V], preve[V];  //直前の辺と頂点

void add_edge(Graph &g, int src, int dest, int cap, Weight weight) {
	g[src].push_back(Edge{ src, dest, cap, (int)g[dest].size(), weight });
	g[dest].push_back(Edge{ dest, src, 0, (int)g[src].size() - 1, -weight });
}
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(auto i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const Weight INF = 2147483647;
const Weight ZERO=0;
//コストがdoubleの時はeps使おう
Weight min_cost_flow(Graph &g, int s, int t, int f) {
	Weight res = ZERO;
	memset(h, ZERO, sizeof(h));
	typedef pair<Weight, int> P;
//ポテンシャルを先に計算して速度向上
//REP(i, g.size() / 2 - 1) {
//	int v = i + 2;
//	REP(j, g[v].size()) {
//		Edge &e = g[v][j];
//		if (e.cap == 0) continue;
//		int u = e.dest;
//		h[u] = min(h[u], h[v] + e.weight);
//	}
//	v = i + g.size() / 2 + 1;
//	REP(j, g[v].size()) {
//		Edge &e = g[v][j];
//		if (e.cap == 0) continue;
//		int u = e.dest;
//		h[u] = min(h[u], h[v] + e.weight);
//	}
//}
	while (f > 0) {
		priority_queue<P, vector<P>, greater<P> > que;
		fill(dist, dist + V, INF);
		dist[s] = 0;
		que.push(P(ZERO, s));
		while (!que.empty()) {
			P p = que.top(); que.pop();
			const int v = p.second;
			if (dist[v] < p.first) continue;
			REP(i, g[v].size()) {
				Edge &e = g[v][i];
				if (e.cap > 0 && dist[e.dest] > dist[v] + e.weight + h[v] - h[e.dest] + eps) {
					dist[e.dest] = dist[v] + e.weight + h[v] - h[e.dest];
					prevv[e.dest] = v;
					preve[e.dest] = i;
					que.push(P(dist[e.dest], e.dest));
				}
			}
		}
		if (dist[t] == INF) return -1;
		REP(v, V) h[v] = h[v] + dist[v];

		int d = f;
		for (int v = t; v != s; v = prevv[v]) d = min(d, g[prevv[v]][preve[v]].cap);
		f -= d;
		res = res + d * h[t];
		for (int v = t; v != s; v = prevv[v]) {
			Edge &e = g[prevv[v]][preve[v]];
			e.cap -= d;
			g[v][e.rev].cap += d;
		}
	}
	return res;
}

int main() {
	int N;cin>>N;
	string S,T;cin>>S>>T;
	vector<int>s_nums(26),t_nums(26);
	for (auto ch : S) {
		s_nums[ch-'a']++;

	}
	for (auto ch : T) {
		t_nums[ch-'a']++;
	}

	const int start=0;
	const int s_x=start+1;
	const int g_x=s_x+26;
	const int goal=g_x+26;

	Graph g(goal+1);

	for (int i = 0; i < 26; ++i) {
		add_edge(g,start,s_x+i,1,0);
	}
	for (int i = 0; i < 26; ++i) {
		for (int j = 0; j<26; ++j) {
			add_edge(g,s_x+i,g_x+j,1,abs(s_nums[i]-t_nums[j]));
		}
	}
	for (int j = 0; j < 26; ++j) {
		add_edge(g,g_x+j,goal,1,0);
	}

	int fl=min_cost_flow(g,start,goal,26);

	cout<<fl/2<<endl;
	return 0;
}

### Prompt

Create a solution in Cpp for the following problem:

Problem

Jennifer and Marian presented Carla with the string S.
However, Carla is not happy to receive the string S.
I wanted the string T.
The three decided to work together to change the string S to the string T.


Jennifer first sorts the letters in any order.

Marian then exchanges the lowercase letters of the two alphabets any number of times.
This operation exchanges all the same characters in the string, for example:


* aab-> Swap a and b-> bba
* aab-> Swap a and c-> ccb



Finally, Carla replaces one character with another and repeats until T.
Jennifer and Marian decided to try to reduce the number of Carla replacements.
Find the minimum number of replacements that Carla makes.

Constraints

* 1 ≤ n ≤ 105
* S and T contain only'a'~'z'
* | S | = | T | = n

Input


n
S
T


The length n of the string is given on the first line.
The character string S is given on the second line, and the character string T is given on the third line.

Output

Print the minimum number of Carla replacements on one line.

Examples

Input

3
abc
xyz


Output

0


Input

5
aaabb
xyxyz


Output

1

### Response

```cpp
#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

typedef long long  Weight;
struct Edge {
	int src, dest;
	int cap, rev;
	Weight weight;
	bool operator < (const Edge &rhs) const { return weight > rhs.weight; }
};

const int V = 4000;
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
Weight h[V];                //ポテンシャル
Weight dist[V];             //最短距離
int prevv[V], preve[V];  //直前の辺と頂点

void add_edge(Graph &g, int src, int dest, int cap, Weight weight) {
	g[src].push_back(Edge{ src, dest, cap, (int)g[dest].size(), weight });
	g[dest].push_back(Edge{ dest, src, 0, (int)g[src].size() - 1, -weight });
}
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(auto i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const Weight INF = 2147483647;
const Weight ZERO=0;
//コストがdoubleの時はeps使おう
Weight min_cost_flow(Graph &g, int s, int t, int f) {
	Weight res = ZERO;
	memset(h, ZERO, sizeof(h));
	typedef pair<Weight, int> P;
//ポテンシャルを先に計算して速度向上
//REP(i, g.size() / 2 - 1) {
//	int v = i + 2;
//	REP(j, g[v].size()) {
//		Edge &e = g[v][j];
//		if (e.cap == 0) continue;
//		int u = e.dest;
//		h[u] = min(h[u], h[v] + e.weight);
//	}
//	v = i + g.size() / 2 + 1;
//	REP(j, g[v].size()) {
//		Edge &e = g[v][j];
//		if (e.cap == 0) continue;
//		int u = e.dest;
//		h[u] = min(h[u], h[v] + e.weight);
//	}
//}
	while (f > 0) {
		priority_queue<P, vector<P>, greater<P> > que;
		fill(dist, dist + V, INF);
		dist[s] = 0;
		que.push(P(ZERO, s));
		while (!que.empty()) {
			P p = que.top(); que.pop();
			const int v = p.second;
			if (dist[v] < p.first) continue;
			REP(i, g[v].size()) {
				Edge &e = g[v][i];
				if (e.cap > 0 && dist[e.dest] > dist[v] + e.weight + h[v] - h[e.dest] + eps) {
					dist[e.dest] = dist[v] + e.weight + h[v] - h[e.dest];
					prevv[e.dest] = v;
					preve[e.dest] = i;
					que.push(P(dist[e.dest], e.dest));
				}
			}
		}
		if (dist[t] == INF) return -1;
		REP(v, V) h[v] = h[v] + dist[v];

		int d = f;
		for (int v = t; v != s; v = prevv[v]) d = min(d, g[prevv[v]][preve[v]].cap);
		f -= d;
		res = res + d * h[t];
		for (int v = t; v != s; v = prevv[v]) {
			Edge &e = g[prevv[v]][preve[v]];
			e.cap -= d;
			g[v][e.rev].cap += d;
		}
	}
	return res;
}

int main() {
	int N;cin>>N;
	string S,T;cin>>S>>T;
	vector<int>s_nums(26),t_nums(26);
	for (auto ch : S) {
		s_nums[ch-'a']++;

	}
	for (auto ch : T) {
		t_nums[ch-'a']++;
	}

	const int start=0;
	const int s_x=start+1;
	const int g_x=s_x+26;
	const int goal=g_x+26;

	Graph g(goal+1);

	for (int i = 0; i < 26; ++i) {
		add_edge(g,start,s_x+i,1,0);
	}
	for (int i = 0; i < 26; ++i) {
		for (int j = 0; j<26; ++j) {
			add_edge(g,s_x+i,g_x+j,1,abs(s_nums[i]-t_nums[j]));
		}
	}
	for (int j = 0; j < 26; ++j) {
		add_edge(g,g_x+j,goal,1,0);
	}

	int fl=min_cost_flow(g,start,goal,26);

	cout<<fl/2<<endl;
	return 0;
}

```