#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>

#define MAX_V 3010
#define INF 100000000000000
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
struct edge {int to; ll cap, cost, rev;};
vector<edge> G[MAX_V],H[MAX_V];
ll V,h[MAX_V],dist[MAX_V],prevv[MAX_V],preve[MAX_V];
void add_edge(int from, int to, ll cap, ll cost){
	G[from].push_back((edge){to, cap, cost, (ll)G[to].size()});
	G[to].push_back((edge){from, 0, -cost, (ll)G[from].size() - 1});
}

ll min_cost_flow(int s,int t, ll f){
	ll res = 0;
	fill(h,h + V,INF);
	h[s] = 0;
	while(true){
		bool upd = false;
		for(int i=0;i<V;i++){
			for(edge e:G[i]){
				if(h[i]==INF || e.cap==0) continue;
				if(h[e.to]>h[i] + e.cost){
					h[e.to] = h[i] + e.cost;
					upd = true;
				}
			}
		}
		if(!upd) break;
	}
	int cnt = 0;
	while(f>0){
		priority_queue<pll,vector<pll>,greater<pll>> que;
		fill(dist,dist + V,INF);
		que.push({0,s});
		dist[s] = 0;
		while(que.size()){
			pll p = que.top(); que.pop();
			if(dist[p.second]<p.first) continue;
			for(int i=0;i<G[p.second].size();i++){
				edge e = G[p.second][i];
				if(e.cap>0 && dist[e.to] > dist[p.second] + e.cost + h[p.second] - h[e.to]){
					dist[e.to] = dist[p.second] + e.cost + h[p.second] - h[e.to];
					prevv[e.to] = p.second;
					preve[e.to] = i;
					que.push({dist[e.to],e.to});
				}
			}
		}
		if(dist[t]==INF) return -1;
		for(int v=0;v<V;v++) h[v] += dist[v];
		ll 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.rev].cap += d;
		}
	}
	return res;
}

ll a[1010],b[1010];
map<ll,int> mp;
int main(){
	int i,n;
	cin >> n;
	int cnt = n + 1;
	for(i=1;i<=n;i++){
		cin >> a[i] >> b[i];
		if(mp[a[i]]==0){
			mp[a[i]] = cnt;
			cnt++;
		}
		if(mp[b[i]]==0){
			mp[b[i]] = cnt;
			cnt++;
		}
	}
	V = cnt + 1;
	for(i=1;i<=n;i++){
		add_edge(0,i,1,0);
		add_edge(i,mp[b[i]],1,-a[i]);
		add_edge(i,mp[a[i]],1,-b[i]);
	}
	for(i=n + 1;i<cnt;i++){
		add_edge(i,cnt,1,0);
	}
	add_edge(0,V - 1,INF,0);
	cout << -min_cost_flow(0,V - 1,n) << endl;
}
