import java.io.*;
import java.util.*;

/*
───────────────■■■─────────────────────────
──█▄─▄█─▄▀▀▀▄─█──▄█─────█──▄▀─▄▀▀▀▄─▀▀█▀▀──
──█─▀─█─█───█─█─█─█─────█■█───█───█───█────
──█───█─▀▄▄▄▀─█▀──█─────█──▀▄─▀▄▄▄▀───█────
───────────────────────────────────────────
*/

public class Main {

    static FastReader in;
    static PrintWriter out;
    static Random rand = new Random();
    static final int INF = (int) (1e9);
    static final int MOD = (int) (1e9 + 7);
    static final int N = (int) (1e6 + 6);
    static int n;
    static ArrayList<Integer>[] g;
    static int[] size;
    static int[][] segs;

    static void dfs1(int v, int par) {
        size[v] = 1;
        for (int u : g[v]) {
            if (u != par) {
                dfs1(u, v);
                size[v] += size[u];
            }
        }
    }

    static void dfs2(int v, int par, int x) {
        int r = x + g[v].size() - 1;
        if (par == -1) r++;
        int i = r - 1, j = r + 1;
        for (int u : g[v]) {
            if (u != par) {
                segs[u][0] = i;
                dfs2(u, v, j);
                i--;
                j += size[u] * 2 - 1;
            }
        }
        segs[v][1] = r;
    }

    static void solve() {
        n = in.nextInt();

        g = new ArrayList[n];
        Arrays.setAll(g, i -> new ArrayList<>());
        for (int i = 0; i < n - 1; i++) {
            int x = in.nextInt() - 1;
            int y = in.nextInt() - 1;
            g[x].add(y);
            g[y].add(x);
        }

        size = new int[n];
        dfs1(0, -1);

        segs = new int[n][2];
        segs[0][0] = 1;
        dfs2(0, -1, 2);

        for (int i = 0; i < n; i++) {
            out.println(segs[i][0] + " " + segs[i][1]);
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        in = new FastReader(System.in);
//        in = new FastReader(new FileInputStream("input.txt"));
        out = new PrintWriter(System.out);
//        out = new PrintWriter(new FileOutputStream("output.txt"));

        int q = 1;

        while (q-- > 0) {
            solve();
        }

        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        Integer nextInt() {
            return Integer.parseInt(next());
        }

        Long nextLong() {
            return Long.parseLong(next());
        }

        Double nextDouble() {
            return Double.parseDouble(next());
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }

        String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }
    }
}


import java.io.*;
import java.util.*;

/*
───────────────■■■─────────────────────────
──█▄─▄█─▄▀▀▀▄─█──▄█─────█──▄▀─▄▀▀▀▄─▀▀█▀▀──
──█─▀─█─█───█─█─█─█─────█■█───█───█───█────
──█───█─▀▄▄▄▀─█▀──█─────█──▀▄─▀▄▄▄▀───█────
───────────────────────────────────────────
*/

public class Main {

    static FastReader in;
    static PrintWriter out;
    static Random rand = new Random();
    static final int INF = (int) (1e9);
    static final int MOD = (int) (1e9 + 7);
    static final int N = (int) (1e6 + 6);
    static int n;
    static ArrayList<Integer>[] g;
    static int[] size;
    static int[][] segs;

    static void dfs1(int v, int par) {
        size[v] = 1;
        for (int u : g[v]) {
            if (u != par) {
                dfs1(u, v);
                size[v] += size[u];
            }
        }
    }

    static void dfs2(int v, int par, int l) {
        int i = l;
        int cnt = l + g[v].size();
        if (par == -1) cnt++;
        for (int u : g[v]) {
            if (u != par) {
                segs[u][0] = i;
                dfs2(u, v, cnt);
                i++;
                cnt += size[u] * 2 - 1;
            }
        }
        segs[v][1] = i;
    }

    static void solve() {
        n = in.nextInt();

        g = new ArrayList[n];
        Arrays.setAll(g, i -> new ArrayList<>());
        for (int i = 0; i < n - 1; i++) {
            int x = in.nextInt() - 1;
            int y = in.nextInt() - 1;
            g[x].add(y);
            g[y].add(x);
        }

        size = new int[n];
        dfs1(0, -1);

        segs = new int[n][2];
        segs[0][0] = 1;
        dfs2(0, -1, 2);

        for (int i = 0; i < n; i++) {
            out.println(segs[i][0] + " " + segs[i][1]);
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        in = new FastReader(System.in);
//        in = new FastReader(new FileInputStream("input.txt"));
        out = new PrintWriter(System.out);
//        out = new PrintWriter(new FileOutputStream("output.txt"));

        int q = 1;

        while (q-- > 0) {
            solve();
        }

        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        Integer nextInt() {
            return Integer.parseInt(next());
        }

        Long nextLong() {
            return Long.parseLong(next());
        }

        Double nextDouble() {
            return Double.parseDouble(next());
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }

        String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }
    }
}


import static java.lang.Math.*;

import java.util.stream.*;

public class E {

	public Object solve () {
		int N = sc.nextInt();
		int [][] E = dec(sc.nextInts(N-1));

		G = graph(N, E);
		S = new int [2*N];
		dfs(0, -1);
		S[2*N-1] = -1;

		int [][] res = new int [N][2]; int i = 1;
		for (int s : S)
			if (s > 0)
				res[s-1][0] = i++;
			else
				res[-s-1][1] = i++;

		for (int j : rep(N))
			print(res[j]);
		return null;
	}

	int [][] G;
	int [] S; int J = 0;

	void dfs(int i, int p) {
		for (int j : G[i])
			if (j != p)
				dfs(j, i);

		S[J++] = i+1;
		int s = G[i].length + 2*J - 2;
		if (p == -1)
			++s;

		for (int j : G[i])
			if (j != p)
				S[s - J++] = -j-1;
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static final int INF = (int) 1e9 + 10;
	private static int [][] dec (int [] ... E) { return dec(E, INF); }
	private static int [][] dec (int [][] E, int N) { for (int [] e : E) for (int i = 0; i < e.length && i < N; ++i) --e[i]; return E; }
	private static int [][] dup (int [][] E) {
		int [][] res = new int [2*E.length][];
		for (int i = 0; i < E.length; ++i) {
			res[2*i] = E[i].clone();
			res[2*i+1] = E[i].clone();
			res[2*i+1][0] = E[i][1]; res[2*i+1][1] = E[i][0];
		}
		return res;
	}
	private static int [][][] dwgraph (int N, int [][] E) {
		int [] D = new int [N];
		for (int [] e : E)
			++D[e[0]];
		int [][][] res = new int [2][N][];
		for (int i = 0; i < 2; ++i)
			for (int j = 0; j < N; ++j)
				res[i][j] = new int [D[j]];
		D = new int [N];
		for (int [] e : E) {
			int x = e[0], y = e[1], z = e.length > 2 ? e[2] : 1;
			res[0][x][D[x]] = y;
			res[1][x][D[x]] = z;
			++D[x];
		}
		return res;
	}
	private static int [][] graph (int N, int [][] E) { return wgraph(N, E)[0]; }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [][][] wgraph (int N, int [][] E) { return dwgraph(N, dup(E)); }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public String nextLine () { line = null; return readLine(); }
			public String [] nextStrings () { return split(nextLine()); }
			public int[] nextInts () { return nextStream().mapToInt(Integer::parseInt).toArray(); }
			public int[][] nextInts (int N) { return IntStream.range(0, N).mapToObj(i -> nextInts()).toArray(int[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private java.util.stream.Stream<String> nextStream () { return java.util.Arrays.stream(nextStrings()); }
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(min(b.length(), delim.length()));
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			if (res.length() > 0)
				pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new E().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import static java.lang.Math.*;

import java.util.*;
import java.util.stream.*;

public class E {

	public Object solve () {
		int N = sc.nextInt();
		int [][] E = dec(sc.nextInts(N-1));

		G = graph(N, E);
		dfs(0, -1);
		S.add(-1);

		int [][] res = new int [N][2]; int i = 1;
		for (int s : S)
			if (s > 0)
				res[s-1][0] = i++;
			else
				res[-s-1][1] = i++;

		for (int j : rep(N))
			print(res[j]);
		return null;
	}

	int [][] G;
	List<Integer> S = new ArrayList<>();

	void dfs(int i, int p) {
		for (int j : G[i])
			if (j != p)
				dfs(j, i);
		S.add(i+1);
		for (int j : G[i])
			if (j != p)
				S.add(-j-1);
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static final int INF = (int) 1e9 + 10;
	private static int [][] dec (int [] ... E) { return dec(E, INF); }
	private static int [][] dec (int [][] E, int N) { for (int [] e : E) for (int i = 0; i < e.length && i < N; ++i) --e[i]; return E; }
	private static int [][] dup (int [][] E) {
		int [][] res = new int [2*E.length][];
		for (int i = 0; i < E.length; ++i) {
			res[2*i] = E[i].clone();
			res[2*i+1] = E[i].clone();
			res[2*i+1][0] = E[i][1]; res[2*i+1][1] = E[i][0];
		}
		return res;
	}
	private static int [][][] dwgraph (int N, int [][] E) {
		int [] D = new int [N];
		for (int [] e : E)
			++D[e[0]];
		int [][][] res = new int [2][N][];
		for (int i = 0; i < 2; ++i)
			for (int j = 0; j < N; ++j)
				res[i][j] = new int [D[j]];
		D = new int [N];
		for (int [] e : E) {
			int x = e[0], y = e[1], z = e.length > 2 ? e[2] : 1;
			res[0][x][D[x]] = y;
			res[1][x][D[x]] = z;
			++D[x];
		}
		return res;
	}
	private static int [][] graph (int N, int [][] E) { return wgraph(N, E)[0]; }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [][][] wgraph (int N, int [][] E) { return dwgraph(N, dup(E)); }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public String nextLine () { line = null; return readLine(); }
			public String [] nextStrings () { return split(nextLine()); }
			public int[] nextInts () { return nextStream().mapToInt(Integer::parseInt).toArray(); }
			public int[][] nextInts (int N) { return IntStream.range(0, N).mapToObj(i -> nextInts()).toArray(int[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private java.util.stream.Stream<String> nextStream () { return java.util.Arrays.stream(nextStrings()); }
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(min(b.length(), delim.length()));
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			if (res.length() > 0)
				pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new E().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import static java.lang.Math.*;

import java.util.*;
import java.util.stream.*;

public class E {

	public Object solve () {
		int N = sc.nextInt();
		int [][] E = dec(sc.nextInts(N-1));

		G = graph(N, E);
		dfs(0, -1);
		S.add(-1);

		int [][] res = new int [N][2]; int i = 1;
		for (int s : S)
			if (s > 0)
				res[s-1][0] = i++;
			else
				res[-s-1][1] = i++;

		for (int j : rep(N))
			print(res[j]);
		return null;
	}

	int [][] G;
	List<Integer> S = new ArrayList<>();

	void dfs(int i, int p) {
		for (int j : rep(G[i].length))
			if (G[i][j] != p)
				dfs(G[i][j], i);
		S.add(i+1);
		for (int j : sep(G[i].length))
			if (G[i][j] != p)
				S.add(-G[i][j]-1);
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static final int INF = (int) 1e9 + 10;
	private static int [][] dec (int [] ... E) { return dec(E, INF); }
	private static int [][] dec (int [][] E, int N) { for (int [] e : E) for (int i = 0; i < e.length && i < N; ++i) --e[i]; return E; }
	private static int [][] dup (int [][] E) {
		int [][] res = new int [2*E.length][];
		for (int i = 0; i < E.length; ++i) {
			res[2*i] = E[i].clone();
			res[2*i+1] = E[i].clone();
			res[2*i+1][0] = E[i][1]; res[2*i+1][1] = E[i][0];
		}
		return res;
	}
	private static int [][][] dwgraph (int N, int [][] E) {
		int [] D = new int [N];
		for (int [] e : E)
			++D[e[0]];
		int [][][] res = new int [2][N][];
		for (int i = 0; i < 2; ++i)
			for (int j = 0; j < N; ++j)
				res[i][j] = new int [D[j]];
		D = new int [N];
		for (int [] e : E) {
			int x = e[0], y = e[1], z = e.length > 2 ? e[2] : 1;
			res[0][x][D[x]] = y;
			res[1][x][D[x]] = z;
			++D[x];
		}
		return res;
	}
	private static int [][] graph (int N, int [][] E) { return wgraph(N, E)[0]; }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [] sep (int N) { return sep(0, N); }
	private static int [] sep (final int S, final int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[T-1-i] = i; return res; }
	private static int [][][] wgraph (int N, int [][] E) { return dwgraph(N, dup(E)); }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public String nextLine () { line = null; return readLine(); }
			public String [] nextStrings () { return split(nextLine()); }
			public int[] nextInts () { return nextStream().mapToInt(Integer::parseInt).toArray(); }
			public int[][] nextInts (int N) { return IntStream.range(0, N).mapToObj(i -> nextInts()).toArray(int[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private java.util.stream.Stream<String> nextStream () { return java.util.Arrays.stream(nextStrings()); }
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(min(b.length(), delim.length()));
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			if (res.length() > 0)
				pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new E().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import static java.lang.Math.*;

import java.util.*;
import java.util.stream.*;

public class E {

	public Object solve () {
		int N = sc.nextInt();
		int [][] E = dec(sc.nextInts(N-1));

		G = graph(N, E);
		S = new int [2*N];
		dfs(0, -1);
		S[2*N-1] = -1;

		int [][] res = new int [N][2]; int i = 1;
		for (int s : S)
			if (s > 0)
				res[s-1][0] = i++;
			else
				res[-s-1][1] = i++;

		for (int j : rep(N))
			print(res[j]);
		return null;
	}

	int [][] G;
	int [] S; int J = 0;

	void dfs(int i, int p) {
		for (int j : rep(G[i].length))
			if (G[i][j] != p)
				dfs(G[i][j], i);
		S[J++] = i+1;
		for (int j : sep(G[i].length))
			if (G[i][j] != p)
				S[J++] = -G[i][j]-1;
	}

	private static final int CONTEST_TYPE = 1;

	private static void init () {
	}

	private static final int INF = (int) 1e9 + 10;
	private static int [][] dec (int [] ... E) { return dec(E, INF); }
	private static int [][] dec (int [][] E, int N) { for (int [] e : E) for (int i = 0; i < e.length && i < N; ++i) --e[i]; return E; }
	private static int [][] dup (int [][] E) {
		int [][] res = new int [2*E.length][];
		for (int i = 0; i < E.length; ++i) {
			res[2*i] = E[i].clone();
			res[2*i+1] = E[i].clone();
			res[2*i+1][0] = E[i][1]; res[2*i+1][1] = E[i][0];
		}
		return res;
	}
	private static int [][][] dwgraph (int N, int [][] E) {
		int [] D = new int [N];
		for (int [] e : E)
			++D[e[0]];
		int [][][] res = new int [2][N][];
		for (int i = 0; i < 2; ++i)
			for (int j = 0; j < N; ++j)
				res[i][j] = new int [D[j]];
		D = new int [N];
		for (int [] e : E) {
			int x = e[0], y = e[1], z = e.length > 2 ? e[2] : 1;
			res[0][x][D[x]] = y;
			res[1][x][D[x]] = z;
			++D[x];
		}
		return res;
	}
	private static int [][] graph (int N, int [][] E) { return wgraph(N, E)[0]; }
	private static int [] rep (int N) { return rep(0, N); }
	private static int [] rep (int S, int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static int [] sep (int N) { return sep(0, N); }
	private static int [] sep (final int S, final int T) { if (S >= T) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[T-1-i] = i; return res; }
	private static int [][][] wgraph (int N, int [][] E) { return dwgraph(N, dup(E)); }
	//////////////////////////////////////////////////////////////////////////////////// OFF
	private static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static Object print (Object o, Object ... A) { IOUtils.print(o, A); return null; }
	private static class IOUtils {
		public static class MyScanner {
			public String next () { newLine(); return line[index++]; }
			public int nextInt () { return Integer.parseInt(next()); }
			public String nextLine () { line = null; return readLine(); }
			public String [] nextStrings () { return split(nextLine()); }
			public int[] nextInts () { return nextStream().mapToInt(Integer::parseInt).toArray(); }
			public int[][] nextInts (int N) { return IntStream.range(0, N).mapToObj(i -> nextInts()).toArray(int[][]::new); }
			//////////////////////////////////////////////
			private boolean eol () { return index == line.length; }
			private String readLine () {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine () {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private java.util.stream.Stream<String> nextStream () { return java.util.Arrays.stream(nextStrings()); }
			private String [] split (String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build (Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim (String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(min(b.length(), delim.length()));
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static java.text.DecimalFormat formatter = new java.text.DecimalFormat("#.#########");
		private static void start () { if (t == 0) t = millis(); }
		private static void append (java.util.function.Consumer<Object> f, java.util.function.Consumer<Object> g, final Object o) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					f.accept(java.lang.reflect.Array.get(o, i));
			}
			else if (o instanceof Iterable<?>)
				((Iterable<?>)o).forEach(f::accept);
			else
				g.accept(o instanceof Double ? formatter.format(o) : o);
		}
		private static void append (final StringBuilder b, Object o, final String delim) {
			append(x -> { append(b, x, delim); }, x -> b.append(delim).append(x), o);
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print (Object o, Object ... A) {
			String res = build(o, A);
			if (DEBUG == 2)
				err(res, '(', time(), ')');
			if (res.length() > 0)
				pw.println(res);
			if (DEBUG == 1) {
				pw.flush();
				System.out.flush();
			}
		}
		private static void err (Object o, Object ... A) { System.err.println(build(o, A)); }
		private static int DEBUG;
		private static void exit () {
			String end = "------------------" + System.lineSeparator() + time();
			switch(DEBUG) {
			case 1: print(end); break;
			case 2: err(end); break;
			}
			IOUtils.pw.close();
			System.out.flush();
			System.exit(0);
		}
		private static long t;
		private static long millis () { return System.currentTimeMillis(); }
		private static String time () { return "Time: " + (millis() - t) / 1000.0; }
		private static void run (int N) {
			try { DEBUG = Integer.parseInt(System.getProperties().get("DEBUG").toString()); }
			catch (Throwable t) {}

			for (int n = 1; n <= N; ++n) {
				Object res = new E().solve();
				if (res != null) {
					@SuppressWarnings("all")
					Object o = CONTEST_TYPE == 0 ? "Case #" + n + ": " + build(res) : res;
					print(o);
				}
			}
			exit();
		}
	}
	////////////////////////////////////////////////////////////////////////////////////
	public static void main (String[] args) {
		init();
		@SuppressWarnings("all")
		int N = CONTEST_TYPE == 1 ? 1 : sc.nextInt();
		IOUtils.run(N);
	}
}


import java.util.*;
import java.io.*;
public class Main{
    static PrintWriter out;
    static InputReader in;
    public static void main(String args[]){
        out = new PrintWriter(System.out);
        in = new InputReader();
        new Main();
        out.flush(); out.close();
    }
    Main(){
        solve();
    }
    class pair{
        int F, S;
        pair(int a, int b){
            F = a; S = b;
        }
    }
    final int max = 500010;
    int val[] = new int[max];
    ArrayList<Integer> al[] = new ArrayList[max];
    int p = 0;
    void dfs(int u, int pa){
        for(int v : al[u]){
            if(v == pa)continue;
            dfs(v, u);
        }
        val[p++] = u;
        for(int i = al[u].size() - 1; i >= 0; i--){
            int v = al[u].get(i);
            if(v == pa)continue;
            val[p++] = v;
        }
    }
    void solve(){
        int n = in.nextInt();
        for(int i = 0; i <= n; i++)al[i] = new ArrayList<>();
        for(int i = 0; i < n - 1; i++){
            int u = in.nextInt(), v = in.nextInt();
            al[u].add(v); al[v].add(u);
        }
        dfs(1, 0);
        val[p++] = 1;
        int dp[][] = new int[n + 1][2];
        for(int i = 0; i < p; i++){
            int node = val[i];
            // System.out.print(node + " ");
            if(dp[node][0] != 0)dp[node][1] = i + 1;
            else dp[node][0] = i + 1;
        }
        for(int i = 1; i <= n; i++){
            out.println(dp[i][0] + " " + dp[i][1]);
        }
    }
    public static class InputReader{
        BufferedReader br;
        StringTokenizer st;
        InputReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }
        public int nextInt(){
            return Integer.parseInt(next());
        }
        public long nextLong(){
            return Long.parseLong(next());
        }
        public double nextDouble(){
            return Double.parseDouble(next());
        }
        public String next(){
            while(st == null || !st.hasMoreTokens()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch(IOException e){}
            }
            return st.nextToken();
        }
    }
}


import java.util.*;
import java.io.*;
public class Main{
    static PrintWriter out;
    static InputReader in;
    public static void main(String args[]){
        out = new PrintWriter(System.out);
        in = new InputReader();
        new Main();
        out.flush(); out.close();
    }
    Main(){
        solve();
    }
    class pair{
        int F, S;
        pair(int a, int b){
            F = a; S = b;
        }
    }
    final int max = 500010;
    int val[] = new int[2 * max];
    ArrayList<Integer> al[] = new ArrayList[max];
    int p = 0;
    void dfs(int u, int pa){
        for(int v : al[u]){
            if(v == pa)continue;
            dfs(v, u);
        }
        val[p++] = u;
        for(int i = al[u].size() - 1; i >= 0; i--){
            int v = al[u].get(i);
            if(v == pa)continue;
            val[p++] = v;
        }
    }
    void solve(){
        int n = in.nextInt();
        for(int i = 0; i <= n; i++)al[i] = new ArrayList<>();
        for(int i = 0; i < n - 1; i++){
            int u = in.nextInt(), v = in.nextInt();
            al[u].add(v); al[v].add(u);
        }
        dfs(1, 0);
        val[p++] = 1;
        int dp[][] = new int[n + 1][2];
        for(int i = 0; i < p; i++){
            int node = val[i];
            // System.out.print(node + " ");
            if(dp[node][0] != 0)dp[node][1] = i + 1;
            else dp[node][0] = i + 1;
        }
        for(int i = 1; i <= n; i++){
            out.println(dp[i][0] + " " + dp[i][1]);
        }
    }
    public static class InputReader{
        BufferedReader br;
        StringTokenizer st;
        InputReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }
        public int nextInt(){
            return Integer.parseInt(next());
        }
        public long nextLong(){
            return Long.parseLong(next());
        }
        public double nextDouble(){
            return Double.parseDouble(next());
        }
        public String next(){
            while(st == null || !st.hasMoreTokens()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch(IOException e){}
            }
            return st.nextToken();
        }
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

// written by luchy0120

public class Main {
    public static void main(String[] args) throws Exception {

        new Main().run();
    }

    int cnt=1;
    int ps[][];

    void dfs(int rt,int fa){
        int sz =g[rt].size();

        for(int i=0;i<sz;++i){
            int v = g[rt].get(i);
            if(v==fa) continue;
            if(ps[v][0]==0) {
                ps[v][0] = cnt++;
            }else{
                ps[v][1] = cnt++;
            }
        }

            ps[rt][1] = cnt++;

        for(int i=sz-1;i>=0;--i){
            int v = g[rt].get(i);
            if(v==fa) continue;
            dfs(v, rt);
        }
    }

    List<Integer> g[];
    void solve(){
        int n = ni();
       ps =new int[n+1][2];
        g = new ArrayList[n+1];

        for(int i=1;i<=n;++i){
            g[i] = new ArrayList<>();
        }

        for(int i=0;i<n-1;++i){
            int u = ni();
            int v = ni();
            g[u].add(v);
            g[v].add(u);
        }
        ps[1][0] = cnt++;
        dfs(1,-1);
        for(int i=1;i<=n;++i){
           println(ps[i][0]+" "+ps[i][1]);
        }

    }

    public static String roundS(double result, int scale){
        String fmt = String.format("%%.%df", scale);
        return String.format(fmt, result);
    }

//    void solve() {
//
//        for(int i=0;i<9;++i) {
//            for (int j = 0; j < 9; ++j) {
//                int v = ni();
//                a[i][j] = v;
//                if(v>0) {
//                    vis_row[i][v] = true;
//                    vis_col[j][v] = true;
//                    vis_room[get_room(i, j)][v] = true;
//                }else{
//                    space++;
//                }
//            }
//        }
//
//
//        prepare = new int[space][2];
//
//        int p = 0;
//
//        for(int i=0;i<9;++i) {
//            for (int j = 0; j < 9; ++j) {
//                if(a[i][j]==0){
//                    prepare[p][0] = i;
//                    prepare[p][1]= j;p++;
//                    List<Integer> temp =new ArrayList<>();
//                    for(int k=1;k<=9;++k){
//                        if(!vis_col[j][k]&&!vis_row[i][k]&&!vis_room[get_room(i,j)][k]){
//                            temp.add(k);
//                        }
//                    }
//                    int sz = temp.size();
//                    val[i][j] = new int[sz];
//                    for(int k=0;k<sz;++k){
//                        val[i][j][k] = temp.get(k);
//                    }
//                }
//            }
//        }
//        Arrays.sort(prepare,(x,y)->{
//           return Integer.compare(val[x[0]][x[1]].length,val[y[0]][y[1]].length);
//        });
//        dfs(0);
//
//
//
//
//
//
//
//
//
//
//    }

    InputStream is;
    PrintWriter out;

    void run() throws Exception {
        is = System.in;
        out = new PrintWriter(System.out);
        solve();
        out.flush();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private char ncc() {
        int b = readByte();
        return (char) b;
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private String nline() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!isSpaceChar(b) || b == ' ') {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[][] nm(int n, int m) {
        char[][] a = new char[n][];
        for (int i = 0; i < n; i++) a[i] = ns(m);
        return a;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private long[] nal(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++) a[i] = nl();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
        }
        ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        while (true) {
            if (b >= '0' && b <= '9') num = (num << 3) + (num << 1) + (b - '0');
            else return minus ? -num : num;
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) {
        }
        ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        while (true) {
            if (b >= '0' && b <= '9') num = num * 10 + (b - '0');
            else return minus ? -num : num;
            b = readByte();
        }
    }

    void print(Object obj) {
        out.print(obj);
    }

    void println(Object obj) {
        out.println(obj);
    }

    void println() {
        out.println();
    }

    void printArray(int a[],int from){
        int l = a.length;
        for(int i=from;i<l;++i){
            print(a[i]);
            if(i!=l-1){
                print(" ");
            }
        }
        println();
    }

    void printArray(long a[],int from){
        int l = a.length;
        for(int i=from;i<l;++i){
            print(a[i]);
            if(i!=l-1){
                print(" ");
            }
        }
        println();
    }
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class E {
	static PrintWriter out = new PrintWriter(System.out);

	static int[] l, r, sz;
	static ArrayList<Integer> adj[];
	static int N;

	public static void main(String args[]){
		new Thread(null, ()->asdf(args), "", 1<<28).start();
	}
	public static void asdf(String[] args) {
		FS in = new FS();
		N = in.nextInt();
		l = new int[N];
		r = new int[N];
		adj = new ArrayList[N];
		for(int i = 0; i < N; i++) {
			adj[i] = new ArrayList<Integer>();
		}
		for(int i = 0; i < N-1; i++) {
			int a = in.nextInt()-1;
			int b = in.nextInt()-1;
			adj[a].add(b);
			adj[b].add(a);
		}
		sz = new int[N];
		getSz(0, -1);
		l = new int[N];
		r = new int[N];
		dfs(0, -1, 1, 2*N);

		for(int i = 0; i < N; i++) {
			out.println(l[i]+" "+r[i]);
		}
		out.close();
	}

	static void getSz(int node, int p) {
		sz[node] = 1;
		for(int ii : adj[node]) {
			if(ii != p) { getSz(ii, node);
			sz[node] += sz[ii];
			}
		}
	}
	static void dfs(int node, int p, int ll, int rr) {
		if(p == -1) {
			l[node] = ll++;
			for(int ii : adj[node]) if(ii != p) r[ii] = rr--;
			r[node] = rr--;
			for(int ii : adj[node]) {
				if(ii != p) {
					int give = 2*sz[ii]-1;
					dfs(ii, node, ll, ll+give-1);
					ll += give;
				}
			}
		}
		else {
			for(int ii : adj[node]) if(ii != p) r[ii] = rr--;
			l[node] = rr--;
			for(int ii : adj[node]) {
				if(ii != p) {
					int give = 2*sz[ii]-1;
					dfs(ii, node, ll, ll+give-1);
					ll += give;
				}
			}
		}

	}

	static class FS{
		BufferedReader br;
		StringTokenizer st;
		public FS() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}
		String next() {
			while(st == null || !st.hasMoreElements()) {
				try {st = new StringTokenizer(br.readLine());}
				catch(Exception e) { throw null;}
			}
			return st.nextToken();
		}
		int nextInt() { return Integer.parseInt(next());}
		double nextDouble() { return Double.parseDouble(next());}
		long nextLong() { return Long.parseLong(next());}
		int[] NIA(int n) {
			int r[] = new int[n];
			for(int i = 0; i < n; i++) r[i] = nextInt();
			return r;
		}
		long[] NLA(int n) {
			long r[] = new long[n];
			for(int i = 0; i < n; i++) r[i] = nextLong();
			return r;
		}
		char[][] grid(int r, int c){
			char res[][] = new char[r][c];
			for(int i = 0; i < r; i++) {
				char l[] = next().toCharArray();
				for(int j = 0; j < c; j++) {
					res[i][j] = l[j];
				}
			}
			return res;
		}
	}

}


//package cf;
import java.io.*;
import java.util.*;
import java.lang.*;
import java.math.*;
public class USACO {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter (System.out);
        //BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
        //StringTokenizer st = new StringTokenizer(reader.readLine()," ");
        int n = Integer.parseInt(reader.readLine());
        HashMap<Integer,List<Integer>> edges = new HashMap<>();
        for (int i=0;i<n;i++) edges.put(i,new ArrayList<>());
        for (int i=0;i<n-1;i++) {
        	StringTokenizer st = new StringTokenizer(reader.readLine()," ");
        	int a = Integer.parseInt(st.nextToken())-1;
        	int b = Integer.parseInt(st.nextToken())-1;
        	edges.get(a).add(b);
        	edges.get(b).add(a);
        }
        Stack<Integer> dfs = new Stack<>();
        int[] answer = new int[2*n];
        int count=1;
        /*for (int i=0;i<edges.get(0).size();i++) {
        	answer[count]=edges.get(0).get(i);
        	count++;
        }*/
        int[] dead = new int[n];
        dfs.push(0);
        while (!dfs.isEmpty()) {
        	int k = dfs.pop();
    		if (dead[k]==0) {
        		for (int i=edges.get(k).size()-1;i>=0;i--) {
        			if (dead[edges.get(k).get(i)]==1) edges.get(k).remove(i);
        		}
        		for (int i=0;i<edges.get(k).size();i++) {
        			//System.out.println(k+" "+count);
        			answer[count]=edges.get(k).get(i);
        			count++;
        		}
        		answer[count]=k;
        		count++;
    		}
    		dead[k]=1;
        	if (!edges.get(k).isEmpty()) {
        		dfs.push(k);
        		int m=edges.get(k).get(edges.get(k).size()-1); // next in pushpop
        		edges.get(k).remove(edges.get(k).size()-1);
        		dfs.push(m);
        	}
        }
        int[] reformat = new int[2*n];
        int[] openclose = new int[n];
        for (int i=0;i<2*n;i++) {
        	if (openclose[answer[i]]==0) reformat[2*answer[i]]=i;
        	else reformat[2*answer[i]+1]=i;
        	openclose[answer[i]]++;
        }
        for (int i=0;i<n;i++) {
        	out.println((reformat[2*i]+1)+" "+(reformat[2*i+1]+1));
        }
        reader.close();
        out.close();
    }
}


/*********** This template help me to solve the SLOW I/O ***********/

import java.io.*;
import java.util.*;
import java.lang.*;
import java.math.*;
public class Main extends Thread  {
    public static int[] visit;
    public static int max=1;
    public static int[][] arr;
    public static ArrayList<Integer>[] adj;
    boolean[] prime;
    FastScanner sc;
    PrintWriter pw;
    MathF mf;
    final class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner() {
            try {
                br = new BufferedReader(new InputStreamReader(System.in));
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public long nlo() {
            return Long.parseLong(next());
        }

        public String next() {
            if (st.hasMoreTokens()) return st.nextToken();
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return st.nextToken();
        }

        public int ni() {
            return Integer.parseInt(next());
        }

        public String nli() {
            String line = "";
            if (st.hasMoreTokens()) line = st.nextToken();
            else try {
                return br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            while (st.hasMoreTokens()) line += " " + st.nextToken();
            return line;
        }

        public double nd() {
            return Double.parseDouble(next());
        }
    }
    final class MathF {
        long grtdiv(long x)
        {
            if(isPrime(x))
                return 1;
            else
            {
                long ans=0;
                long y=(long)Math.sqrt(x)+1;
                for(;y>=2;y--)
                {
                    if(x%y==0)
                        ans=Math.max(ans,Math.max(y,x/y));
                }
                return ans;
            }
        }
        boolean isPrime(long x)
        {
            for(int i=2;i*i<=x;i++)
            {
                if(x%i==0)
                {
                    return false;
                }
            }
            return true;
        }
        long[][] mul(long[][] arr,long[][] brr,int a,int b,int c,int d)
        {
            long[][] crr=new long[a][d];
            for(int i=0;i<a;i++)
            {
                for(int j=0;j<d;j++)
                {
                    for(int k=0;k<b;k++)
                    {
                        crr[i][j]+=(((arr[i][k]%1000000007)*(brr[k][j]%1000000007))%1000000007);
                    }
                }
            }
            return crr;
        }
        int sod(long a)
        {
            int ans=0;
            while(a!=0)
            {
                ans+=(a%10);
                a=a/10;
            }
            return ans;
        }
        long pow(long a,long b)
        {
            if(b==0)
                return 1;
            else
            {
                long x=pow(a,b/2);
                if(b%2==1)
                    return (x*x*a);
                else
                    return (x*x);
            }
        }
        public  long gcd(long a, long b) {
            return (b == 0 ? a : gcd(b, a % b));
        }
        public long exponent(long a,long b)
        {
            if(b==0)
                return 1;
            else
            {
                long x=exponent(a,b/2);
                x*=x;
                if(b%2==1)
                    x*=a;
                return x;
            }
        }
        public  int nod(long x) {
            int i = 0;
            while (x != 0) {
                i++;
                x = x / 10;
            }
            return i;
        }

        public  int nob(long x) {
            if(x==0)
                return 1;
            return (int) Math.floor(Math.log(x) / Math.log(2)) + 1;
        }

        public int[] FastradixSort(int[] f) {
            int[] to = new int[f.length];
            {
                int[] b = new int[65537];
                for (int i = 0; i < f.length; i++) b[1 + (f[i] & 0xffff)]++;
                for (int i = 1; i <= 65536; i++) b[i] += b[i - 1];
                for (int i = 0; i < f.length; i++) to[b[f[i] & 0xffff]++] = f[i];
                int[] d = f;
                f = to;
                to = d;
            }
            {
                int[] b = new int[65537];
                for (int i = 0; i < f.length; i++) b[1 + (f[i] >>> 16)]++;
                for (int i = 1; i <= 65536; i++) b[i] += b[i - 1];
                for (int i = 0; i < f.length; i++) to[b[f[i] >>> 16]++] = f[i];
                int[] d = f;
                f = to;
                to = d;
            }
            return f;
        }

        public  void Primesieve(int n) {
            prime=new boolean[n];
            for (int i = 0; i < n; i++)
                prime[i] = true;
            for (int p = 2; p * p < n; p++) {
                if (prime[p] == true) {
                    for (int i = p * p; i < n; i += p)
                        prime[i] = false;
                }
            }
        }
    }
    public Main(ThreadGroup t,Runnable r,String s,long d )
    {
        super(t,r,s,d);
    }
    public void run()
    {
        sc=new FastScanner();
        pw=new PrintWriter(System.out);
        mf=new MathF();
        solve();
        pw.flush();
        pw.close();
    }
    public static void main(String[] args)
    {
        new Main(null,null,"",1<<30).start();
    }

    /////////////------------------------------------/////////////
    /////////////------------------------------------/////////////
    ////////////------------------MAIN-LOGIC---------/////////////
    ////////////-------------------------------------/////////////
    ///////////--------------------------------------/////////////

    public void solve() {
     	int n=sc.ni();
		adj=new ArrayList[n];
		for(int i=0;i<n;i++)
		adj[i]=new ArrayList();
		visit=new int[n];
		arr=new int[n][2];
		for(int i=0;i<n-1;i++)
		{
		    int x=sc.ni();
		    int y=sc.ni();
		    x--;y--;
		   // System.out.println(x+" "+y);
		    adj[x].add(y);
		    adj[y].add(x);
		}
		Stack<Integer> stk=new Stack();
	    for(int x:adj[0])
	    {
	        stk.push(x);
	        arr[x][0]=max++;
	        //System.out.println(x+" 0     :"+arr[x][0]);
	    }
	    visit[0]=1;
	    arr[0][0]=max++;
	    while(!stk.isEmpty())
	    {
	        solve(stk.pop());
	    }
	    arr[0][1]=max++;
	    for(int i=0;i<n;i++)
	    pw.println(arr[i][0]+" "+arr[i][1]);
    }
    public static void solve(int x)
	{
	    visit[x]=1;
	    Stack<Integer> stk=new Stack();
	    for(int k:adj[x])
	    {
	        if(visit[k]==0)
	        {stk.push(k);
	        arr[k][0]=max++;
	       // System.out.println(x+" 0     :"+arr[x][0]);

	        }
	    }
	    arr[x][1]=max++;
	    //System.out.println(x+" 1     :"+arr[x][1]);
	    while(!stk.isEmpty())
	    {
	        solve(stk.pop());
	    }
	}
}


import java.util.*;
import java.io.*;
public class Main
{
    public static int[] visit;
    public static int max=1;
    public static int[][] arr;
    public static ArrayList<Integer>[] adj;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		PrintWriter pw=new PrintWriter(System.out);
		int n=sc.nextInt();
		adj=new ArrayList[n];
		for(int i=0;i<n;i++)
		adj[i]=new ArrayList();
		visit=new int[n];
		arr=new int[n][2];
		for(int i=0;i<n-1;i++)
		{
		    int x=sc.nextInt();
		    int y=sc.nextInt();
		    x--;y--;
		    adj[x].add(y);
		    adj[y].add(x);
		}
		Stack<Integer> stk=new Stack();
	    for(int x:adj[0])
	    {
	        stk.push(x);
	        arr[x][0]=max++;
	        //System.out.println(x+" 0     :"+arr[x][0]);
	    }
	    visit[0]=1;
	    arr[0][0]=max++;
	    while(!stk.isEmpty())
	    {
	        solve(stk.pop());
	    }
	    arr[0][1]=max++;
	    for(int i=0;i<n;i++)
	    pw.println(arr[i][0]+" "+arr[i][1]);
	    pw.flush();
	    pw.close();
	}
	public static void solve(int x)
	{
	    visit[x]=1;
	    Stack<Integer> stk=new Stack();
	    for(int k:adj[x])
	    {
	        if(visit[k]==0)
	        {stk.push(k);
	        arr[k][0]=max++;
	       // System.out.println(x+" 0     :"+arr[x][0]);

	        }
	    }
	    arr[x][1]=max++;
	    //System.out.println(x+" 1     :"+arr[x][1]);
	    while(!stk.isEmpty())
	    {
	        solve(stk.pop());
	    }
	}
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main{
	public static class FastReader {
		BufferedReader br;
		StringTokenizer root;

		public FastReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			while (root == null || !root.hasMoreTokens()) {
				try {
					root = new StringTokenizer(br.readLine());
				} catch (Exception r) {
					r.printStackTrace();
				}
			}
			return root.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (Exception r) {
				r.printStackTrace();
			}
			return str;
		}
	}

	public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));
	static long mod = (long) (1e9+7);
	static long cf = 998244353;
    static final long MAX = (long) 1e8;
    public static List<Integer>[] edges;
    public static int[][] parent;
    public static long[] fac;
    public static int N = (int) 1e5;
    public static int x = 0;
	public static void main(String[] args) {
		FastReader sc = new FastReader();

		int n = sc.nextInt();
		edges = new ArrayList[n+1];
		for(int i=0;i<=n;++i) edges[i] = new ArrayList<>();

		for(int i=0;i<n-1;++i) {
			int u = sc.nextInt();
			int v = sc.nextInt();
			edges[u].add(v);
			edges[v].add(u);
		}
		int[] l = new int[n+1];
		int[] r = new int[n+1];
		l[1] = ++x;
		dfs(1,0,l,r);
		for(int i=1;i<=n;++i) out.println(l[i] +" "+ r[i]);

		out.close();
}
	private static void dfs(int v, int p, int[] l, int[] r) {
		for(int child : edges[v]) {
			if(child != p) {
				l[child] = ++x; // add each child
			}
		}
		// close parent
		r[v] = ++x;
		for(int i = edges[v].size()-1;i>=0;--i) {
			int child = edges[v].get(i);
			if(child != p)
				dfs(child,v,l,r);
		}

	}

}


import java.io.*;
import java.util.StringTokenizer;

public class ETask {
    private static final String QUICK_ANSWER = "NO";
    private final Input in;
    private final StringBuilder out;
    private int n;
    int[] from;
    int[] to;
    private Tree tree;

    public ETask(Input in, StringBuilder out) {
        this.in = in;
        this.out = out;
    }

    public void solve() throws QuickAnswer {
        n = nextInt();
        from = new int[n];
        to = new int[n];
        tree = Tree.treeBuilder()
                .nodeCount(n)
                .build(this::nextInt);
        place(0, 1, 2);
        for (int i = 0; i < n; i++) {
            println(from[i] + " " + to[i]);
        }
    }

    int place(int node, int start, int cont) {
        from[node] = start;
        int[] children = tree.children[node];
        to[node] = cont + children.length;
        int end = cont + children.length + 1;
        for (int i = 0; i < children.length; ++i) {
            end = place(children[i], cont + children.length - 1 - i, end);
        }
        return end;
    }

    // Common functions

    private static class Input {
        private final BufferedReader in;
        private StringTokenizer tokenizer = null;

        public Input(BufferedReader in) {
            this.in = in;
        }

        String nextToken() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) tokenizer = new StringTokenizer(in.readLine());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return tokenizer.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        String nextLine() {
            try {
                return in.readLine();
            } catch (IOException e) {
                return "";
            }
        }
    }

    void quickAnswer(String answer) throws QuickAnswer {
        throw new QuickAnswer(answer);
    }

    void quickAnswer() throws QuickAnswer {
        quickAnswer(QUICK_ANSWER);
    }

    static class QuickAnswer extends Exception {
        private String answer;

        public QuickAnswer(String answer) {
            this.answer = answer;
        }
    }

    void print(Object... args) {
        String prefix = "";
        for (Object arg : args) {
            out.append(prefix);
            out.append(arg);
            prefix = " ";
        }
    }

    void println(Object... args) {
        print(args);
        out.append("\n");
    }

    void printsp(Object... args) {
        print(args);
        out.append(" ");
    }

    int nextInt() {
        return in.nextInt();
    }

    long nextLong() {
        return in.nextLong();
    }

    String nextString() {
        return in.nextLine();
    }

    int[] nextInts(int count) {
        int[] res = new int[count];
        for (int i = 0; i < count; ++i) {
            res[i] = nextInt();
        }
        return res;
    }

    int[][] nextInts(int count, int n) {
        int[][] res = new int[n][count];
        for (int i = 0; i < count; ++i) {
            for (int j = 0; j < n; j++) {
                res[j][i] = nextInt();
            }
        }
        return res;
    }

    long[] nextLongs(int count) {
        long[] res = new long[count];
        for (int i = 0; i < count; ++i) {
            res[i] = nextLong();
        }
        return res;
    }

    long[][] nextLongs(int count, int n) {
        long[][] res = new long[n][count];
        for (int i = 0; i < count; ++i) {
            for (int j = 0; j < n; j++) {
                res[j][i] = nextLong();
            }
        }
        return res;
    }

    public static void main(String[] args) {
        doMain(System.in, System.out);
    }

    static void doMain(InputStream inStream, PrintStream outStream) {
        Input in = new Input(new BufferedReader(new InputStreamReader(inStream)));
        StringBuilder totalOut = new StringBuilder();
        int count = 1;
        //count = in.nextInt();
        while (count-- > 0) {
            try {
                StringBuilder out = new StringBuilder();
                new ETask(in, out).solve();
                totalOut.append(out.toString());
            } catch (QuickAnswer e) {
                totalOut.append(e.answer);
            }
            if (count > 0) {
                totalOut.append("\n");
            }
        }
        outStream.print(totalOut.toString());
    }

    static class Graph {
        interface Input {
            int nextInt();
        }

        final int nodeCount;
        final int edgeCount;
        final int[][] neighbors;
        final int[] color;
        final int[] edgeFrom;
        final int[] edgeTo;
        final int[] edgeWeight;

        static Builder builder() {
            return new Builder();
        }

        static class Builder {
            int adjustIndex = -1;
            boolean withWeights = false;
            int nodeCount = -1;
            int edgeCount = -1;

            Builder adjustIndex(int adjustIndex) {
                this.adjustIndex = adjustIndex;
                return this;
            }

            Builder withWeights() {
                this.withWeights = true;
                return this;
            }

            Builder nodeCount(int n) {
                this.nodeCount = n;
                return this;
            }

            Builder edgeCount(int m) {
                this.edgeCount = m;
                return this;
            }

            Graph build(Input in) {
                return new Graph(
                        in,
                        nodeCount == -1 ? in.nextInt() : nodeCount,
                        edgeCount == -1 ? in.nextInt() : edgeCount,
                        adjustIndex,
                        withWeights);
            }
        }

        Graph(Input in, int nodeCount, int m, int adjustIndex, boolean withWeights) {
            this.nodeCount = nodeCount;
            this.edgeCount = m;
            this.color = new int[nodeCount];
            int[] cnt = new int[nodeCount];
            edgeFrom = new int[m];
            edgeTo = new int[m];
            edgeWeight = new int[m];
            for (int i = 0; i < m; ++i) {
                int x = in.nextInt() + adjustIndex;
                int y = in.nextInt() + adjustIndex;
                edgeFrom[i] = x;
                edgeTo[i] = y;
                edgeWeight[i] = withWeights ? in.nextInt() : 1;
                cnt[x]++;
                cnt[y]++;
            }
            this.neighbors = new int[nodeCount][];
            for (int i = 0; i < nodeCount; i++) {
                neighbors[i] = new int[cnt[i]];
            }
            for (int i = 0; i < m; ++i) {
                int from = edgeFrom[i];
                int to = edgeTo[i];
                neighbors[from][--cnt[from]] = to;
                neighbors[to][--cnt[to]] = from;
            }
        }
    }

    static class IntQueue {
        final int[] togo;
        int curr;
        int end;

        public IntQueue(int maxLen) {
            togo = new int[maxLen];
        }

        void add(int val) {
            togo[end++] = val;
        }

        int poll() {
            return togo[curr++];
        }

        boolean isEmpty() {
            return curr == end;
        }
    }

    static class Tree extends Graph {
        final int[] level;
        final int[] parent;
        final int[][] children;

        static Builder treeBuilder() {
            return new Builder();
        }

        static class Builder {
            private int rootNode = 0;
            int adjustIndex = -1;
            boolean withWeights = false;
            int nodeCount = -1;

            Builder rootNode(int rootNode) {
                this.rootNode = rootNode;
                return this;
            }

            Builder adjustIndex(int adjustIndex) {
                this.adjustIndex = adjustIndex;
                return this;
            }

            Builder withWeights() {
                this.withWeights = true;
                return this;
            }

            Builder nodeCount(int n) {
                this.nodeCount = n;
                return this;
            }

            public Tree build(Input in) {
                return new Tree(
                        in,
                        nodeCount == -1 ? in.nextInt() : nodeCount,
                        adjustIndex,
                        withWeights,
                        rootNode);
            }
        }

        Tree(Input in, int n, int adjustIndex, boolean withWeights, int rootNode) {
            super(in, n, n - 1, adjustIndex, withWeights);
            level = new int[n];
            parent = new int[n];
            children = new int[n][];

            IntQueue iq = new IntQueue(n);
            level[rootNode] = 0;
            parent[rootNode] = -1;
            iq.add(rootNode);
            while (!iq.isEmpty()) {
                int node = iq.poll();
                int childLevel = level[node] + 1;
                if (parent[node] == -1) {
                    children[node] = new int[neighbors[node].length];
                } else {
                    children[node] = new int[neighbors[node].length - 1];
                }
                int curr = 0;
                for (int neighbor : neighbors[node]) {
                    if (neighbor == parent[node]) continue;
                    level[neighbor] = childLevel;
                    parent[neighbor] = node;
                    children[node][curr++] = neighbor;
                    iq.add(neighbor);
                }
            }
        }
    }
}


import java.io.*;
import java.util.StringTokenizer;

public class ETask {
    private static final String QUICK_ANSWER = "NO";
    private final Input in;
    private final StringBuilder out;
    private int n;
    int[] from;
    int[] to;
    private Tree tree;

    public ETask(Input in, StringBuilder out) {
        this.in = in;
        this.out = out;
    }

    public void solve() throws QuickAnswer {
        n = nextInt();
        from = new int[n];
        to = new int[n];
        tree = Tree.treeBuilder()
                .nodeCount(n)
                .build(this::nextInt);
        place(0, 1, 2);
        for (int i = 0; i < n; i++) {
            println(from[i] + " " + to[i]);
        }
    }

    int place(int node, int start, int cont) {
        from[node] = start;
        int[] children = tree.children[node];
        to[node] = cont + children.length;
        int end = cont + children.length + 1;
        for (int child : children) {
            end = place(child, cont++, end);
        }
        return end;
    }

    // Common functions

    private static class Input {
        private final BufferedReader in;
        private StringTokenizer tokenizer = null;

        public Input(BufferedReader in) {
            this.in = in;
        }

        String nextToken() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) tokenizer = new StringTokenizer(in.readLine());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return tokenizer.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        String nextLine() {
            try {
                return in.readLine();
            } catch (IOException e) {
                return "";
            }
        }
    }

    void quickAnswer(String answer) throws QuickAnswer {
        throw new QuickAnswer(answer);
    }

    void quickAnswer() throws QuickAnswer {
        quickAnswer(QUICK_ANSWER);
    }

    static class QuickAnswer extends Exception {
        private String answer;

        public QuickAnswer(String answer) {
            this.answer = answer;
        }
    }

    void print(Object... args) {
        String prefix = "";
        for (Object arg : args) {
            out.append(prefix);
            out.append(arg);
            prefix = " ";
        }
    }

    void println(Object... args) {
        print(args);
        out.append("\n");
    }

    void printsp(Object... args) {
        print(args);
        out.append(" ");
    }

    int nextInt() {
        return in.nextInt();
    }

    long nextLong() {
        return in.nextLong();
    }

    String nextString() {
        return in.nextLine();
    }

    int[] nextInts(int count) {
        int[] res = new int[count];
        for (int i = 0; i < count; ++i) {
            res[i] = nextInt();
        }
        return res;
    }

    int[][] nextInts(int count, int n) {
        int[][] res = new int[n][count];
        for (int i = 0; i < count; ++i) {
            for (int j = 0; j < n; j++) {
                res[j][i] = nextInt();
            }
        }
        return res;
    }

    long[] nextLongs(int count) {
        long[] res = new long[count];
        for (int i = 0; i < count; ++i) {
            res[i] = nextLong();
        }
        return res;
    }

    long[][] nextLongs(int count, int n) {
        long[][] res = new long[n][count];
        for (int i = 0; i < count; ++i) {
            for (int j = 0; j < n; j++) {
                res[j][i] = nextLong();
            }
        }
        return res;
    }

    public static void main(String[] args) {
        doMain(System.in, System.out);
    }

    static void doMain(InputStream inStream, PrintStream outStream) {
        Input in = new Input(new BufferedReader(new InputStreamReader(inStream)));
        StringBuilder totalOut = new StringBuilder();
        int count = 1;
        //count = in.nextInt();
        while (count-- > 0) {
            try {
                StringBuilder out = new StringBuilder();
                new ETask(in, out).solve();
                totalOut.append(out.toString());
            } catch (QuickAnswer e) {
                totalOut.append(e.answer);
            }
            if (count > 0) {
                totalOut.append("\n");
            }
        }
        outStream.print(totalOut.toString());
    }

    static class Graph {
        interface Input {
            int nextInt();
        }

        final int nodeCount;
        final int edgeCount;
        final int[][] neighbors;
        final int[] color;
        final int[] edgeFrom;
        final int[] edgeTo;
        final int[] edgeWeight;

        static Builder builder() {
            return new Builder();
        }

        static class Builder {
            int adjustIndex = -1;
            boolean withWeights = false;
            int nodeCount = -1;
            int edgeCount = -1;

            Builder adjustIndex(int adjustIndex) {
                this.adjustIndex = adjustIndex;
                return this;
            }

            Builder withWeights() {
                this.withWeights = true;
                return this;
            }

            Builder nodeCount(int n) {
                this.nodeCount = n;
                return this;
            }

            Builder edgeCount(int m) {
                this.edgeCount = m;
                return this;
            }

            Graph build(Input in) {
                return new Graph(
                        in,
                        nodeCount == -1 ? in.nextInt() : nodeCount,
                        edgeCount == -1 ? in.nextInt() : edgeCount,
                        adjustIndex,
                        withWeights);
            }
        }

        Graph(Input in, int nodeCount, int m, int adjustIndex, boolean withWeights) {
            this.nodeCount = nodeCount;
            this.edgeCount = m;
            this.color = new int[nodeCount];
            int[] cnt = new int[nodeCount];
            edgeFrom = new int[m];
            edgeTo = new int[m];
            edgeWeight = new int[m];
            for (int i = 0; i < m; ++i) {
                int x = in.nextInt() + adjustIndex;
                int y = in.nextInt() + adjustIndex;
                edgeFrom[i] = x;
                edgeTo[i] = y;
                edgeWeight[i] = withWeights ? in.nextInt() : 1;
                cnt[x]++;
                cnt[y]++;
            }
            this.neighbors = new int[nodeCount][];
            for (int i = 0; i < nodeCount; i++) {
                neighbors[i] = new int[cnt[i]];
            }
            for (int i = 0; i < m; ++i) {
                int from = edgeFrom[i];
                int to = edgeTo[i];
                neighbors[from][--cnt[from]] = to;
                neighbors[to][--cnt[to]] = from;
            }
        }
    }

    static class IntQueue {
        final int[] togo;
        int curr;
        int end;

        public IntQueue(int maxLen) {
            togo = new int[maxLen];
        }

        void add(int val) {
            togo[end++] = val;
        }

        int poll() {
            return togo[curr++];
        }

        boolean isEmpty() {
            return curr == end;
        }
    }

    static class Tree extends Graph {
        final int[] level;
        final int[] parent;
        final int[][] children;

        static Builder treeBuilder() {
            return new Builder();
        }

        static class Builder {
            private int rootNode = 0;
            int adjustIndex = -1;
            boolean withWeights = false;
            int nodeCount = -1;

            Builder rootNode(int rootNode) {
                this.rootNode = rootNode;
                return this;
            }

            Builder adjustIndex(int adjustIndex) {
                this.adjustIndex = adjustIndex;
                return this;
            }

            Builder withWeights() {
                this.withWeights = true;
                return this;
            }

            Builder nodeCount(int n) {
                this.nodeCount = n;
                return this;
            }

            public Tree build(Input in) {
                return new Tree(
                        in,
                        nodeCount == -1 ? in.nextInt() : nodeCount,
                        adjustIndex,
                        withWeights,
                        rootNode);
            }
        }

        Tree(Input in, int n, int adjustIndex, boolean withWeights, int rootNode) {
            super(in, n, n - 1, adjustIndex, withWeights);
            level = new int[n];
            parent = new int[n];
            children = new int[n][];

            IntQueue iq = new IntQueue(n);
            level[rootNode] = 0;
            parent[rootNode] = -1;
            iq.add(rootNode);
            while (!iq.isEmpty()) {
                int node = iq.poll();
                int childLevel = level[node] + 1;
                if (parent[node] == -1) {
                    children[node] = new int[neighbors[node].length];
                } else {
                    children[node] = new int[neighbors[node].length - 1];
                }
                int curr = 0;
                for (int neighbor : neighbors[node]) {
                    if (neighbor == parent[node]) continue;
                    level[neighbor] = childLevel;
                    parent[neighbor] = node;
                    children[node][curr++] = neighbor;
                    iq.add(neighbor);
                }
            }
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.io.UncheckedIOException;
import java.util.List;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            ETestsForProblemD solver = new ETestsForProblemD();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class ETestsForProblemD {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            Node[] nodes = new Node[n];
            for (int i = 0; i < n; i++) {
                nodes[i] = new Node();
            }
            for (int i = 1; i < n; i++) {
                Node a = nodes[in.readInt() - 1];
                Node b = nodes[in.readInt() - 1];
                a.next.add(b);
                b.next.add(a);
            }

            dfs(nodes[0], null);
            for (int i = 0; i < n; i++) {
                Splay.splay(nodes[i].left);
                out.append(nodes[i].left.size - nodes[i].left.right.size).append(' ');
                Splay.splay(nodes[i].right);
                out.println(nodes[i].right.size - nodes[i].right.right.size);
            }
        }

        public Splay dfs(Node root, Node p) {
            root.next.remove(p);
            Splay splay = Splay.NIL;
            for (int i = 0; i < root.next.size(); i++) {
                Node node = root.next.get(i);
                Splay child = dfs(node, root);
                if (splay == Splay.NIL) {
                    splay = child;
                    continue;
                }
                splay = Splay.selectKthAsRoot(splay, i);
                Splay right = Splay.splitRight(splay);
                splay = Splay.merge(splay, child);
                splay = Splay.merge(splay, right);
            }

            splay = Splay.merge(root.left, splay);
            splay = Splay.selectKthAsRoot(splay, root.next.size() + 1);
            Splay right = Splay.splitRight(splay);
            splay = Splay.merge(splay, root.right);
            splay = Splay.merge(splay, right);

            return splay;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class Node {
        List<Node> next = new ArrayList<>();
        Splay left = new Splay();
        Splay right = new Splay();

    }

    static class Splay implements Cloneable {
        public static final Splay NIL = new Splay();
        Splay left = NIL;
        Splay right = NIL;
        Splay father = NIL;
        int size = 1;
        int key;

        static {
            NIL.left = NIL;
            NIL.right = NIL;
            NIL.father = NIL;
            NIL.size = 0;
        }

        public static void splay(Splay x) {
            if (x == NIL) {
                return;
            }
            Splay y, z;
            while ((y = x.father) != NIL) {
                if ((z = y.father) == NIL) {
                    y.pushDown();
                    x.pushDown();
                    if (x == y.left) {
                        zig(x);
                    } else {
                        zag(x);
                    }
                } else {
                    z.pushDown();
                    y.pushDown();
                    x.pushDown();
                    if (x == y.left) {
                        if (y == z.left) {
                            zig(y);
                            zig(x);
                        } else {
                            zig(x);
                            zag(x);
                        }
                    } else {
                        if (y == z.left) {
                            zag(x);
                            zig(x);
                        } else {
                            zag(y);
                            zag(x);
                        }
                    }
                }
            }

            x.pushDown();
            x.pushUp();
        }

        public static void zig(Splay x) {
            Splay y = x.father;
            Splay z = y.father;
            Splay b = x.right;

            y.setLeft(b);
            x.setRight(y);
            z.changeChild(y, x);

            y.pushUp();
        }

        public static void zag(Splay x) {
            Splay y = x.father;
            Splay z = y.father;
            Splay b = x.left;

            y.setRight(b);
            x.setLeft(y);
            z.changeChild(y, x);

            y.pushUp();
        }

        public void setLeft(Splay x) {
            left = x;
            x.father = this;
        }

        public void setRight(Splay x) {
            right = x;
            x.father = this;
        }

        public void changeChild(Splay y, Splay x) {
            if (left == y) {
                setLeft(x);
            } else {
                setRight(x);
            }
        }

        public void pushUp() {
            size = left.size + right.size + 1;
        }

        public void pushDown() {
        }

        public static void toString(Splay root, StringBuilder builder) {
            if (root == NIL) {
                return;
            }
            root.pushDown();
            toString(root.left, builder);
            builder.append(root.key).append(',');
            toString(root.right, builder);
        }

        public Splay clone() {
            try {
                return (Splay) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }

        public static Splay cloneTree(Splay splay) {
            if (splay == NIL) {
                return NIL;
            }
            splay = splay.clone();
            splay.left = cloneTree(splay.left);
            splay.right = cloneTree(splay.right);
            return splay;
        }

        public static Splay selectMaxAsRoot(Splay root) {
            if (root == NIL) {
                return root;
            }
            root.pushDown();
            while (root.right != NIL) {
                root = root.right;
                root.pushDown();
            }
            splay(root);
            return root;
        }

        public static Splay splitRight(Splay root) {
            root.pushDown();
            Splay right = root.right;
            right.father = NIL;
            root.setRight(NIL);
            root.pushUp();
            return right;
        }

        public static Splay merge(Splay a, Splay b) {
            if (a == NIL) {
                return b;
            }
            if (b == NIL) {
                return a;
            }
            a = selectMaxAsRoot(a);
            a.setRight(b);
            a.pushUp();
            return a;
        }

        public static Splay selectKthAsRoot(Splay root, int k) {
            if (root == NIL) {
                return NIL;
            }
            Splay trace = root;
            Splay father = NIL;
            while (trace != NIL) {
                father = trace;
                trace.pushDown();
                if (trace.left.size >= k) {
                    trace = trace.left;
                } else {
                    k -= trace.left.size + 1;
                    if (k == 0) {
                        break;
                    } else {
                        trace = trace.right;
                    }
                }
            }
            splay(father);
            return father;
        }

        public String toString() {
            StringBuilder builder = new StringBuilder().append(key).append(":");
            toString(cloneTree(this), builder);
            return builder.toString();
        }

    }

    static class FastOutput implements AutoCloseable, Closeable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(int c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            cache.append(c).append('\n');
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }
}


import java.util.*;
import java.io.*;
import java.math.*;

public class Main {
    static PrintWriter out;
    static Reader in;
    public static void main(String[] args) throws IOException {
        //out = new PrintWriter(new File("out.txt"));
        //PrintWriter out = new PrintWriter(System.out);
        //in = new Reader(new FileInputStream("in.txt"));
        //Reader in = new Reader();
        input_output();
        Main solver = new Main();
        solver.solve();
        out.flush();
        out.close();

    }

    static int INF = (int)1e9-1;
    static int maxn = (int)1e6+5;
    static int mod = 998_244_353;
    static int n, m, q, k, t;

    static List<Integer> adj[];

    void solve() throws IOException{
        n = in.nextInt();

        adj = new ArrayList[n+1];
        for (int i = 1; i <= n; i++) adj[i] = new ArrayList<Integer>();

        for (int i = 1; i < n; i++) {
            int u = in.nextInt(),
                v = in.nextInt();
            adj[u].add(v);
            adj[v].add(u);
        }

        ans = new int[2*n+1];
        cur = 2;
        ans[1] = 1;

        DFS(1, 0);

        int[][] pair = new int[n+1][2];
        for (int i = 1; i <= 2*n; i++) {
            int elm = ans[i];
            if (pair[elm][0] == 0) pair[elm][0] = i;
            else pair[elm][1] = i;
        }

        for (int i = 1; i <= n; i++) out.println(pair[i][0]+" "+pair[i][1]);
    }

    //<>

    static int cur, ans[];
    static void DFS(int s, int p) {
        int elm;
        for (int i = 0; i < adj[s].size(); i++) {
            elm = adj[s].get(i);
            if (elm == p) continue;
            ans[cur++] = elm;
        }
        ans[cur++] = s;
        for (int i = adj[s].size()-1; i >= 0; i--) {
            elm = adj[s].get(i);
            if (elm == p) continue;
            DFS(elm, s);
        }
    }

    static class Reader {

        private InputStream mIs;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public Reader() {
            this(System.in);
        }

        public Reader(InputStream is) {
            mIs = is;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();

        }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = mIs.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public String nextLine() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public String next() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

    }
    static void input_output() throws IOException {
        File f = new File("in.txt");
        if(f.exists() && !f.isDirectory()) {
            in = new Reader(new FileInputStream("in.txt"));
        } else in = new Reader();
        f = new File("out.txt");
        if(f.exists() && !f.isDirectory()) {
            out = new PrintWriter(new File("out.txt"));
        } else out = new PrintWriter(System.out);
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author John Martin
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        ETestsForProblemD solver = new ETestsForProblemD();
        solver.solve(1, in, out);
        out.close();
    }

    static class ETestsForProblemD {
        int nxt = 1;
        int[] l;
        int[] r;

        public void solve(int testNumber, InputReader c, OutputWriter w) {
            int n = c.readInt();
            ArrayList<Integer> adj[] = new ArrayList[n];
            for (int i = 0; i < n; i++) {
                adj[i] = new ArrayList<>();
            }
            for (int i = 0; i < n - 1; i++) {
                int u = c.readInt() - 1, v = c.readInt() - 1;
                adj[u].add(v);
                adj[v].add(u);
            }
            l = new int[n];
            r = new int[n];
            l[0] = nxt++;
            dfs(0, adj, -1);
            for (int i = 0; i < n; i++) {
                w.printLine(l[i], r[i]);
            }
        }

        private void dfs(int x, ArrayList<Integer>[] adj, int p) {

            for (int t : adj[x]) {
                if (t != p) {
                    l[t] = nxt++;
                }
            }
            r[x] = nxt++;
            Collections.reverse(adj[x]);

            for (int t : adj[x]) {
                if (t != p) {
                    dfs(t, adj, x);
                }
            }
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void printLine(Object... objects) {
            print(objects);
            writer.println();
        }

        public void close() {
            writer.close();
        }

    }
}