You must have heard of the two brothers dreaming of ruling the world. With all their previous plans failed, this time they decided to cooperate with each other in order to rule the world. 

As you know there are n countries in the world. These countries are connected by n - 1 directed roads. If you don't consider direction of the roads there is a unique path between every pair of countries in the world, passing through each road at most once. 

Each of the brothers wants to establish his reign in some country, then it's possible for him to control the countries that can be reached from his country using directed roads. 

The brothers can rule the world if there exists at most two countries for brothers to choose (and establish their reign in these countries) so that any other country is under control of at least one of them. In order to make this possible they want to change the direction of minimum number of roads. Your task is to calculate this minimum number of roads.

Input

The first line of input contains an integer n (1 ≤ n ≤ 3000). Each of the next n - 1 lines contains two space-separated integers ai and bi (1 ≤ ai, bi ≤ n; ai ≠ bi) saying there is a road from country ai to country bi.

Consider that countries are numbered from 1 to n. It's guaranteed that if you don't consider direction of the roads there is a unique path between every pair of countries in the world, passing through each road at most once.

Output

In the only line of output print the minimum number of roads that their direction should be changed so that the brothers will be able to rule the world.

Examples

Input

4
2 1
3 1
4 1


Output

1


Input

5
2 1
2 3
4 3
4 5


Output

0
import java.io.*; 
import java.util.*;
import java.math.*;
import java.awt.geom.*;

import static java.lang.Math.*;

public class Solution implements Runnable {
	
	class Edge {
		int to, cost;
		
		public Edge(int to, int cost) {
			this.to = to;
			this.cost = cost;
		}
		
	}
	
	ArrayList<Edge> g [];
	int parent [];
	int edgeParent [];
	int d [][];
	int bestd [];
	int vertexCost [];
	int wayCost [];
	
	int tin [], tout [];
	int timer = 0;
	
	boolean isUpper (int a, int b) {
		return tin[a] <= tin [b] && tout [a] >= tout[b];
	}
	
	void dfs1 (int v, int p, int pe) {
		parent[v] = p;
		edgeParent[v] = pe;
		tin [v] = timer++;
		for (int i = 0; i < g[v].size(); i++) {
			Edge e = g[v].get(i);
			if (e.to != p) {
				dfs1 (e.to, v, e.cost ^ 1);
			}
		}
		tout [v] = timer++;
	}
	
	int dfs2 (int v, int p) {
		int result = 0;
		for (int i = 0; i < g[v].size(); i++) {
			Edge e = g[v].get(i);
			if (e.to != p) {
				result += dfs2 (e.to, v) + e.cost;
			}
		}
		return vertexCost[v] = result;
	}
	
	void dfs3 (int from, int p, int v, int current) {
		if (v == 0) return;
		int result = current;
		for (int i = 0; i < g[v].size(); i++) {
			Edge e = g[v].get(i);
			if (e.to != parent[v] && e.to != p) {
				result = result + vertexCost[e.to] + e.cost;
			}
		}
		d[from][v] = min (d[from][v], result);
		dfs3 (from, v, parent[v], result + edgeParent[v]);
	}
	
	public void solve () throws Exception {
		int n = nextInt();
		
		g = new ArrayList [n];
		for (int i = 0; i < n; i++) {
			g [i] = new ArrayList<Solution.Edge>();
		}
		
		for (int i = 0; i < n - 1; i++) {
			int v1 = nextInt() - 1;
			int v2 = nextInt() - 1;
			g[v1].add(new Edge (v2, 0));
			g[v2].add(new Edge (v1, 1));
		}
		
		d = new int [n][n];
		for (int i = 0; i < n; i++) {
			Arrays.fill(d[i], Integer.MAX_VALUE / 2);
		}
		
		parent = new int [n];
		edgeParent = new int [n];
		vertexCost = new int [n];
		tin = new int [n];
		tout = new int [n];
		
		dfs1 (0, -1, 0);
		dfs2 (0, -1);
		
		for (int i = 1; i < n; i++) {
			dfs3 (i, -1, i, 0);
		}
		
		bestd = new int [n];
		Arrays.fill(bestd, Integer.MAX_VALUE / 2);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				bestd[j] = min (bestd[j], d[i][j]);
			}
		}
		
		wayCost = new int [n];
		for (int i = 0; i < n; i++) {
			int v = i;
			int p = -1;
			int result = 0;
			while (v != -1) {
				for (int j = 0; j < g[v].size(); j++) {
					Edge e = g[v].get(j);
					if (e.to != p && e.to != parent[v]) {
						result = result + vertexCost[e.to] + e.cost;
					}
				}
				result = result + edgeParent[v];
				p = v;
				v = parent [v];
			}
			wayCost [i] = result;
		}
		
		int answer = Integer.MAX_VALUE / 2;
		
		for (int i = 0; i < n; i++) {
			answer = min (answer, wayCost[i]);
		}
		
		for (int first = 0; first < n; first++) {
			for (int second = 0; second < n; second++) {
				if (isUpper(second, first)) continue;
				int current = bestd[second] + wayCost[first] - vertexCost[second] - (edgeParent[second] == 0 ? 1 : 0);
				answer = min (answer, current);
			}
		}
		
		out.println(answer);
	}
	
	private static long stime = 0;
	
	private BufferedReader in;
	private PrintWriter out;
	private StringTokenizer st;
	
	
	private String nextToken () throws Exception {
		while (st == null || !st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}
	
	private int nextInt () throws Exception {
		return Integer.parseInt(nextToken());
	}
	
	private long nextLong () throws Exception {
		return Long.parseLong(nextToken());
	}
	
	private double nextDouble () throws Exception {
		return Double.parseDouble(nextToken());
	}

	@Override
	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			solve ();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			out.close();
		}
	}
	
	public static void main(String[] args) {
		new Thread(null, new Solution(), "", 1<<26).start();
	}

}
