#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cmath>
#include <iomanip>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i=0; i<(n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007

#define MAX_N 4000
class MinCostFlow {
public:
  struct Edge { int to, cap, cost, rev; };
  vector<Edge> G[MAX_N];
  int dist[MAX_N];
  int prevv[MAX_N], preve[MAX_N];

  void add_edge(int from, int to, int cap, int cost) {
    G[from].pb((Edge) { to, cap, cost, (int)G[to].size() });
    G[to].pb((Edge) { from, 0, -cost, (int)G[from].size() - 1 });
  }

  int min_cost_flow(int s, int t, int f) {
    int res = 0;
    while (f > 0) {
      rep(i, MAX_N) dist[i] = INF;
      dist[s] = 0;
      bool update = true;
      while (update) {
        update = false;
        rep(x, MAX_N) {
          if (dist[x] == INF) continue;
          rep(i, G[x].size()) {
            Edge &e = G[x][i];
            if (e.cap > 0 && dist[e.to] > dist[x] + e.cost) {
              dist[e.to] = dist[x] + e.cost;
              prevv[e.to] = x;
              preve[e.to] = i;
              update = true;
            }
          }
        }
      }
      if (dist[t] == INF) return -1;
      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*dist[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 N;
int A[1000], B[1000];
MinCostFlow flow;

signed main() {
  ios::sync_with_stdio(false); cin.tie(0);
  cin >> N;
  int S = 0, T = 1;
  // S:0 T:1 P:2+i X:2+N+i

  // S->V
  flow.add_edge(S, T, N, 0);
  vector<int> xs;
  rep(i, N) {
    cin >> A[i] >> B[i];
    xs.pb(A[i]);
    xs.pb(B[i]);

    // S->P
    flow.add_edge(S, 2+i, 1, 0);
  }
  sort(all(xs));
  uniq(xs);

  rep(i, N) {
    // P->X
    int a = lower_bound(all(xs), A[i]) - xs.begin(),
        b = lower_bound(all(xs), B[i]) - xs.begin();
    flow.add_edge(2+i, 2+N+a, 1, -B[i]);
    flow.add_edge(2+i, 2+N+b, 1, -A[i]);
  }

  rep(i, xs.size()) {
    // X->T
    flow.add_edge(2+N+i, T, 1, 0);
  }
  cout << -flow.min_cost_flow(S, T, N) << "\n";
  return 0;
}