using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using Number = System.Int32;
namespace Program {
	public class Solver {
		Random rnd = new Random(1);
		public void Solve() {
			var n = ri;
			var G = Enumerate(n, x => new List<int>());
			for (int i = 0; i < n - 1; i++) {
				var u = ri - 1;
				var v = ri - 1;
				G[u].Add(v);
				G[v].Add(u);
			}
			int X = n + 50;
			int root = -1;

			for (int r = 0; r < n; r++) {
				int[] sz = new int[n];
				Func<int, int, int> dfs = null;
				dfs = (pre, cur) => {
					sz[cur] = 1;
					foreach (var t in G[cur])
						if (pre != t)
							sz[cur] += dfs(cur, t);
					return sz[cur];
				};
				dfs(-1, r);
				var max = -1;
				foreach (var t in G[r])
					max = Max(max, sz[t]);
				if (max < X) {
					X = max;
					root = r;
				}
			}
			solve(G, root);
			//1/3*2/3
		}
		void solve(List<int>[] G, int r) {
			var n = G.Length;
			int[] sz = new int[n];
			{
				Func<int, int, int> dfs = null;
				dfs = (pre, cur) => {
					sz[cur] = 1;
					foreach (var t in G[cur])
						if (t != pre)
							sz[cur] += dfs(cur, t);
					return sz[cur];
				};
				dfs(-1, r);
			}
			{
				G[r] = G[r].OrderByDescending(x => sz[x]).ToList();
				var v = 0;
				var dist = new int[n];

				var D = 1;
				var dx = 1;
				Action<int, int> dfs = null;
				dfs = (pre, cur) => {

					dist[cur] = D;
					if (v * 3 <= n) {
						D++;
						dx++;
					}
					else {
						D += dx;
					}
					Debug.WriteLine($"{pre} {cur} {D} {dist[cur]} {dist[pre]} {v}");
					Console.WriteLine($"{pre + 1} {cur + 1} {dist[cur] - dist[pre]}");
					foreach (var t in G[cur])
						if (t != pre) dfs(cur, t);

				};
				foreach (var t in G[r]) {
					dfs(r, t);
					v += sz[t];
				}
			}
		}
		int read() => int.Parse(Console.ReadLine());
		const long INF = 1L << 60;
		static int[] dx = { -1, 0, 1, 0 };
		static int[] dy = { 0, 1, 0, -1 };
		int ri { get { return sc.Integer(); } }
		long rl { get { return sc.Long(); } }
		double rd { get { return sc.Double(); } }
		string rs { get { return sc.Scan(); } }
		public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

		static T[] Enumerate<T>(int n, Func<int, T> f) {
			var a = new T[n];
			for (int i = 0; i < a.Length; ++i) a[i] = f(i);
			return a;
		}
		static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
	}
}

#region main
static class Ex {
	static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
	static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
		return string.Join(st, ie);
	}
	static public void Main() {
		Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
		var solver = new Program.Solver();
		//var t = new System.Threading.Thread(solver.Solve, 50000000);
		//t.Start();
		//t.Join();
		solver.Solve();
		Console.Out.Flush();
	}
}
#endregion
#region Ex
namespace Program.IO {
	using System.IO;
	using System.Text;
	using System.Globalization;

	public class Printer : StreamWriter {
		public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
		public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	}

	public class StreamScanner {
		public StreamScanner(Stream stream) { str = stream; }

		public readonly Stream str;
		private readonly byte[] buf = new byte[1024];
		private int len, ptr;
		public bool isEof = false;
		public bool IsEndOfStream { get { return isEof; } }

		private byte read() {
			if (isEof) return 0;
			if (ptr >= len) {
				ptr = 0;
				if ((len = str.Read(buf, 0, 1024)) <= 0) {
					isEof = true;
					return 0;
				}
			}
			return buf[ptr++];
		}

		public char Char() {
			byte b = 0;
			do b = read(); while ((b < 33 || 126 < b) && !isEof);
			return (char)b;
		}
		public string Scan() {
			var sb = new StringBuilder();
			for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
			return sb.ToString();
		}
		public string ScanLine() {
			var sb = new StringBuilder();
			for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
			return sb.ToString();
		}
		public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
		public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
		public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
	}
}

#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using CompLib.Util;

public class Program
{
    private int N;
    private List<(int to, int num)>[] E;
    private int[] U, V;
    private int Max;

    private int R;
    private bool[] IsX;
    private bool Found;
    private int XSize;

    private int[] Len;
    private int[] Dist;
    private int TmpX;
    private int TmpY;

    void Scan()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        E = new List<(int to, int num)>[N];
        U = new int[N - 1];
        V = new int[N - 1];
        for (int i = 0; i < N; i++)
        {
            E[i] = new List<(int to, int num)>();
        }

        for (int i = 0; i < N - 1; i++)
        {
            int u = sc.NextInt() - 1;
            int v = sc.NextInt() - 1;
            U[i] = u + 1;
            V[i] = v + 1;
            E[u].Add((v, i));
            E[v].Add((u, i));
        }

        Max = 2 * N * N / 9;
    }

    void SetFlag(int cur, int par)
    {
        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            SetFlag(e.to, cur);
        }

        IsX[cur] = true;
    }

    int Go(int cur, int par)
    {
        var ls = new List<(int to, int size)>();
        int size = 1;
        foreach (var e in E[cur])
        {
            if (e.to == par) continue;
            int tmp = Go(e.to, cur);
            ls.Add((e.to, tmp));
            size += tmp;
        }

        if (par != -1)
        {
            ls.Add((par, N - size));
        }

        if (!Found)
        {
            bool[,] dp = new bool[ls.Count + 1, N];
            dp[0, 0] = true;
            for (int i = 0; i < ls.Count; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    if (dp[i, j])
                    {
                        dp[i + 1, j] = true;
                        dp[i + 1, j + ls[i].size] = true;
                    }
                }
            }

            int x = -1;
            for (int i = 0; i < N; i++)
            {
                if (!dp[ls.Count, i]) continue;
                int y = N - 1 - i;
                if (Max < (i + 1) * (y + 1))
                {
                    x = i;
                    break;
                }
            }

            if (x != -1)
            {
                XSize = x;
                R = cur;
                for (int i = ls.Count - 1; i >= 0; i--)
                {
                    if (x - ls[i].size >= 0 && dp[i, x - ls[i].size])
                    {
                        SetFlag(ls[i].to, cur);
                        x -= ls[i].size;
                    }
                }

                Found = true;
            }
        }

        return size;
    }

    // r、x,yの頂点を決める
    void SearchR()
    {
        IsX = new bool[N];
        Found = false;
        Go(0, -1);
        if (!Found) throw new Exception();
    }

    // 現在地、親、par-curが辺num
    void SetX(int cur, int par, int num)
    {
        Dist[cur] = TmpX++;
        if (par != -1)
        {
            Len[num] = Dist[cur] - Dist[par];
        }

        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            if (!IsX[e.to]) continue;
            SetX(e.to, cur, e.num);
        }
    }

    void SetY(int cur, int par, int num)
    {
        Dist[cur] = TmpY;
        TmpY += (XSize + 1);
        if (par != -1)
        {
            Len[num] = Dist[cur] - Dist[par];
        }

        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            if (IsX[e.to]) continue;
            SetY(e.to, cur, e.num);
        }
    }

    void SetLen()
    {
        // 辺の長さ
        Len = new int[N - 1];
        // R->頂点までの距離
        Dist = new int[N];
        // X側の頂点はRに近い順に距離1~Xを割り当てる
        // それぞれの頂点までの距離になるように頂点の長さを割り当てる
        TmpX = 0;
        SetX(R, -1, -1);

        // Y (X+1)刻みで割り当てる
        TmpY = 0;
        SetY(R, -1, -1);
    }

    void Write()
    {
        var sb = new StringBuilder();
        for (int i = 0; i < N - 1; i++)
        {
            sb.AppendLine($"{U[i]} {V[i]} {Len[i]}");
        }

        Console.Write(sb);
    }

    public void Solve()
    {
        // ある頂点rを境目に2つに分ける
        // 片方x個 もう片方 y個 x + y + 1 = N
        // 片方でrからの距離 0~xをつくる
        // 残り x+1刻みで y個
        // 0 <= p < (x+1)(y+1)できる

        Scan();
        SearchR();
        SetLen();
        Write();
    }

    public static void Main(string[] args)
    {
        new Thread(new ThreadStart(new Program().Solve), 1 << 27).Start();
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s;
                do
                {
                    s = Console.ReadLine();
                } while (s.Length == 0);

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using CompLib.Util;

public class Program
{
    private int N;
    private List<(int to, int num)>[] E;
    private int[] U, V;
    private int Max;

    private int R;
    private bool[] IsX;
    private bool Found;
    private int XSize;

    private int[] Len;
    private int[] Dist;
    private int TmpX;
    private int TmpY;

    void Scan()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        E = new List<(int to, int num)>[N];
        U = new int[N - 1];
        V = new int[N - 1];
        for (int i = 0; i < N; i++)
        {
            E[i] = new List<(int to, int num)>();
        }

        for (int i = 0; i < N - 1; i++)
        {
            int u = sc.NextInt() - 1;
            int v = sc.NextInt() - 1;
            U[i] = u + 1;
            V[i] = v + 1;
            E[u].Add((v, i));
            E[v].Add((u, i));
        }

        Max = 2 * N * N / 9;
    }

    void SetFlag(int cur, int par)
    {
        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            SetFlag(e.to, cur);
        }

        IsX[cur] = true;
    }

    int Go(int cur, int par)
    {
        var ls = new List<(int to, int size)>();
        int size = 1;
        foreach (var e in E[cur])
        {
            if (e.to == par) continue;
            int tmp = Go(e.to, cur);
            ls.Add((e.to, tmp));
            size += tmp;
        }

        if (par != -1)
        {
            ls.Add((par, N - size));
        }

        if (!Found)
        {
            bool[,] dp = new bool[ls.Count + 1, N];
            dp[0, 0] = true;
            for (int i = 0; i < ls.Count; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    if (dp[i, j])
                    {
                        dp[i + 1, j] = true;
                        dp[i + 1, j + ls[i].size] = true;
                    }
                }
            }

            int x = -1;
            for (int i = 0; i < N; i++)
            {
                if (!dp[ls.Count, i]) continue;
                int y = N - 1 - i;
                if (Max < (i + 1) * (y + 1))
                {
                    x = i;
                    break;
                }
            }

            if (x != -1)
            {
                XSize = x;
                R = cur;
                for (int i = ls.Count - 1; i >= 0; i--)
                {
                    if (x - ls[i].size >= 0 && dp[i, x - ls[i].size])
                    {
                        SetFlag(ls[i].to, cur);
                        x -= ls[i].size;
                    }
                }

                Found = true;
            }
        }

        return size;
    }

    // r、x,yの頂点を決める
    void SearchR()
    {
        IsX = new bool[N];
        Found = false;
        Go(0, -1);
        if (!Found) throw new Exception();
    }

    // 現在地、親、par-curが辺num
    void SetX(int cur, int par, int num)
    {
        Dist[cur] = TmpX++;
        if (par != -1)
        {
            Len[num] = Dist[cur] - Dist[par];
        }

        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            if (!IsX[e.to]) continue;
            SetX(e.to, cur, e.num);
        }
    }

    void SetY(int cur, int par, int num)
    {
        Dist[cur] = TmpY;
        TmpY += (XSize + 1);
        if (par != -1)
        {
            Len[num] = Dist[cur] - Dist[par];
        }

        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            if (IsX[e.to]) continue;
            SetY(e.to, cur, e.num);
        }
    }

    void SetLen()
    {
        // 辺の長さ
        Len = new int[N - 1];
        // R->頂点までの距離
        Dist = new int[N];
        // X側の頂点はRに近い順に距離1~Xを割り当てる
        // それぞれの頂点までの距離になるように辺の長さを割り当てる
        TmpX = 0;
        SetX(R, -1, -1);

        // Y (X+1)刻みで割り当てる
        TmpY = 0;
        SetY(R, -1, -1);
    }

    void Write()
    {
        var sb = new StringBuilder();
        for (int i = 0; i < N - 1; i++)
        {
            sb.AppendLine($"{U[i]} {V[i]} {Len[i]}");
        }

        Console.Write(sb);
    }

    public void Solve()
    {
        // ある頂点rを境目に2つに分ける
        // 片方x個 もう片方 y個 x + y + 1 = N
        // 片方でrからの距離 0~xをつくる
        // 残り x+1刻みで y個
        // 0 <= p < (x+1)(y+1)できる

        Scan();
        SearchR();
        SetLen();
        Write();
    }

    public static void Main(string[] args)
    {
        new Thread(new ThreadStart(new Program().Solve), 1 << 27).Start();
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s;
                do
                {
                    s = Console.ReadLine();
                } while (s.Length == 0);

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;

namespace F.AlmostAll
{
    internal static class Program
    {
        public static void Main()
        {
            var adjacencyList = ReadInput();

            var solver = new Solver(adjacencyList);
            solver.Solve();

            foreach (var edge in solver.Edges)
                Console.WriteLine($"{edge.From} {edge.To} {edge.Num}");
        }

        private static List<Node>[] ReadInput()
        {
            var n = int.Parse(Console.ReadLine());
            var adjacencyList = new List<Node>[n];
            for (var i = 0; i < n; i++)
                adjacencyList[i] = new List<Node>();

            for (var i = 1; i < n; i++)
            {
                var uv = Console.ReadLine().Split();
                var u = int.Parse(uv[0]) - 1;
                var v = int.Parse(uv[1]) - 1;

                adjacencyList[u].Add(new Node(v));
                adjacencyList[v].Add(new Node(u));
            }

            return adjacencyList;
        }
    }

    internal sealed class Solver
    {
        private readonly List<Node>[] _adjacencyList;
        private readonly List<Edge> _resultEdges;
        private readonly int _centroidLimit;

        private Node? _centroid;

        public Solver(List<Node>[] adjacencyList)
        {
            _adjacencyList = adjacencyList;
            _resultEdges = new List<Edge>(N - 1);

            _centroidLimit = N / 2;
        }

        public IReadOnlyCollection<Edge> Edges => _resultEdges;

        private int N => _adjacencyList.Length;

        private Node Centroid => _centroid.Value;

        public void Solve()
        {
            FindCentroidDfs(new Node(0), new Node(-1));
            var (groupA, groupB) = SplitRootChildrenToGroups();

            var groupANums = Enumerable.Range(1, groupA.TotalSize);
            FillGroupEdges(groupA.DirectChildren, groupANums);

            var groupBNums = Enumerable.Range(1, groupB.TotalSize)
                .Select(it => it * (groupA.TotalSize + 1));
            FillGroupEdges(groupB.DirectChildren, groupBNums);
        }

        private int FindCentroidDfs(Node node, Node prev)
        {
            var isCentroid = true;

            var subTreeSize = 1;
            foreach (var next in GetAdjacent(node).Where(it => it != prev))
            {
                var nextSubTree = FindCentroidDfs(next, node);
                if (_centroid.HasValue)
                    return 0;

                isCentroid = isCentroid && nextSubTree <= _centroidLimit;
                subTreeSize += nextSubTree;
            }

            if (isCentroid && N - subTreeSize <= _centroidLimit)
                _centroid = node;

            return subTreeSize;
        }

        private (RootChildGroup, RootChildGroup) SplitRootChildrenToGroups()
        {
            RootChildGroup
                groupA = new RootChildGroup() {DirectChildren = new List<Node>()},
                groupB = new RootChildGroup() {DirectChildren = new List<Node>()};

            var groupLimit = (N + 1) / 3; // ceiling ((N - 1) / 3)

            var rootChildren = GetAdjacent(Centroid)
                .Select(it => new {Node = it, Size = GetSubtreeSize(it, Centroid)})
                .OrderBy(it => it.Size);

            foreach (var child in rootChildren)
            {
                if (groupA.TotalSize < groupLimit)
                    groupA.Add(child.Node, child.Size);
                else
                    groupB.Add(child.Node, child.Size);
            }

            return (groupA, groupB);
        }

        private int GetSubtreeSize(Node node, Node parent)
        {
            return 1 + GetAdjacent(node)
                       .Where(it => it != parent)
                       .Select(it => GetSubtreeSize(it, node))
                       .Sum();
        }

        private void FillGroupEdges(List<Node> group, IEnumerable<int> nums)
        {
            using (var num = nums.GetEnumerator())
                foreach (var node in group)
                    FillGroupEdges(node, Centroid, 0, num);
        }

        private void FillGroupEdges(Node node, Node parent, int parentSum, IEnumerator<int> numEnumerator)
        {
            numEnumerator.MoveNext();
            var curSum = numEnumerator.Current;
            _resultEdges.Add(new Edge(node, parent, curSum - parentSum));

            foreach (var child in GetAdjacent(node).Where(it => it != parent))
                FillGroupEdges(child, node, curSum, numEnumerator);
        }

        private List<Node> GetAdjacent(Node node) => _adjacencyList[node.Id];

        private struct RootChildGroup
        {
            public List<Node> DirectChildren { get; set; }
            public int TotalSize { get; private set; }

            public void Add(Node child, int size)
            {
                DirectChildren.Add(child);
                TotalSize += size;
            }
        }
    }

    internal struct Node
    {
        public Node(int id) => Id = id;
        public int Id { get; }

        public override bool Equals(object obj) => obj is Node node && node.Id == Id;
        public override int GetHashCode() => Id;

        public static bool operator==(Node a, Node b) => a.Id == b.Id;
        public static bool operator!=(Node a, Node b) => a.Id != b.Id;

        public override string ToString() => (Id + 1).ToString();
    }

    internal struct Edge
    {
        public Edge(Node from, Node to, int num)
        {
            From = from;
            To = to;
            Num = num;
        }

        public Node From { get; }
        public Node To { get; }
        public int Num { get; }
    }
}

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using CompLib.Util;

public class Program
{
    private int N;
    private List<(int to, int num)>[] E;
    private int[] U, V;
    private int Max;

    private int R;
    private bool[] IsX;
    private bool Found;
    private int XSize;

    private int[] Len;
    private int[] Dist;
    private int TmpX;
    private int TmpY;

    void Scan()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        E = new List<(int to, int num)>[N];
        U = new int[N - 1];
        V = new int[N - 1];
        for (int i = 0; i < N; i++)
        {
            E[i] = new List<(int to, int num)>();
        }

        for (int i = 0; i < N - 1; i++)
        {
            int u = sc.NextInt() - 1;
            int v = sc.NextInt() - 1;
            U[i] = u + 1;
            V[i] = v + 1;
            E[u].Add((v, i));
            E[v].Add((u, i));
        }

        Max = 2 * N * N / 9;
    }

    void SetFlag(int cur, int par)
    {
        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            SetFlag(e.to, cur);
        }

        IsX[cur] = true;
    }

    int Go(int cur, int par)
    {
        var ls = new List<(int to, int size)>();
        int size = 1;
        foreach (var e in E[cur])
        {
            if (e.to == par) continue;
            int tmp = Go(e.to, cur);
            ls.Add((e.to, tmp));
            size += tmp;
        }

        // if (par != -1)
        // {
        //     ls.Add((par, N - size));
        // }

        // 親側は処理が難しいので飛ばす
        // x,y逆になってもいいので問題ない
        bool[,] dp = new bool[ls.Count + 1, N];
        dp[0, 0] = true;
        for (int i = 0; i < ls.Count; i++)
        {
            for (int j = 0; j < N; j++)
            {
                if (dp[i, j]) dp[i + 1, j + ls[i].size] = true;
            }
        }

        if (!Found)
        {
            int x = -1;
            for (int i = 0; i < N; i++)
            {
                if (!dp[ls.Count, i]) continue;
                int y = N - 1 - i;
                if (Max < (i + 1) * (y + 1))
                {
                    x = i;
                    break;
                }
            }

            if (x != -1)
            {
                XSize = x;
                R = cur;
                for (int i = ls.Count - 1; i >= 0; i--)
                {
                    if (x - ls[i].size >= 0 && dp[i, x - ls[i].size])
                    {
                        SetFlag(ls[i].to, cur);
                        x -= ls[i].size;
                    }
                }

                Found = true;
            }
        }

        return size;
    }

    // r、x,yの頂点を決める
    void SearchR()
    {
        IsX = new bool[N];
        Found = false;
        Go(0, -1);
    }

    // 現在地、親、par-curが辺num
    void SetX(int cur, int par, int num)
    {
        Dist[cur] = TmpX++;
        if (par != -1)
        {
            Len[num] = Dist[cur] - Dist[par];
        }

        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            if (!IsX[e.to]) continue;
            SetX(e.to, cur, e.num);
        }
    }

    void SetY(int cur, int par, int num)
    {
        Dist[cur] = TmpY;
        TmpY += (XSize + 1);
        if (par != -1)
        {
            Len[num] = Dist[cur] - Dist[par];
        }

        foreach ((int to, int num) e in E[cur])
        {
            if (e.to == par) continue;
            if (IsX[e.to]) continue;
            SetY(e.to, cur, e.num);
        }
    }

    void SetLen()
    {
        // 辺の長さ
        Len = new int[N - 1];
        // R->頂点までの距離
        Dist = new int[N];
        // X側の頂点はRに近い順に距離1~Xを割り当てる
        // それぞれの頂点までの距離になるように頂点の長さを割り当てる
        TmpX = 0;
        SetX(R, -1, -1);

        // Y (X+1)刻みで割り当てる
        TmpY = 0;
        SetY(R, -1, -1);
    }

    void Write()
    {
        var sb = new StringBuilder();
        for (int i = 0; i < N - 1; i++)
        {
            sb.AppendLine($"{U[i]} {V[i]} {Len[i]}");
        }

        Console.Write(sb);
    }

    public void Solve()
    {
        // ある頂点rを境目に2つに分ける
        // 片方x個 もう片方 y個 x + y + 1 = N
        // 片方でrからの距離 0~xをつくる
        // 残り x+1刻みで y個
        // 0 <= p < (x+1)(y+1)できる

        Scan();
        SearchR();
        SetLen();
        Write();
    }

    public static void Main(string[] args)
    {
        new Thread(new ThreadStart(new Program().Solve), 1 << 27).Start();
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s;
                do
                {
                    s = Console.ReadLine();
                } while (s.Length == 0);

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;

namespace F.AlmostAll
{
    internal static class Program
    {
        public static void Main()
        {
            var adjacencyList = ReadInput();

            var solver = new Solver(adjacencyList);
            solver.Solve();

            foreach (var edge in solver.Edges)
                Console.WriteLine($"{edge.From} {edge.To} {edge.Num}");
        }

        private static List<Node>[] ReadInput()
        {
            var n = int.Parse(Console.ReadLine());
            var adjacencyList = new List<Node>[n];
            for (var i = 0; i < n; i++)
                adjacencyList[i] = new List<Node>();

            for (var i = 1; i < n; i++)
            {
                var uv = Console.ReadLine().Split();
                var u = int.Parse(uv[0]) - 1;
                var v = int.Parse(uv[1]) - 1;

                adjacencyList[u].Add(new Node(v));
                adjacencyList[v].Add(new Node(u));
            }

            return adjacencyList;
        }
    }

    internal sealed class Solver
    {
        private readonly List<Node>[] _adjacencyList;
        private readonly List<Edge> _resultEdges;
        private readonly int _centroidLimit;

        private Node? _centroid;

        public Solver(List<Node>[] adjacencyList)
        {
            _adjacencyList = adjacencyList;
            _resultEdges = new List<Edge>(N - 1);

            _centroidLimit = N / 2;
        }

        public IReadOnlyCollection<Edge> Edges => _resultEdges;

        private int N => _adjacencyList.Length;

        private Node Centroid => _centroid.Value;

        public void Solve()
        {
            FindCentroidDfs(new Node(0), new Node(-1));
            var (groupA, groupB) = SplitRootChildrenToGroups();

            var groupANums = Enumerable.Range(1, groupA.TotalSize);
            FillGroupEdges(groupA.DirectChildren, groupANums);

            var groupBNums = Enumerable.Range(1, groupB.TotalSize)
                .Select(it => it * (groupA.TotalSize + 1));
            FillGroupEdges(groupB.DirectChildren, groupBNums);
        }

        private int FindCentroidDfs(Node node, Node prev)
        {
            var isCentroid = true;

            var subTreeSize = 1;
            foreach (var next in GetAdjacent(node).Where(it => it != prev))
            {
                var nextSubTree = FindCentroidDfs(next, node);
                if (_centroid.HasValue)
                    return 0;

                isCentroid = isCentroid && nextSubTree <= _centroidLimit;
                subTreeSize += nextSubTree;
            }

            if (isCentroid && N - subTreeSize <= _centroidLimit)
                _centroid = node;

            return subTreeSize;
        }

        private (RootChildGroup, RootChildGroup) SplitRootChildrenToGroups()
        {
            RootChildGroup
                groupA = new RootChildGroup() {DirectChildren = new List<Node>()},
                groupB = new RootChildGroup() {DirectChildren = new List<Node>()};

            var groupLimit = (N + 1) / 3; // ceiling ((N - 1) / 3)

            var rootChildren = GetAdjacent(Centroid)
                .Select(it => new {Node = it, Size = GetSubtreeSize(it, Centroid)})
                .OrderBy(it => it.Size);

            foreach (var child in rootChildren)
            {
                if (groupA.TotalSize < groupLimit)
                    groupA.Add(child.Node, child.Size);
                else
                    groupB.Add(child.Node, child.Size);
            }

            return (groupA, groupB);
        }

        private int GetSubtreeSize(Node node, Node parent)
        {
            return 1 + GetAdjacent(node)
                       .Where(it => it != parent)
                       .Select(it => GetSubtreeSize(it, node))
                       .Sum();
        }

        private void FillGroupEdges(List<Node> group, IEnumerable<int> nums)
        {
            using (var num = nums.GetEnumerator())
                foreach (var node in group)
                    FillGroupEdges(node, Centroid, num);
        }

        private void FillGroupEdges(Node node, Node parent, IEnumerator<int> numEnumerator)
        {
            numEnumerator.MoveNext();
            _resultEdges.Add(new Edge(node, parent, numEnumerator.Current));

            foreach (var child in GetAdjacent(node).Where(it => it != parent))
                FillGroupEdges(child, node, numEnumerator);
        }

        private List<Node> GetAdjacent(Node node) => _adjacencyList[node.Id];

        private struct RootChildGroup
        {
            public List<Node> DirectChildren { get; set; }
            public int TotalSize { get; private set; }

            public void Add(Node child, int size)
            {
                DirectChildren.Add(child);
                TotalSize += size;
            }
        }
    }

    internal struct Node
    {
        public Node(int id) => Id = id;
        public int Id { get; }

        public override bool Equals(object obj) => obj is Node node && node.Id == Id;
        public override int GetHashCode() => Id;

        public static bool operator==(Node a, Node b) => a.Id == b.Id;
        public static bool operator!=(Node a, Node b) => a.Id != b.Id;

        public override string ToString() => (Id + 1).ToString();
    }

    internal struct Edge
    {
        public Edge(Node from, Node to, int num)
        {
            From = from;
            To = to;
            Num = num;
        }

        public Node From { get; }
        public Node To { get; }
        public int Num { get; }
    }
}


using System;
using System.Collections.Generic;
using System.Text;

public class taskA
{
    static void Main(string[] args)
    {
        string inp = Console.ReadLine();
        string[] spl = inp.Split(' ');
        int n, m;
        n = int.Parse(spl[0]);
        m = int.Parse(spl[1]);

        long res = pow(3,n,m);

        res = (res - (long)1+(long)m) % m;

        Console.WriteLine(res);

    }

    private static long pow(int p, int n, int m)
    {
        long res = 0;
        if (n == 0) return 1;

        if ((n % 2) == 0)
        {
            res = pow(p, n / 2, m);
            res = res * res;
            res %= m;

        }
        else
        {
            res = pow(p, n - 1, m);
            res = res * p;
            return res;
        }
        res %= m;
        return res;
    }

}

using System;
using System.Linq;
using System.Text;

namespace VKD
{
    class Program
    {
        static int m = 10;

        static long Pow(long a, int p)
        {
            if (p == 0)
            {
                return 1 % m;
            }

            if (p % 2 == 1)
            {
                return ((a % m) * Pow(a, p - 1) % m) % m;
            }
            else
            {
                var t = Pow(a, p / 2) % m;
                return (t * t) % m;
            }

        }
        static void Main(string[] args)
        {
            var inp = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
            int n = inp[0];
            m = inp[1];

            long ans = 0;
            ans = (Pow(3, n) - 1 % m + m) % m;
            Console.WriteLine(ans);
            //Console.ReadKey();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace C24_09_12
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] s = Regex.Split(Console.ReadLine(), " ");
            Int64 n = Int64.Parse(s[0]);
            Int64 m = Int64.Parse(s[1]);
            Int64 k = 1;
            Int64 t = 3;
            while (n > 0)
            {
                if( n%2==1) k *= t;
                n /= 2;
                t *= t;
                k %= m;
                t %= m;
            }
            //if (m == 1)
            //    k = 0;
            //else
                if (k == 0) k = m - 1;
                else k--;
            Console.WriteLine("{0}", k);
        }
    }
}

using System;
using System.Numerics;

public class CF_227C
{
    public CF_227C()
    {
    }

    public long solve(int n, int m)
    {
		long[] powersof3 = new long[32];
		powersof3[0] = 3 % m;
		for (int i = 1; i < 32; i++)
        {
			powersof3[i] = (powersof3[i - 1] * powersof3[i - 1]) % m;
		}

        long answer = 1;
        for (int i = 0; i < 32; i++)
        {
            if ((n & (1 << i)) != 0)
            {
                answer *= powersof3[i];
                answer %= m;
            }
        }
        answer = (answer == 0 ? m - 1 : answer - 1);
        return answer;
	}

    public static void Main(string[] args)
    {
        string[] lines = Console.ReadLine().Split();
        int n = Convert.ToInt32(lines[0]);
        int m = Convert.ToInt32(lines[1]);
        Console.WriteLine(new CF_227C().solve(n, m));
    }
}

using System;
using System.IO;
using System.Text;

namespace Flying_Saucer_Segments
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static int mod;

        private static long Pow(long a, int k)
        {
            long r = 1;
            while (k > 0)
            {
                if ((k & 1) == 1)
                {
                    r = (r*a)%mod;
                }
                a = (a*a)%mod;
                k >>= 1;
            }
            return r;
        }

        private static void Main(string[] args)
        {
            int n = Next();
            mod = Next();

            long res = Pow(3, n) - 1;
            if (res < 0)
                res += mod;

            writer.WriteLine(res);
            writer.Flush();
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        public static Int64 powermod(Int64 b, Int64 n, Int64 m)
        {
            Int64 result = 1;
            while (n > 0)
            {
                if ((n & 1) == 1)
                {
                    result = (result * b) % m;
                }
                b = (b * b) % m;
                n = n / 2;
            }
            return result;

            //return (result - 1) % m;
        }

        static void Main(string[] args)
        {
            Int64 n, m;
            string[] inp = Console.ReadLine().ToString().Split(' ');
            n = Convert.ToInt64(inp[0]);
            m = Convert.ToInt64(inp[1]);

            Int64 r = powermod(3, n, m);
            r = r == 0 ? m - 1 : r-1;
            Console.WriteLine(r);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        public static Int64 powermod(Int64 b, Int64 n, Int64 m)
        {
            Int64 result = 1;
            while (n > 0)
            {
                if ((n & 1) == 1)
                {
                    result = (result * b) % m;
                }
                b = (b * b) % m;
                n = n / 2;
            }
            return (m+result-1)%m;
        }

        static void Main(string[] args)
        {
            Int64 n, m;
            string[] inp = Console.ReadLine().ToString().Split(' ');
            n = Convert.ToInt64(inp[0]);
            m = Convert.ToInt64(inp[1]);
            Console.WriteLine(powermod(3, n, m));
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeForces
{
    class Program_R158_Div2_255A
    {
        static void Main(string[] args)
        {
            string[] s = (Console.ReadLine().Split());
            int n = int.Parse(s[0]);
            int m = int.Parse(s[1]);

            long num = GetBigPowerMod(3, n, m);
            num--;
            if (num < 0) num = m - 1;
            Console.WriteLine(num);
        }

        static long GetBigPowerMod(long b, int n, int m)
        {
            //num will be b^n mod m; for n, m up to 1e10
            //long num = 1
            //for (int i = 0; i < n; i++)
            //    num = (num * b) % m;

            long num = 1;
            while (n > 0)
            {
                if (n % 2 == 1)
                    num = (num * b) % m;
                b = (b * b) % m;
                n /= 2;
                //Console.WriteLine("{0} {1} {2}", num, b, n);
            }
            return num;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Globalization;
using System.Threading;

namespace CodeForces
{

	class A
	{

		private void Solve()
		{
			int n = NextInt(), m = NextInt();
			Out.WriteLine( ( pow( 3, n, m ) - 1 + m ) % m );
		}

		int pow( int a, int b, int m )
		{
			if ( b == 0 ) return 1 % m;
			int r = pow( a, b / 2, m );
			r = (int)( ( (long)r * r ) % m );
			if ( b % 2 == 1 )
			{
				r = (int)( ( (long)r * a ) % m );
			}
			return r;
		}

		#region Local wireup

		public int NextInt()
		{
			return _in.NextInt();
		}

		public long NextLong()
		{
			return _in.NextLong();
		}

		public string NextLine()
		{
			return _in.NextLine();
		}

		public double NextDouble()
		{
			return _in.NextDouble();
		}

		readonly Scanner _in = new Scanner();
		static readonly TextWriter Out = Console.Out;

		void Start()
		{
#if !ONLINE_JUDGE
			var timer = new Stopwatch();
			timer.Start();
#endif
			var t = new Thread( Solve, 20000000 );
			t.Start();
			t.Join();
#if !ONLINE_JUDGE
			timer.Stop();
			Console.WriteLine( string.Format( CultureInfo.InvariantCulture, "Done in {0} seconds.\nPress <Enter> to exit.", timer.ElapsedMilliseconds / 1000.0 ) );
			Console.ReadLine();
#endif
		}

		static void Main()
		{
			new A().Start();
		}

		class Scanner : IDisposable
		{
			#region Fields

			readonly TextReader _reader;
			readonly int _bufferSize;
			readonly bool _closeReader;
			readonly char[] _buffer;
			int _length, _pos;

			#endregion

			#region .ctors

			public Scanner( TextReader reader, int bufferSize, bool closeReader )
			{
				_reader = reader;
				_bufferSize = bufferSize;
				_closeReader = closeReader;
				_buffer = new char[_bufferSize];
				FillBuffer( false );
			}

			public Scanner( TextReader reader, bool closeReader ) : this( reader, 1 << 16, closeReader ) { }

			public Scanner( string fileName ) : this( new StreamReader( fileName, Encoding.Default ), true ) { }

#if ONLINE_JUDGE
			public Scanner() : this( Console.In, false ) { }
#else
			public Scanner() : this( "input.txt" ) { }
#endif

			#endregion

			#region IDisposable Members

			public void Dispose()
			{
				if ( _closeReader )
				{
					_reader.Close();
				}
			}

			#endregion

			#region Properties

			public bool Eof
			{
				get
				{
					if ( _pos < _length ) return false;
					FillBuffer( false );
					return _pos >= _length;
				}
			}

			#endregion

			#region Methods

			private char NextChar()
			{
				if ( _pos < _length ) return _buffer[_pos++];
				FillBuffer( true );
				return _buffer[_pos++];
			}

			private char PeekNextChar()
			{
				if ( _pos < _length ) return _buffer[_pos];
				FillBuffer( true );
				return _buffer[_pos];
			}

			private void FillBuffer( bool throwOnEof )
			{
				_length = _reader.Read( _buffer, 0, _bufferSize );
				if ( throwOnEof && Eof )
				{
					throw new IOException( "Can't read beyond the end of file" );
				}
				_pos = 0;
			}

			public int NextInt()
			{
				var neg = false;
				int res = 0;
				SkipWhitespaces();
				if ( !Eof && PeekNextChar() == '-' )
				{
					neg = true;
					_pos++;
				}
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					var c = NextChar();
					if ( c < '0' || c > '9' ) throw new ArgumentException( "Illegal character" );
					res = 10 * res + c - '0';
				}
				return neg ? -res : res;
			}

			public long NextLong()
			{
				var neg = false;
				long res = 0;
				SkipWhitespaces();
				if ( !Eof && PeekNextChar() == '-' )
				{
					neg = true;
					_pos++;
				}
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					var c = NextChar();
					if ( c < '0' || c > '9' ) throw new ArgumentException( "Illegal character" );
					res = 10 * res + c - '0';
				}
				return neg ? -res : res;
			}

			public string NextLine()
			{
				SkipUntilNextLine();
				if ( Eof ) return "";
				var builder = new StringBuilder();
				while ( !Eof && !IsEndOfLine( PeekNextChar() ) )
				{
					builder.Append( NextChar() );
				}
				return builder.ToString();
			}

			public double NextDouble()
			{
				SkipWhitespaces();
				var builder = new StringBuilder();
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					builder.Append( NextChar() );
				}
				return double.Parse( builder.ToString(), CultureInfo.InvariantCulture );
			}

			private void SkipWhitespaces()
			{
				while ( !Eof && IsWhitespace( PeekNextChar() ) )
				{
					++_pos;
				}
			}

			private void SkipUntilNextLine()
			{
				while ( !Eof && IsEndOfLine( PeekNextChar() ) )
				{
					++_pos;
				}
			}

			private static bool IsWhitespace( char c )
			{
				return c == ' ' || c == '\t' || c == '\n' || c == '\r';
			}

			private static bool IsEndOfLine( char c )
			{
				return c == '\n' || c == '\r';
			}

			#endregion
		}

		#endregion
	}
}

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;

namespace Codeforces
{
    class C
    {
        private static ThreadStart s_threadStart = new C().Go;
        private static bool s_time = false;

        private long Power(long a, long b, long m)
        {
            if (b == 0) return 1;
            a %= m;
            if (b % 2 == 0)
            {
                return Power((a * a) % m, b / 2, m) % m;
            }
            else if (b % 2 == 1)
            {
                return (a * Power((a * a) % m, b / 2, m)) % m;
            }
            return 0;
        }

        private void Go()
        {
            long n = GetInt();
            long m = GetInt();

            long res = Power(3, n, m)-1;
            if (res == -1) res = m - 1;
            Wl(res);
        }

        #region Template

        public static void Main(string[] args)
        {
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            Thread main = new Thread(new ThreadStart(s_threadStart), 512 * 1024 * 1024);
            timer.Start();
            main.Start();
            main.Join();
            timer.Stop();
            if (s_time)
                Wl(timer.ElapsedMilliseconds);
        }

        private static IEnumerator<string> ioEnum;
        private static string GetString()
        {
            while (ioEnum == null || !ioEnum.MoveNext())
            {
                ioEnum = Console.ReadLine().Split().AsEnumerable().GetEnumerator();
            }

            return ioEnum.Current;
        }

        private static int GetInt()
        {
            return int.Parse(GetString());
        }

        private static long GetLong()
        {
            return long.Parse(GetString());
        }

        private static double GetDouble()
        {
            return double.Parse(GetString());
        }

        private static List<int> GetIntArr(int n)
        {
            List<int> ret = new List<int>(n);
            for (int i = 0; i < n; i++)
            {
                ret.Add(GetInt());
            }
            return ret;
        }

        private static void Wl<T>(T o)
        {
            if (o is double)
            {
                Wld((o as double?).Value, "");
            }
            else if (o is float)
            {
                Wld((o as float?).Value, "");
            }
            else
                Console.WriteLine(o.ToString());
        }

        private static void Wl<T>(IEnumerable<T> enumerable)
        {
            Wl(string.Join(" ", enumerable.Select(e => e.ToString()).ToArray()));
        }

        private static void Wld(double d, string format)
        {
            Wl(d.ToString(format, CultureInfo.InvariantCulture));
        }

        public struct Tuple<T, K> : IComparable<Tuple<T, K>>, IComparable
            where T : IComparable<T>
            where K : IComparable<K>
        {
            public T Item1;
            public K Item2;

            public Tuple(T t, K k)
            {
                Item1 = t;
                Item2 = k;
            }

            public override bool Equals(object obj)
            {
                var o = (Tuple<T, K>)obj;
                return o.Item1.Equals(Item1) && o.Item2.Equals(Item2);
            }

            public override int GetHashCode()
            {
                return Item1.GetHashCode() ^ Item2.GetHashCode();
            }

            public override string ToString()
            {
                return "(" + Item1 + " " + Item2 + ")";
            }

            #region IComparable<Tuple<T,K>> Members

            public int CompareTo(Tuple<T, K> other)
            {
                int ret = Item1.CompareTo(other.Item1);
                if (ret != 0) return ret;
                return Item2.CompareTo(other.Item2);
            }

            #endregion

            #region IComparable Members

            public int CompareTo(object obj)
            {
                if (obj is Tuple<T, K>)
                    return CompareTo((Tuple<T, K>)obj);
                return CompareTo(null);
            }

            #endregion
        }

        #endregion
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Temp
{
    internal struct PointInt
    {
        public long X;

        public long Y;

        public PointInt(long x, long y)
            : this()
        {
            this.X = x;
            this.Y = y;
        }

        public PointInt(PointInt head)
            : this(head.X, head.Y)
        {
        }

        public static PointInt operator +(PointInt a, PointInt b)
        {
            return new PointInt(a.X + b.X, a.Y + b.Y);
        }

        public static PointInt operator -(PointInt a, PointInt b)
        {
            return new PointInt(a.X - b.X, a.Y - b.Y);
        }

        public static PointInt operator *(PointInt a, long k)
        {
            return new PointInt(k * a.X, k * a.Y);
        }

        public static PointInt operator *(long k, PointInt a)
        {
            return new PointInt(k * a.X, k * a.Y);
        }

        public bool IsInsideRectangle(long l, long b, long r, long t)
        {
            return (l <= X) && (X <= r) && (b <= Y) && (Y <= t);
        }
    }

    internal struct LineInt
    {
        public LineInt(PointInt a, PointInt b)
            : this()
        {
            A = a.Y - b.Y;
            B = b.X - a.X;
            C = a.X * b.Y - a.Y * b.X;
        }

        public long A, B, C;

        public bool ContainsPoint(PointInt p)
        {
            return A * p.X + B * p.Y + C == 0;
        }
    }

    internal static class Geometry
    {
        public static long VectInt(PointInt a, PointInt b)
        {
            return a.X * b.Y - a.Y * b.X;
        }

        public static long VectInt(PointInt a, PointInt b, PointInt c)
        {
            return (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X);
        }
    }

    internal class MatrixInt
    {
        private long[,] m_Matrix;

        public int Size
        {
            get
            {
                return m_Matrix.GetLength(0);
            }
        }

        public long Mod { get; private set; }

        public MatrixInt(int size, long mod = 0)
        {
            m_Matrix = new long[size,size];
            Mod = mod;
        }

        public MatrixInt(long[,] matrix, long mod = 0)
        {
            this.m_Matrix = matrix;
            Mod = mod;
        }

        public static MatrixInt GetIdentityMatrix(int size, long mod = 0)
        {
            long[,] matrix = new long[size,size];

            for (int i = 0; i < size; i++)
            {
                matrix[i, i] = 1;
            }

            return new MatrixInt(matrix, mod);
        }

        public long this[int i, int j]
        {
            get
            {
                return m_Matrix[i, j];
            }

            set
            {
                m_Matrix[i, j] = value;
            }
        }

        public static MatrixInt operator +(MatrixInt a, MatrixInt b)
        {
            int n = a.Size;
            long mod = Math.Max(a.Mod, b.Mod);
            long[,] c = new long[n,n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    c[i, j] = a[i, j] + b[i, j];
                }
            }

            if (mod > 0)
            {
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        c[i, j] %= mod;
                    }
                }
            }

            return new MatrixInt(c, mod);
        }

        public static MatrixInt operator *(MatrixInt a, MatrixInt b)
        {
            int n = a.Size;
            long mod = Math.Max(a.Mod, b.Mod);

            long[,] c = new long[n,n];

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    for (int k = 0; k < n; k++)
                    {
                        c[i, j] += a[i, k] * b[k, j];
                        if (mod > 0)
                        {
                            c[i, j] %= mod;
                        }
                    }
                }
            }

            return new MatrixInt(c, mod);
        }
    }

    internal static class Algebra
    {
        public static long Phi(long n)
        {
            long result = n;
            for (long i = 2; i * i <= n; i++)
            {
                if (n % i == 0)
                {
                    while (n % i == 0)
                    {
                        n /= i;
                    }

                    result -= result / i;
                }
            }

            if (n > 1)
            {
                result -= result / n;
            }

            return result;
        }

        public static long BinPower(long a, long n, long mod)
        {
            long result = 1;

            while (n > 0)
            {
                if ((n & 1) != 0)
                {
                    result = (result * a) % mod;
                }

                a = (a * a) % mod;
                n >>= 1;
            }

            return result;
        }

        public static class Permutations
        {
            public static int[] GetRandomPermutation(int n)
            {
                int[] p = new int[n];
                for (int i = 0; i < n; i++)
                {
                    p[i] = i;
                }

                Random random = new Random();
                for (int i = n - 1; i > 0; i--)
                {
                    int j = random.Next(i + 1);
                    int tmp = p[i];
                    p[i] = p[j];
                    p[j] = tmp;
                }

                return p;
            }
        }

        public static T[] Shuffle<T>(this T[] array)
        {
            int length = array.Length;
            int[] p = Permutations.GetRandomPermutation(length);
            T[] result = new T[length];
            for (int i = 0; i < length; i++)
            {
                result[i] = array[p[i]];
            }

            return result;
        }

        public static MatrixInt MatrixBinPower(MatrixInt a, long n)
        {
            MatrixInt result = MatrixInt.GetIdentityMatrix(a.Size, a.Mod);

            while (n > 0)
            {
                if ((n & 1) != 0)
                {
                    result *= a;
                }

                a *= a;
                n >>= 1;
            }

            return result;
        }

        public static long Gcd(long a, long b)
        {
            return b == 0 ? a : Gcd(b, a % b);
        }

        public static long ExtendedGcd(long a, long b, out long x, out long y)
        {
            if (b == 0)
            {
                x = 1;
                y = 0;
                return a;
            }

            long x1;
            long y1;
            long d = ExtendedGcd(b, a % b, out x1, out y1);
            x = y1;
            y = x1 - (a / b) * y1;
            return d;
        }

        public static long Lcm(long a, long b)
        {
            return (a / Gcd(a, b)) * b;
        }

        public static bool[] GetPrimes(int n)
        {
            n = Math.Max(n, 2);
            bool[] prime = new bool[n + 1];
            for (int i = 2; i <= n; i++)
            {
                prime[i] = true;
            }

            for (int i = 2; i * i <= n; i++)
            {
                if (prime[i])
                {
                    if ((long)i * i <= n)
                    {
                        for (int j = i * i; j <= n; j += i)
                        {
                            prime[j] = false;
                        }
                    }
                }
            }

            return prime;
        }

        public static long GetFibonacciNumber(long n, long mod = 0)
        {
            long[,] matrix = new long[,] { { 0, 0, 0 }, { 0, 0, 1 }, { 0, 1, 1 } };

            MatrixInt result = MatrixBinPower(new MatrixInt(matrix, mod), n);

            return result[2, 2];
        }

        public static long[] GetFibonacciSequence(int n)
        {
            long[] result = new long[n];
            result[0] = result[1] = 1;

            for (int i = 2; i < n; i++)
            {
                result[i] = result[i - 1] + result[i - 2];
            }

            return result;
        }

        public static long GetInverseElement(long a, long mod)
        {
            long x, y;
            long g = ExtendedGcd(a, mod, out x, out y);

            if (g != 1)
            {
                return -1;
            }

            return ((x % mod) + mod) % mod;
        }

        public static long[] GetAllInverseElements(long mod)
        {
            long[] result = new long[mod];
            result[1] = 1;
            for (int i = 2; i < mod; i++)
            {
                result[i] = (mod - (((mod / i) * result[mod % i]) % mod)) % mod;
            }

            return result;
        }
    }

    internal static class Reader
    {
        public static void ReadInt(out int a)
        {
            int[] number = new int[1];
            ReadInt(number);
            a = number[0];
        }

        public static void ReadInt(out int a, out int b)
        {
            int[] numbers = new int[2];
            ReadInt(numbers);
            a = numbers[0];
            b = numbers[1];
        }

        public static void ReadInt(out int int1, out int int2, out int int3)
        {
            int[] numbers = new int[3];
            ReadInt(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
        }

        public static void ReadInt(out int int1, out int int2, out int int3, out int int4)
        {
            int[] numbers = new int[4];
            ReadInt(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
            int4 = numbers[3];
        }

        public static void ReadLong(out long a)
        {
            long[] number = new long[1];
            ReadLong(number);
            a = number[0];
        }

        public static void ReadLong(out long a, out long b)
        {
            long[] numbers = new long[2];
            ReadLong(numbers);
            a = numbers[0];
            b = numbers[1];
        }

        public static void ReadLong(out long int1, out long int2, out long int3)
        {
            long[] numbers = new long[3];
            ReadLong(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
        }

        public static void ReadLong(out long int1, out long int2, out long int3, out long int4)
        {
            long[] numbers = new long[4];
            ReadLong(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
            int4 = numbers[3];
        }

        public static void ReadInt(int[] numbers)
        {
            // ReSharper disable PossibleNullReferenceException
            var list = Console.ReadLine().Split();
            // ReSharper restore PossibleNullReferenceException

            int count = Math.Min(numbers.Length, list.Length);

            for (int i = 0; i < count; i++)
            {
                numbers[i] = int.Parse(list[i]);
            }
        }

        public static int[] ReadDigits()
        {
            // ReSharper disable AssignNullToNotNullAttribute
            return Console.ReadLine().Select(x => int.Parse(x.ToString())).ToArray();
            // ReSharper restore AssignNullToNotNullAttribute
        }

        public static void ReadLong(long[] numbers)
        {
            // ReSharper disable PossibleNullReferenceException
            var list = Console.ReadLine().Split();
            // ReSharper restore PossibleNullReferenceException

            int count = Math.Min(numbers.Length, list.Length);

            for (int i = 0; i < count; i++)
            {
                numbers[i] = long.Parse(list[i]);
            }
        }

        public static void ReadDouble(double[] numbers)
        {
            // ReSharper disable PossibleNullReferenceException
            var list = Console.ReadLine().Split();
            // ReSharper restore PossibleNullReferenceException

            int count = Math.Min(numbers.Length, list.Length);

            for (int i = 0; i < count; i++)
            {
                numbers[i] = double.Parse(list[i]);
            }
        }

        public static void ReadDouble(out double a, out double b)
        {
            double[] numbers = new double[2];
            ReadDouble(numbers);
            a = numbers[0];
            b = numbers[1];
        }

        public static void ReadDouble(out double int1, out double int2, out double int3)
        {
            double[] numbers = new double[3];
            ReadDouble(numbers);
            int1 = numbers[0];
            int2 = numbers[1];
            int3 = numbers[2];
        }

        public static string ReadLine()
        {
            return Console.ReadLine();
        }
    }

    internal static class MyMath
    {
        public static int GetMinimalPrimeDivisor(int n)
        {
            for (int i = 2; i * i <= n; i++)
            {
                if (n % i == 0)
                {
                    return i;
                }
            }

            return n;
        }

        public static long Sqr(long x)
        {
            return x * x;
        }
    }

    public interface IGraph
    {
        int Vertices { get; set; }

        IList<int> this[int i] { get; }

        void AddEdge(int u, int v);

        void AddOrientedEdge(int u, int v);
    }

    public class Graph : IGraph
    {
        private List<int>[] m_Edges;

        public int Vertices { get; set; }

        public IList<int> this[int i]
        {
            get
            {
                return this.m_Edges[i];
            }
        }

        public Graph(int vertices)
        {
            this.Vertices = vertices;

            this.m_Edges = new List<int>[vertices];

            for (int i = 0; i < vertices; i++)
            {
                this.m_Edges[i] = new List<int>();
            }
        }

        public void AddEdge(int u, int v)
        {
            this.AddOrientedEdge(u, v);
            this.AddOrientedEdge(v, u);
        }

        public void AddOrientedEdge(int first, int second)
        {
            this.m_Edges[first].Add(second);
        }

        public int[] Bfs(int start)
        {
            int[] d = new int[Vertices];
            for (int i = 0; i < Vertices; i++)
            {
                d[i] = -1;
            }

            Queue<int> queue = new Queue<int>();
            queue.Enqueue(start);
            d[start] = 0;

            while (queue.Count > 0)
            {
                int v = queue.Dequeue();
                foreach (int t in this.m_Edges[v].Where(t => d[t] == -1))
                {
                    queue.Enqueue(t);
                    d[t] = d[v] + 1;
                }
            }

            return d;
        }
    }

    internal class SimpleSumTable
    {
        private readonly int[,] m_Sum;

        public SimpleSumTable(int n, int m, int[,] table)
        {
            m_Sum = new int[n + 1,m + 1];

            for (int i = 1; i < n + 1; i++)
            {
                for (int j = 1; j < m + 1; j++)
                {
                    m_Sum[i, j] = m_Sum[i, j - 1] + m_Sum[i - 1, j] - m_Sum[i - 1, j - 1] + table[i, j];
                }
            }
        }

        public int GetSum(int l, int b, int r, int t)
        {
            return m_Sum[r, t] - m_Sum[r, b] - m_Sum[l, t] + m_Sum[l, b];
        }
    }

    internal class SegmentTreeSimpleInt<T>
    {
        public int Size { get; private set; }

        private readonly T[] m_Tree;

        private Func<T, T, T> m_Operation;

        private T m_Null;

        public SegmentTreeSimpleInt(int size, Func<T, T, T> operation, T nullElement, IList<T> array = null)
        {
            this.Size = size;
            this.m_Operation = operation;
            this.m_Null = nullElement;

            m_Tree = new T[4 * size];
            if (array != null)
            {
                this.Build(array, 1, 0, size - 1);
            }
        }

        private void Build(IList<T> array, int v, int tl, int tr)
        {
            if (tl == tr)
            {
                m_Tree[v] = array[tl];
            }
            else
            {
                int tm = (tl + tr) / 2;
                this.Build(array, 2 * v, tl, tm);
                this.Build(array, 2 * v + 1, tm + 1, tr);
                this.CalculateNode(v);
            }
        }

        public T GetSum(int l, int r)
        {
            return GetSum(1, 0, Size - 1, l, r);
        }

        private T GetSum(int v, int tl, int tr, int l, int r)
        {
            if (l > r)
            {
                return m_Null;
            }

            if (l == tl && r == tr)
            {
                return m_Tree[v];
            }

            int tm = (tl + tr) / 2;

            return this.m_Operation(
                GetSum(2 * v, tl, tm, l, Math.Min(r, tm)), GetSum(2 * v + 1, tm + 1, tr, Math.Max(l, tm + 1), r));
        }

        public void Update(int pos, T newValue)
        {
            Update(1, 0, Size - 1, pos, newValue);
        }

        private void Update(int v, int tl, int tr, int pos, T newValue)
        {
            if (tl == tr)
            {
                m_Tree[v] = newValue;
            }
            else
            {
                int tm = (tl + tr) / 2;
                if (pos <= tm)
                {
                    Update(2 * v, tl, tm, pos, newValue);
                }
                else
                {
                    Update(2 * v + 1, tm + 1, tr, pos, newValue);
                }
                this.CalculateNode(v);
            }
        }

        private void CalculateNode(int v)
        {
            m_Tree[v] = this.m_Operation(m_Tree[2 * v], m_Tree[2 * v + 1]);
        }
    }

    internal struct Pair<TFirst, TSecond>
    {
        public Pair(TFirst first, TSecond second)
            : this()
        {
            this.First = first;
            this.Second = second;
        }

        public TFirst First { set; get; }

        public TSecond Second { set; get; }
    }

    internal class FenwickTreeInt64
    {
        public FenwickTreeInt64(int size)
        {
            this.m_Size = size;
            m_Tree = new long[size];
        }

        public FenwickTreeInt64(int size, IList<long> tree)
            : this(size)
        {
            for (int i = 0; i < size; i++)
            {
                Inc(i, tree[i]);
            }
        }

        public long Sum(int r)
        {
            long res = 0;
            for (; r >= 0; r = (r & (r + 1)) - 1)
            {
                res += m_Tree[r];
            }
            return res;
        }

        public long Sum(int l, int r)
        {
            return Sum(r) - Sum(l - 1);
        }

        public void Inc(int i, long x)
        {
            for (; i < m_Size; i = i | (i + 1))
            {
                m_Tree[i] += x;
            }
        }

        public void Set(int i, long x)
        {
            Inc(i, x - Sum(i, i));
        }

        private int m_Size;

        private long[] m_Tree;
    }

    internal class AccumulativeDictionary<TKey> : Dictionary<TKey, int>
    {
        public new void Add(TKey key, int value = 1)
        {
            if (this.ContainsKey(key))
            {
                base[key] += value;
            }
            else
            {
                base.Add(key, value);
            }
        }

        public new int this[TKey key]
        {
            get
            {
                return this.ContainsKey(key) ? base[key] : 0;
            }
            set
            {
                this.Add(key, value);
            }
        }
    }

    internal class PriorityQueue<T>
    {
        public PriorityQueue(Comparison<T> comparison = null)
        {
            if (comparison == null)
            {
                if (typeof(T).GetInterfaces().Any(i => i == typeof(IComparable<T>)))
                {
                    m_Comparison = (a, b) => ((IComparable<T>)a).CompareTo(b);
                }
                else
                {
                    throw new ApplicationException("Add comparer");
                }
            }
            else
            {
                m_Comparison = comparison;
            }
        }

        public int Count { get; private set; }

        public void Enqueue(T item)
        {
            m_List.Add(item);
            m_Indexes.Add(item, this.Count);
            this.Count++;
            Up(this.Count);
        }

        public T Peek()
        {
            return m_List[0];
        }

        public T Dequeue()
        {
            if (this.Count > 0)
            {
                var result = m_List[0];

                Swap(0, this.Count - 1);
                m_Indexes.Remove(m_List[this.Count - 1]);
                m_List.RemoveAt(this.Count - 1);
                this.Count--;
                this.Down(1);

                return result;
            }
            throw new ApplicationException("Couldn't get element from empty queue");
        }

        public void Update(T item)
        {
            int index = m_Indexes[item];
            this.Up(index + 1);
        }

        private readonly List<T> m_List = new List<T>();

        private readonly Dictionary<T, int> m_Indexes = new Dictionary<T, int>();

        private readonly Comparison<T> m_Comparison;

        private void Up(int index)
        {
            while (index > 1 && m_Comparison.Invoke(m_List[index - 1], m_List[index / 2 - 1]) > 0)
            {
                this.Swap(index - 1, index / 2 - 1);

                index = index / 2;
            }
        }

        private void Down(int index)
        {
            while (2 * index <= this.Count && m_Comparison.Invoke(m_List[index - 1], m_List[2 * index - 1]) < 0
                   || 2 * index + 1 <= this.Count && m_Comparison.Invoke(m_List[index - 1], m_List[2 * index]) < 0)
            {
                if (2 * index + 1 > this.Count || m_Comparison.Invoke(m_List[2 * index - 1], m_List[2 * index]) > 0)
                {
                    this.Swap(index - 1, 2 * index - 1);
                    index = 2 * index;
                }
                else
                {
                    this.Swap(index - 1, 2 * index);
                    index = 2 * index + 1;
                }
            }
        }

        private void Swap(int i, int j)
        {
            var tmp = m_List[i];
            m_List[i] = m_List[j];
            m_List[j] = tmp;

            m_Indexes[m_List[i]] = i;
            m_Indexes[m_List[j]] = j;
        }
    }

    internal class Program
    {
        private static StreamReader m_InputStream;

        private static StreamWriter m_OutStream;

        private static void OpenFiles()
        {
            m_InputStream = File.OpenText("input.txt");
            Console.SetIn(m_InputStream);

            m_OutStream = File.CreateText("output.txt");
            Console.SetOut(m_OutStream);
        }

        private static void CloseFiles()
        {
            m_OutStream.Flush();

            m_InputStream.Dispose();
            m_OutStream.Dispose();
        }

        private static void Main()
        {
            //OpenFiles();

            new Solution().Solve();

            //CloseFiles();
        }
    }

    internal class Solution
    {
        public void Solve()
        {
            int n, m;
            Reader.ReadInt(out n, out m);

            var a = new MatrixInt(new long[,] { { 1, 0 }, { 1, 3 } }, m);

            var res = Algebra.MatrixBinPower(a, n);

            Console.WriteLine((2 * res[1, 0]) % m);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Globalization;
using System.Threading;

namespace CodeForces
{

	class A
	{

		private void Solve()
		{
			int n = NextInt(), m = NextInt();
			Out.WriteLine( ( pow( 3, n, m ) - 1 + m ) % m );
		}

		int pow( int a, int b, int m )
		{
			if ( b == 1 ) return 1 % m;
			int r = pow( a, b / 2, m );
			r = (int)( ( (long)r * r ) % m );
			if ( b % 2 == 1 )
			{
				r = (int)( ( (long)r * a ) % m );
			}
			return r;
		}

		#region Local wireup

		public int NextInt()
		{
			return _in.NextInt();
		}

		public long NextLong()
		{
			return _in.NextLong();
		}

		public string NextLine()
		{
			return _in.NextLine();
		}

		public double NextDouble()
		{
			return _in.NextDouble();
		}

		readonly Scanner _in = new Scanner();
		static readonly TextWriter Out = Console.Out;

		void Start()
		{
#if !ONLINE_JUDGE
			var timer = new Stopwatch();
			timer.Start();
#endif
			var t = new Thread( Solve, 20000000 );
			t.Start();
			t.Join();
#if !ONLINE_JUDGE
			timer.Stop();
			Console.WriteLine( string.Format( CultureInfo.InvariantCulture, "Done in {0} seconds.\nPress <Enter> to exit.", timer.ElapsedMilliseconds / 1000.0 ) );
			Console.ReadLine();
#endif
		}

		static void Main()
		{
			new A().Start();
		}

		class Scanner : IDisposable
		{
			#region Fields

			readonly TextReader _reader;
			readonly int _bufferSize;
			readonly bool _closeReader;
			readonly char[] _buffer;
			int _length, _pos;

			#endregion

			#region .ctors

			public Scanner( TextReader reader, int bufferSize, bool closeReader )
			{
				_reader = reader;
				_bufferSize = bufferSize;
				_closeReader = closeReader;
				_buffer = new char[_bufferSize];
				FillBuffer( false );
			}

			public Scanner( TextReader reader, bool closeReader ) : this( reader, 1 << 16, closeReader ) { }

			public Scanner( string fileName ) : this( new StreamReader( fileName, Encoding.Default ), true ) { }

#if ONLINE_JUDGE
			public Scanner() : this( Console.In, false ) { }
#else
			public Scanner() : this( "input.txt" ) { }
#endif

			#endregion

			#region IDisposable Members

			public void Dispose()
			{
				if ( _closeReader )
				{
					_reader.Close();
				}
			}

			#endregion

			#region Properties

			public bool Eof
			{
				get
				{
					if ( _pos < _length ) return false;
					FillBuffer( false );
					return _pos >= _length;
				}
			}

			#endregion

			#region Methods

			private char NextChar()
			{
				if ( _pos < _length ) return _buffer[_pos++];
				FillBuffer( true );
				return _buffer[_pos++];
			}

			private char PeekNextChar()
			{
				if ( _pos < _length ) return _buffer[_pos];
				FillBuffer( true );
				return _buffer[_pos];
			}

			private void FillBuffer( bool throwOnEof )
			{
				_length = _reader.Read( _buffer, 0, _bufferSize );
				if ( throwOnEof && Eof )
				{
					throw new IOException( "Can't read beyond the end of file" );
				}
				_pos = 0;
			}

			public int NextInt()
			{
				var neg = false;
				int res = 0;
				SkipWhitespaces();
				if ( !Eof && PeekNextChar() == '-' )
				{
					neg = true;
					_pos++;
				}
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					var c = NextChar();
					if ( c < '0' || c > '9' ) throw new ArgumentException( "Illegal character" );
					res = 10 * res + c - '0';
				}
				return neg ? -res : res;
			}

			public long NextLong()
			{
				var neg = false;
				long res = 0;
				SkipWhitespaces();
				if ( !Eof && PeekNextChar() == '-' )
				{
					neg = true;
					_pos++;
				}
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					var c = NextChar();
					if ( c < '0' || c > '9' ) throw new ArgumentException( "Illegal character" );
					res = 10 * res + c - '0';
				}
				return neg ? -res : res;
			}

			public string NextLine()
			{
				SkipUntilNextLine();
				if ( Eof ) return "";
				var builder = new StringBuilder();
				while ( !Eof && !IsEndOfLine( PeekNextChar() ) )
				{
					builder.Append( NextChar() );
				}
				return builder.ToString();
			}

			public double NextDouble()
			{
				SkipWhitespaces();
				var builder = new StringBuilder();
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					builder.Append( NextChar() );
				}
				return double.Parse( builder.ToString(), CultureInfo.InvariantCulture );
			}

			private void SkipWhitespaces()
			{
				while ( !Eof && IsWhitespace( PeekNextChar() ) )
				{
					++_pos;
				}
			}

			private void SkipUntilNextLine()
			{
				while ( !Eof && IsEndOfLine( PeekNextChar() ) )
				{
					++_pos;
				}
			}

			private static bool IsWhitespace( char c )
			{
				return c == ' ' || c == '\t' || c == '\n' || c == '\r';
			}

			private static bool IsEndOfLine( char c )
			{
				return c == '\n' || c == '\r';
			}

			#endregion
		}

		#endregion
	}
}

using System;
using System.Collections.Generic;
using System.Text;

public class taskA
{
    static void Main(string[] args)
    {
        string inp = Console.ReadLine();
        string[] spl = inp.Split(' ');
        int n, m;
        n = int.Parse(spl[0]);
        m = int.Parse(spl[1]);

        long res = 1;
        while (n > 0)
        {
            if ((n % 2) == 0)
            {
                res *= res;
                n /= 2;
            }
            else
            {
                res *= 3;
                n--;
            }
            res = res % m;
        }
        res = (res - (long)1+(long)m) % m;
        Console.WriteLine(res);

    }

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace C24_09_12
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] s = Regex.Split(Console.ReadLine(), " ");
            Int64 n = Int64.Parse(s[0]);
            Int64 m = Int64.Parse(s[1]);
            Int64 k = 1;
            Int64 t = 3;
            while (n > 0)
            {
                if( n%2==1) k *= t;
                n /= 2;
                t *= t;
                k %= m;
                t %= m;
            }
            if (m == 1)
                k = 0;
            else
                if (k == 0) k = m - 1;
                else k--;
            Console.WriteLine("{0}", 2%1);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace C24_09_12
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] s = Regex.Split(Console.ReadLine(), " ");
            Int64 n = Int64.Parse(s[0]);
            Int64 m = Int64.Parse(s[1]);
            Int64 k = 1;
            Int64 t = 3;
            while (n > 0)
            {
                if( n%2==1) k *= t;
                n /= 2;
                t *= t;
                k %= m;
            }
            if (k == 0) k = m - 1;
            else k--;
            Console.WriteLine("{0}", k);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        public static int powermod(int b, int n, int m)
        {

            int result = 1;
            while (n > 0)
            {
                if ((n % 2) == 1)
                {
                    result = (result * b) % m;
                }
                b = (b * b) % m;
                n = n / 2;
            }
            return (result - 1) % m;
        }
        static void Main(string[] args)
        {
            int n, m, r = 1;
            string[] inp = Console.ReadLine().ToString().Split(' ');
            n = Convert.ToInt32(inp[0]);
            m = Convert.ToInt32(inp[1]);

            Console.WriteLine(powermod(3, n, m));
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        public static int powermod(int b, int n, int m)
        {
            Int64 result = 1;
            while (n > 0)
            {
                if ((n % 2) == 1)
                {
                    result = (result * b) % m;
                }
                b = (b * b) % m;
                n = n / 2;
            }
            return (int)(result - 1) % m;
        }

        static void Main(string[] args)
        {
            int n, m;
            string[] inp = Console.ReadLine().ToString().Split(' ');
            n = Convert.ToInt32(inp[0]);
            m = Convert.ToInt32(inp[1]);

            Console.WriteLine(powermod(3, n, m));
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        public static Int64 powermod(Int64 b, Int64 n, Int64 m)
        {
            Int64 result = 1;
            while (n > 0)
            {
                if ((n & 1) == 1)
                {
                    result = (result * b) % m;
                }
                b = (b * b) % m;
                n = n / 2;
            }
            return (result - 1) % m;
        }

        static void Main(string[] args)
        {
            Int64 n, m;
            string[] inp = Console.ReadLine().ToString().Split(' ');
            n = Convert.ToInt64(inp[0]);
            m = Convert.ToInt64(inp[1]);

            Console.WriteLine(powermod(3, n, m));
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        public static Int64 powermod(Int64 b, Int64 n, Int64 m)
        {
            Int64 result = 1;
            while (n > 0)
            {
                if ((n & 1) == 1)
                {
                    result = (result * b) % m;
                }
                b = (b * b) % m;
                n = n / 2;
            }
            return (result - 1) % m;
        }

        static void Main(string[] args)
        {
            Int64 n, m;
            string[] inp = Console.ReadLine().ToString().Split(' ');
            n = Convert.ToInt32(inp[0]);
            m = Convert.ToInt32(inp[1]);

            Console.WriteLine(powermod(3, n, m));
        }
    }
}

using System;
using System.Numerics;

public class CF_227C
{
    public CF_227C()
    {
    }

    public long solve(int n, int m)
    {
		long[] powersof3 = new long[32];
		powersof3[0] = 3 % m;
		for (int i = 1; i < 32; i++)
        {
			powersof3[i] = (powersof3[i - 1] * powersof3[i - 1]) % m;
            powersof3[i] = (powersof3[i] == 0 ? 1 : powersof3[i]);
		}

        long answer = 1;
        for (int i = 0; i < 32; i++)
        {
            if ((n & (1 << i)) != 0)
            {
                answer *= powersof3[i];
                answer %= m;
            }
        }
        answer = (answer == 0 ? m - 1 : answer - 1);
        return answer;
	}

    public static void Main(string[] args)
    {
        string[] lines = Console.ReadLine().Split();
        int n = Convert.ToInt32(lines[0]);
        int m = Convert.ToInt32(lines[1]);
        Console.WriteLine(new CF_227C().solve(n, m));
    }
}

using System;
using System.Numerics;

public class CF_227C
{
    public CF_227C()
    {
    }

    public long solve(int n, int m)
    {
		long[] powersof3 = new long[32];
		powersof3[0] = 3 % m;
		for (int i = 1; i < 32; i++)
		{
			powersof3[i] = (powersof3[i - 1] * powersof3[i - 1]) % m;
		}

        long answer = 1;
        for (int i = 0; i < 32; i++)
        {
            if ((n & (1 << i)) != 0)
            {
                answer *= powersof3[i];
                answer %= m;
            }
        }
        return answer - 1;
	}

    public static void Main(string[] args)
    {
        string[] lines = Console.ReadLine().Split();
        int n = Convert.ToInt32(lines[0]);
        int m = Convert.ToInt32(lines[1]);
        Console.WriteLine(new CF_227C().solve(n, m));
    }
}

using System;
using System.Collections.Generic;
using System.Text;

class CF_227C
{
    public long solve(long n, long m)
    {
        long[] powerof3 = new long[32];
        long k = 1;
        long power = 3 % m;
        for (int i = 0; i < 32; i++)
        {
            k = (k * power) % m;
            powerof3[i] = k;
        }

        k = 1;
        for (int i = 0; i < 32; i++)
        {
            if ((n & (1 << i)) != 0)
            {
                k *= powerof3[i]; k %= m;
            }
        }
        return k - 1;
    }

    public static void Main(string[] args)
    {
        string[] lines = Console.ReadLine().Split();
        long n = Convert.ToInt64(lines[0]);
        long m = Convert.ToInt64(lines[1]);
        Console.WriteLine(new CF_227C().solve(n, m));
    }
}

#if !ONLINE_JUDGE
namespace CodeForces
{
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class Test_CF_227C
    {
        [TestMethod]
        public void Test1()
        {
            Assert.AreEqual(2, new CF_227C().solve(1, 10));
        }

        [TestMethod]
        public void Test2()
        {
            Assert.AreEqual(2, new CF_227C().solve(3, 8));
        }

        [TestMethod]
        public void Test3()
        {
            Assert.AreEqual(690359500, new CF_227C().solve(331358794, 820674098));
        }
    }
}
#endif