#include <bits/stdc++.h>
using namespace std;

#define loop(i,a,b) for(int i=a;i<(int)(b);i++)
#define rep(i,b) loop(i,0,b)
#define show(x) cout << #x << " = " << x << endl
template<class T>
ostream& operator << (ostream& os, const vector<T> v){
    rep(i,v.size()) os << v[i] << " ";
    return os;
}

typedef long long ll;



typedef int Capacity;
typedef int Cost;
struct PrimalDual {
    struct Edge {
        int dst;
        Capacity cap, cap_orig;
        Cost cost;
        int revEdge; bool isRev;
        Edge(int dst, Capacity cap, Cost cost, int revEdge, bool isRev)
            :dst(dst), cap(cap), cap_orig(cap), cost(cost), revEdge(revEdge), isRev(isRev) {}
    };
    int n;
    vector<vector<Edge> > g;
    enum : Cost { inf = 1<<29 };
    enum : int { MAX_V = 1000 };

    PrimalDual(int n_) : n(n_), g(vector<vector<Edge> >(n_)){}

    void add_edge(int src, int dst, Capacity cap, Cost cost) {
        g[src].emplace_back(dst, cap, cost, g[dst].size(), false);
        g[dst].emplace_back(src, 0, -cost, g[src].size() - 1, true);
    }

    Cost solve(int s, int t, int f) {
        Cost res = 0;
        static Cost h[MAX_V], dist[MAX_V];
        static int prevv[MAX_V], preve[MAX_V];
        rep(i,n)h[i] = 0;
        while (f > 0) {
            typedef pair<Cost,int> pcv;
            priority_queue<pcv, vector<pcv>, greater<pcv> > q;
            rep(i,n) dist[i] = inf;
            dist[s] = 0;
            q.emplace(pcv(0, s));
            while (q.size()) {
                pcv p = q.top(); q.pop();
                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.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
                        dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
                        prevv[e.dst] = v;
                        preve[e.dst] = i;
                        q.emplace(pcv(dist[e.dst], e.dst));
                    }
                }
            }
            if (dist[t] == inf) {
                return -1;
            }
            rep(v,n) h[v] += dist[v];
            // s-t 間最短路に沿って目一杯流す
            int d = f;
            for (int v = t; v != s; v = prevv[v]) {
                d = min(d, g[prevv[v]][preve[v]].cap);
            }
            f -= d;
            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.revEdge].cap += d;
            }
        }
        return res;
    }

    void view(){
        rep(i,g.size()){
            rep(j,g[i].size())if(!g[i][j].isRev){
                Edge& e = g[i][j];
                if(e.cap_orig - e.cap==0) continue;
                printf("%3d->%3d (flow:%d cost:%d)\n", i, e.dst, e.cap_orig - e.cap, e.cost);
            }
        }
    }

};

int main(){
    int n;
    while(cin >> n){
        string s,t;
        cin >> s >> t;
        vector<int> cs(26),ct(26);
        rep(i,n){
            cs[s[i]-'a']++;
            ct[t[i]-'a']++;
        }
        PrimalDual g(102);
        const int S = 100;
        const int T = 101;
        // from, to, cap, cost
        rep(i,26){
            g.add_edge(S,    i, 1, 0);
            g.add_edge(50+i, T, 1, 0);
        }
        rep(i,26)rep(j,26){
            g.add_edge(i, j+50, 1, max(0, ct[j]-cs[i]));
        }
        int ans = g.solve(S,T,26);
        //g.view();
        //show(ans);
        cout << ans << endl;
    }
}
### Prompt

Develop a solution in Cpp to the problem described below:

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>
using namespace std;

#define loop(i,a,b) for(int i=a;i<(int)(b);i++)
#define rep(i,b) loop(i,0,b)
#define show(x) cout << #x << " = " << x << endl
template<class T>
ostream& operator << (ostream& os, const vector<T> v){
    rep(i,v.size()) os << v[i] << " ";
    return os;
}

typedef long long ll;



typedef int Capacity;
typedef int Cost;
struct PrimalDual {
    struct Edge {
        int dst;
        Capacity cap, cap_orig;
        Cost cost;
        int revEdge; bool isRev;
        Edge(int dst, Capacity cap, Cost cost, int revEdge, bool isRev)
            :dst(dst), cap(cap), cap_orig(cap), cost(cost), revEdge(revEdge), isRev(isRev) {}
    };
    int n;
    vector<vector<Edge> > g;
    enum : Cost { inf = 1<<29 };
    enum : int { MAX_V = 1000 };

    PrimalDual(int n_) : n(n_), g(vector<vector<Edge> >(n_)){}

    void add_edge(int src, int dst, Capacity cap, Cost cost) {
        g[src].emplace_back(dst, cap, cost, g[dst].size(), false);
        g[dst].emplace_back(src, 0, -cost, g[src].size() - 1, true);
    }

    Cost solve(int s, int t, int f) {
        Cost res = 0;
        static Cost h[MAX_V], dist[MAX_V];
        static int prevv[MAX_V], preve[MAX_V];
        rep(i,n)h[i] = 0;
        while (f > 0) {
            typedef pair<Cost,int> pcv;
            priority_queue<pcv, vector<pcv>, greater<pcv> > q;
            rep(i,n) dist[i] = inf;
            dist[s] = 0;
            q.emplace(pcv(0, s));
            while (q.size()) {
                pcv p = q.top(); q.pop();
                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.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
                        dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
                        prevv[e.dst] = v;
                        preve[e.dst] = i;
                        q.emplace(pcv(dist[e.dst], e.dst));
                    }
                }
            }
            if (dist[t] == inf) {
                return -1;
            }
            rep(v,n) h[v] += dist[v];
            // s-t 間最短路に沿って目一杯流す
            int d = f;
            for (int v = t; v != s; v = prevv[v]) {
                d = min(d, g[prevv[v]][preve[v]].cap);
            }
            f -= d;
            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.revEdge].cap += d;
            }
        }
        return res;
    }

    void view(){
        rep(i,g.size()){
            rep(j,g[i].size())if(!g[i][j].isRev){
                Edge& e = g[i][j];
                if(e.cap_orig - e.cap==0) continue;
                printf("%3d->%3d (flow:%d cost:%d)\n", i, e.dst, e.cap_orig - e.cap, e.cost);
            }
        }
    }

};

int main(){
    int n;
    while(cin >> n){
        string s,t;
        cin >> s >> t;
        vector<int> cs(26),ct(26);
        rep(i,n){
            cs[s[i]-'a']++;
            ct[t[i]-'a']++;
        }
        PrimalDual g(102);
        const int S = 100;
        const int T = 101;
        // from, to, cap, cost
        rep(i,26){
            g.add_edge(S,    i, 1, 0);
            g.add_edge(50+i, T, 1, 0);
        }
        rep(i,26)rep(j,26){
            g.add_edge(i, j+50, 1, max(0, ct[j]-cs[i]));
        }
        int ans = g.solve(S,T,26);
        //g.view();
        //show(ans);
        cout << ans << endl;
    }
}
```