#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <unordered_map>

using namespace std;
typedef long long ll;

/**
 * Primal-Dual????????????????°??????¨???
 * ?????????????????´??°??§????????¨?§£??????????????¨?????¨???
 */
const ll INF = 1LL<<55;
template<int V>
struct MinCostFlow {
    typedef ll T;
    typedef pair<T, int> P;
    struct Edge {
        int to, rev;
        int cap;
        T cost;
    };
    vector<Edge> g[V];
    T h[V], dist[V];
    int pv[V], pe[V];
    /// ????????????
    void add(int from, int to, int cap, T cost) {
//        printf("add %d %d %d %lld\n", from, to, cap, cost);
        g[from].push_back(Edge{to, (int)g[to].size(), cap, cost});
        g[to].push_back(Edge{from, (int)g[from].size()-1, 0, -cost});
    }
    /**
     * ????°??????¨???????¨??????????
     *
     * bell?????¢?????????????????????????????¨????????´????????????????????°????????§????§£??????????????¨?????¨???
     *
     * Params:
     *   s = ?§????
     *   t = ??????
     *   f = ?????????
     *   bell = ?????????????????????????????¨??????????????????
     */
    T exec(int s, int t, int f, bool bell = false) {
        T res = 0;
        fill_n(h, V, 0);
        while (f > 0) {
            fill_n(dist, V, INF);
            dist[s] = 0;
            if (bell) {
                bell = false;
                bool update;
                do {
                    update = false;
                    for (int v = 0; v < V; v++) {
                        if (dist[v] == INF) continue;
                        for (int i = 0; i < (int)g[v].size(); i++) {
                            Edge &e = g[v][i];
                            if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
                                dist[e.to] = dist[v] + e.cost;
                                pv[e.to] = v;
                                pe[e.to] = i;
                                update = true;
                            }
                        }
                    }
                } while (update);
            } else {
                priority_queue<P, vector<P>, greater<P>> que;
                que.push(P(0, s));
                while (!que.empty()) {
                    P p = que.top(); que.pop();
                    int v = p.second;
                    if (dist[v] < p.first) continue;
                    for (int i = 0; i < (int)g[v].size(); i++) {
                        Edge &e = g[v][i];
                        if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
                            dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
                            pv[e.to] = v;
                            pe[e.to] = i;
                            que.push(P(dist[e.to], e.to));
                        }
                    }
                }
            }
            if (dist[t] == INF) {
                return res;
            }
            for (int v = 0; v < V; v++) {
                h[v] += dist[v];
            }

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

typedef pair<int, int> P;

const int MN = 1100;
int a[MN], b[MN];

vector<P> g[2*MN];

MinCostFlow<3*MN+10> mf;

int main() {
    int n;
    cin >> n;
    set<int> s;
    for (int i = 0; i < n; i++) {
        cin >> a[i] >> b[i];
        s.insert(a[i]);
        s.insert(b[i]);
    }
    vector<int> v(s.begin(), s.end());
    for (int i = 0; i < n; i++) {
        int x = lower_bound(v.begin(), v.end(), a[i]) - v.begin();
        int y = lower_bound(v.begin(), v.end(), b[i]) - v.begin();
        g[x].push_back(P(b[i], i));
        g[y].push_back(P(a[i], i));
    }
    /**
     * 0..2*MN l
     * 2*MN..3*MN r
     * 3*MN s, 3*MN+1 t
     */

    int sv = 3*MN, tv = 3*MN+1;
    for (int i = 0; i < 2*MN; i++) {
        if (g[i].size() == 0) continue;
        mf.add(sv, i, 1, 0);
        for (P p: g[i]) {
            int d, t;
            tie(d, t) = p;
            mf.add(i, 2*MN+t, 1, -d);
        }
    }
    for (int i = 0; i < n; i++) {
        mf.add(2*MN+i, tv, 1, 0);
    }
    cout << -mf.exec(sv, tv, 10000, true) << endl;
    return 0;
}

Measured memory_bytes: 2048