#include <utility>
#include <queue>
#include <type_traits>
#include <cstdlib>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <limits>
#include <iostream>
namespace lc {
template <class WeightType, class CapacityType>
struct EdgeWithWeightAndCapacity {
	int to;
	WeightType weight;
	CapacityType capacity;
	EdgeWithWeightAndCapacity() : to(0), weight(), capacity() { }
	EdgeWithWeightAndCapacity(
		int to, const WeightType &weight, const CapacityType &capacity)
		: to(to), weight(weight), capacity(capacity)
	{ }
};
}
namespace lc {
template <typename EdgeType>
class AdjacencyList {
public:
	typedef std::vector<EdgeType> ListType;
private:
	std::vector<ListType> m_lists;
public:
	explicit AdjacencyList(int n = 0)
		: m_lists(n)
	{ }
	int size() const { return m_lists.size(); }
	template <typename... Args>
	void add_edge(int u, Args&&... args){
		m_lists[u].emplace_back(args...);
	}
	const ListType &operator[](int u) const { return m_lists[u]; }
	ListType &operator[](int u){ return m_lists[u]; }
};
}
namespace lc {
template <class EdgeType>
struct ResidualEdge : public EdgeType {
	int rev;
	template <class... Args>
	ResidualEdge(int rev, Args&&... args)
		: EdgeType(args...)
		, rev(rev)
	{ }
};
template <class EdgeType>
class ResidualAdjacencyList
	: public AdjacencyList<ResidualEdge<EdgeType>>
{
public:
	explicit ResidualAdjacencyList(int n = 0)
		: AdjacencyList<ResidualEdge<EdgeType>>(n)
	{ }
};
template <class EdgeType>
ResidualAdjacencyList<EdgeType> make_residual(const AdjacencyList<EdgeType> &graph){
	typedef decltype(EdgeType().capacity) capacity_type;
	const int n = graph.size();
	ResidualAdjacencyList<EdgeType> result(n);
	for(int u = 0; u < n; ++u){
		for(const auto &e : graph[u]){
			const int v = e.to;
			const int rev_u = result[v].size();
			const int rev_v = result[u].size();
			result[u].emplace_back(rev_u, e);
			result[v].emplace_back(rev_v, e);
			result[v].back().to = u;
			result[v].back().capacity = capacity_type();
			result[v].back().weight = -e.weight;
		}
	}
	return result;
}
}
namespace lc {
template <class EdgeType>
auto mincostflow_primal_dual(
	int source, int sink, decltype(EdgeType().capacity) flow,
	ResidualAdjacencyList<EdgeType> &graph)
	-> decltype(EdgeType().weight)
{
	typedef decltype(EdgeType().weight) weight_type;
	typedef decltype(EdgeType().capacity) capacity_type;
	typedef std::pair<weight_type, int> weighted_pair;
	const weight_type inf = std::numeric_limits<weight_type>::max();
	const int n = graph.size();
	weight_type result = 0;
	std::vector<weight_type> h(n);
	std::vector<int> prev_vertex(n), prev_edge(n);
	while(flow > 0){
		std::priority_queue<
			weighted_pair, std::vector<weighted_pair>,
			std::greater<weighted_pair>> pq;
		std::vector<weight_type> dist(n, inf);
		dist[source] = weight_type();
		pq.push(std::make_pair(dist[source], source));
		while(!pq.empty()){
			weighted_pair p = pq.top();
			pq.pop();
			const int u = p.second;
			if(dist[u] < p.first){ continue; }
			for(size_t i = 0; i < graph[u].size(); ++i){
				const auto &e = graph[u][i];
				if(e.capacity <= 0){ continue; }
				const int v = e.to;
				const auto new_dist = dist[u] + e.weight + h[u] - h[v];
				if(dist[v] <= new_dist){ continue; }
				dist[v] = new_dist;
				prev_vertex[v] = u;
				prev_edge[v] = i;
				pq.push(std::make_pair(new_dist, v));
			}
		}
		if(dist[sink] >= inf){ return -1; }
		for(int i = 0; i < n; ++i){ h[i] += dist[i]; }
		weight_type diff = flow;
		for(int v = sink; v != source; v = prev_vertex[v]){
			diff = std::min(
				diff, graph[prev_vertex[v]][prev_edge[v]].capacity);
		}
		flow -= diff;
		result += diff * h[sink];
		for(int v = sink; v != source; v = prev_vertex[v]){
			auto &e = graph[prev_vertex[v]][prev_edge[v]];
			e.capacity -= diff;
			graph[v][e.rev].capacity += diff;
		}
	}
	return result;
}
}
using namespace std;
typedef lc::EdgeWithWeightAndCapacity<int, int> Edge;
int main(){
	ios_base::sync_with_stdio(false);
	int n;
	string s, t;
	cin >> n >> s >> t;
	vector<int> s_hist(26), t_hist(26);
	for(int i = 0; i < n; ++i){ ++s_hist[s[i] - 'a']; }
	for(int i = 0; i < n; ++i){ ++t_hist[t[i] - 'a']; }
	lc::AdjacencyList<Edge> graph(26 + 26 + 2);
	const int source = 26 + 26, sink = source + 1;
	for(int i = 0; i < 26; ++i){
		graph.add_edge(source, i, 0, 1);
		graph.add_edge(26 + i, sink, 0, 1);
		for(int j = 0; j < 26; ++j){
			const int cost = abs(s_hist[i] - t_hist[j]);
			graph.add_edge(i, 26 + j, cost, 1);
		}
	}
	auto residual = lc::make_residual(graph);
	const int f = lc::mincostflow_primal_dual(source, sink, 26, residual);
	cout << f / 2 << endl;
	return 0;
}

Measured memory_bytes: 1524