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

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var solver = new Solver(n, m, k, c, d);
            solver.Init();

            ReadInput(solver, m);

            for (var i = 0; i < k; i++)
                solver.IncreaseFlow();

            Console.WriteLine(solver.TotalCost);
        }

        private static void ReadInput(Solver solver, int m)
        {
            var memberHomes = Console.ReadLine().Split().GroupBy(int.Parse);
            foreach (var memberHome in memberHomes)
                solver.AddMemberHome(memberHome.Key - 1, memberHome.Count());

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = int.Parse(xy[0]) - 1;
                var y = int.Parse(xy[1]) - 1;

                solver.AddEdge(x, y);
                solver.AddEdge(y, x);
            }
        }
    }

    internal sealed class Solver
    {
        private static readonly Edge FakeEdge = new Edge();

        private readonly int _n, _m, _k, _c, _d;
        private readonly int _maxTime;
        private readonly Node _start, _sink;
        private readonly Node[,] _nodes;
        private readonly List<Edge>[] _nodeEdges;

        private readonly int[] _bestCosts;
        private readonly Edge[] _bestMoves;
        private readonly bool[] _isInQueue;
        private readonly Queue<Node> _bestPathSearchQueue;

        public Solver(int n, int m, int k, int c, int d)
        {
            _n = n;
            _m = m;
            _k = k;
            _c = c;
            _d = d;

            _maxTime = k + m;
            _nodes = new Node[n, _maxTime];

            _start = new Node() {Id = _nodes.Length};
            _sink = new Node() {Id = _nodes.Length + 1};

            var allNodesCount = _nodes.Length + 2;

            _nodeEdges = new List<Edge>[allNodesCount];
            _bestCosts = new int[allNodesCount];
            _bestMoves = new Edge[allNodesCount];
            _isInQueue = new bool[allNodesCount];
            _bestPathSearchQueue = new Queue<Node>(allNodesCount);

            for (var i = 0; i < allNodesCount; i++)
                _nodeEdges[i] = new List<Edge>(_maxTime);
        }

        public int TotalCost { get; private set; }

        public void Init()
        {
            var nodeId = 0;
            for (var node = 0; node < _n; node++)
                for (var time = 0; time < _maxTime; time++)
                    _nodes[node, time] = new Node() { Id = nodeId++ };

            for (var time = 0; time < _maxTime; time++)
                AddEdgeWithoutPair(_nodes[0, time], _sink, time * _c, _k);

            for (var node = 0; node < _n; node++)
            {
                var from = _nodes[node, 0];
                for (var time = 1; time < _maxTime; time++)
                {
                    var to = _nodes[node, time];
                    AddEdgePair(from, to, 0, _k);
                    from = to;
                }
            }

            _isInQueue[_sink.Id] = true;
        }

        public void AddMemberHome(int home, int count)
        {
            AddEdgeWithoutPair(_start, _nodes[home, 0], 0, count);
        }

        public void AddEdge(int from, int to)
        {
            for (var time = 0; time < _maxTime - 1; time++)
            {
                var nodeFrom = _nodes[from, time];
                var nodeTo = _nodes[to, time + 1];

                for (int people = 0, cost = 1; people < _k; people++, cost += 2)
                    AddEdgePair(nodeFrom, nodeTo, cost * _d, 1);
            }
        }

        public void IncreaseFlow()
        {
            FindBestPath();
            CommitBestPath();
            TotalCost += _bestCosts[_sink.Id];
        }

        private void FindBestPath()
        {
            for (var i = 0; i < _bestCosts.Length; i++)
                _bestCosts[i] = int.MaxValue;

            _bestCosts[_start.Id] = 0;
            _bestPathSearchQueue.Enqueue(_start);

            while (_bestPathSearchQueue.Count > 0)
            {
                var node = _bestPathSearchQueue.Dequeue();
                var costToNode = _bestCosts[node.Id];

                foreach (var edge in _nodeEdges[node.Id])
                {
                    if (edge.ResidualCapacity == 0)
                        continue;

                    var possibleCost = costToNode + edge.Cost;
                    if (possibleCost >= _bestCosts[edge.To.Id])
                        continue;

                    _bestCosts[edge.To.Id] = possibleCost;
                    _bestMoves[edge.To.Id] = edge;
                    if (_isInQueue[edge.To.Id])
                        continue;

                    _isInQueue[edge.To.Id] = true;
                    _bestPathSearchQueue.Enqueue(edge.To);
                }

                _isInQueue[node.Id] = false;
            }
        }

        private void CommitBestPath()
        {
            var cur = _bestMoves[_sink.Id];
            while (cur != null)
            {
                cur.ResidualCapacity--;
                cur.Paired.ResidualCapacity++;
                cur = _bestMoves[cur.From.Id];
            }
        }

        private void AddEdgePair(Node from, Node to, int cost, int capacity)
        {
            var forwardEdge = new Edge()
            {
                From = from,
                To = to,
                Cost = cost,
                ResidualCapacity = capacity,
            };

            var reverseEdge = new Edge()
            {
                From = to,
                To = from,
                Cost = -cost,
                ResidualCapacity = 0,
            };

            forwardEdge.Paired = reverseEdge;
            reverseEdge.Paired = forwardEdge;

            _nodeEdges[from.Id].Add(forwardEdge);
            _nodeEdges[to.Id].Add(reverseEdge);
        }

        private void AddEdgeWithoutPair(Node from, Node to, int cost, int capacity)
        {
            _nodeEdges[from.Id].Add(new Edge()
            {
                From = from,
                To = to,
                Cost = cost,
                ResidualCapacity = capacity,
                Paired = FakeEdge,
            });
        }
    }

    internal struct Node
    {
        public int Id { get; set; }
        public override string ToString() => Id.ToString();
    }

    internal sealed class Edge
    {
        public Node From { get; set; }
        public Node To { get; set; }
        public int Cost { get; set; }
        public int ResidualCapacity { get; set; }
        public Edge Paired { get; set; }
    }
}


using System;
using System.Collections.Generic;

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var solver = new Solver(n, m, k, c, d);
            solver.Init();

            ReadInput(solver, n, m);

            for (var i = 0; i < k; i++)
                solver.IncreaseFlow();

            Console.WriteLine(solver.TotalCost);
        }

        private static void ReadInput(Solver solver, int n, int m)
        {
            var memberCounts = new int[n];
            foreach (var memberHome in Console.ReadLine().Split())
                memberCounts[int.Parse(memberHome) - 1]++;

            for (var crossroad = 0; crossroad < n; crossroad++)
                solver.AddMemberHome(crossroad, memberCounts[crossroad]);

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = int.Parse(xy[0]) - 1;
                var y = int.Parse(xy[1]) - 1;

                solver.AddEdge(x, y);
                solver.AddEdge(y, x);
            }
        }
    }

    internal sealed class Solver
    {
        private static readonly Edge FakeEdge = new Edge();

        private readonly int _n, _m, _k, _c, _d;
        private readonly int _maxTime;
        private readonly Node _start, _sink;
        private readonly Node[,] _nodes;
        private readonly List<Edge>[] _nodeEdges;
        private readonly BestPathSearcher _bestPathSearcher;

        public Solver(int n, int m, int k, int c, int d)
        {
            _n = n;
            _m = m;
            _k = k;
            _c = c;
            _d = d;

            _maxTime = k + m;
            _nodes = new Node[n, _maxTime];

            _start = new Node() {Id = _nodes.Length};
            _sink = new Node() {Id = _nodes.Length + 1};

            var allNodesCount = _nodes.Length + 2;

            _nodeEdges = new List<Edge>[allNodesCount];
            for (var i = 0; i < allNodesCount; i++)
                _nodeEdges[i] = new List<Edge>(_maxTime);

            _bestPathSearcher = new BestPathSearcher(_nodeEdges);
        }

        public int TotalCost { get; private set; }

        public void Init()
        {
            var nodeId = 0;
            for (var node = 0; node < _n; node++)
                for (var time = 0; time < _maxTime; time++)
                    _nodes[node, time] = new Node() { Id = nodeId++ };

            for (var time = 0; time < _maxTime; time++)
                AddEdgeWithoutPair(_nodes[0, time], _sink, time * _c, _k);

            for (var node = 0; node < _n; node++)
            {
                var from = _nodes[node, 0];
                for (var time = 1; time < _maxTime; time++)
                {
                    var to = _nodes[node, time];
                    AddEdgePair(from, to, 0, _k);
                    from = to;
                }
            }
        }

        public void AddMemberHome(int home, int count)
        {
            if (count > 0)
                AddEdgeWithoutPair(_start, _nodes[home, 0], 0, count);
        }

        public void AddEdge(int from, int to)
        {
            for (var time = 0; time < _maxTime - 1; time++)
            {
                var nodeFrom = _nodes[from, time];
                var nodeTo = _nodes[to, time + 1];

                for (int people = 0, cost = 1; people < _k; people++, cost += 2)
                    AddEdgePair(nodeFrom, nodeTo, cost * _d, 1);
            }
        }

        public void IncreaseFlow()
        {
            var bestPath = _bestPathSearcher.FindBestPath(_start, _sink);
            foreach (var edge in bestPath)
            {
                edge.ResidualCapacity--;
                edge.PairedEdge.ResidualCapacity++;
                TotalCost += edge.Cost;
            }
        }

        private void AddEdgePair(Node from, Node to, int cost, int capacity)
        {
            var forwardEdge = new Edge()
            {
                From = from,
                To = to,
                Cost = cost,
                ResidualCapacity = capacity,
            };

            var reverseEdge = new Edge()
            {
                From = to,
                To = from,
                Cost = -cost,
                ResidualCapacity = 0,
            };

            forwardEdge.PairedEdge = reverseEdge;
            reverseEdge.PairedEdge = forwardEdge;

            _nodeEdges[from.Id].Add(forwardEdge);
            _nodeEdges[to.Id].Add(reverseEdge);
        }

        private void AddEdgeWithoutPair(Node from, Node to, int cost, int capacity)
        {
            _nodeEdges[from.Id].Add(new Edge()
            {
                From = from,
                To = to,
                Cost = cost,
                ResidualCapacity = capacity,
                PairedEdge = FakeEdge,
            });
        }
    }

    internal sealed class BestPathSearcher
    {
        private readonly List<Edge>[] _nodeEdges;

        private readonly int[] _bestCosts;
        private readonly Edge[] _bestMoves;
        private readonly bool[] _isInQueue;
        private readonly Queue<Node> _bestPathSearchQueue;

        public BestPathSearcher(List<Edge>[] nodeEdges)
        {
            _nodeEdges = nodeEdges;
            _bestCosts = new int[nodeEdges.Length];
            _bestMoves = new Edge[nodeEdges.Length];
            _isInQueue = new bool[nodeEdges.Length];
            _bestPathSearchQueue = new Queue<Node>(nodeEdges.Length);
        }

        public IEnumerable<Edge> FindBestPath(Node start, Node to)
        {
            for (var i = 0; i < _bestCosts.Length; i++)
                _bestCosts[i] = int.MaxValue;

            _bestCosts[start.Id] = 0;
            _bestPathSearchQueue.Enqueue(start);

            while (_bestPathSearchQueue.Count > 0)
            {
                var node = _bestPathSearchQueue.Dequeue();
                var costToNode = _bestCosts[node.Id];

                foreach (var edge in _nodeEdges[node.Id])
                {
                    if (edge.ResidualCapacity == 0)
                        continue;

                    var possibleCost = costToNode + edge.Cost;
                    if (possibleCost >= _bestCosts[edge.To.Id])
                        continue;

                    _bestCosts[edge.To.Id] = possibleCost;
                    _bestMoves[edge.To.Id] = edge;
                    if (_isInQueue[edge.To.Id])
                        continue;

                    _isInQueue[edge.To.Id] = true;
                    _bestPathSearchQueue.Enqueue(edge.To);
                }

                _isInQueue[node.Id] = false;
            }

            var cur = _bestMoves[to.Id];
            while (cur != null)
            {
                yield return cur;
                cur = _bestMoves[cur.From.Id];
            }
        }
    }

    internal struct Node
    {
        public int Id { get; set; }
        public override string ToString() => Id.ToString();
    }

    internal sealed class Edge
    {
        public Node From { get; set; }
        public Node To { get; set; }
        public int Cost { get; set; }
        public int ResidualCapacity { get; set; }
        public Edge PairedEdge { get; set; }
    }
}


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

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var solver = new Solver(n, m, k, c, d);
            solver.Init();

            var memberHomes = Console.ReadLine().Split().GroupBy(int.Parse);
            foreach (var memberHome in memberHomes)
                solver.AddMemberHome(memberHome.Key - 1, memberHome.Count());

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = int.Parse(xy[0]) - 1;
                var y = int.Parse(xy[1]) - 1;

                solver.AddEdge(x, y);
                solver.AddEdge(y, x);
            }

            for (var i = 0; i < k; i++)
                solver.IncreaseFlow();

            Console.WriteLine(solver.TotalCost);
        }
    }

    internal sealed class Solver
    {
        private static readonly Edge FakeEdge = new Edge();

        private readonly int _n, _m, _k, _c, _d;
        private readonly int _maxTime;
        private readonly Node _start, _sink;
        private readonly Node[,] _nodes;
        private readonly List<Edge>[] _nodeEdges;

        private readonly int[] _bestCosts;
        private readonly Edge[] _bestMoves;
        private readonly bool[] _isInQueue;
        private readonly Queue<Node> _bestPathSearchQueue;

        public Solver(int n, int m, int k, int c, int d)
        {
            _n = n;
            _m = m;
            _k = k;
            _c = c;
            _d = d;

            _maxTime = k + m;
            _nodes = new Node[n, _maxTime];

            _start = new Node() {Id = _nodes.Length};
            _sink = new Node() {Id = _nodes.Length + 1};

            var allNodesCount = _nodes.Length + 2;

            _nodeEdges = new List<Edge>[allNodesCount];
            _bestCosts = new int[allNodesCount];
            _bestMoves = new Edge[allNodesCount];
            _isInQueue = new bool[allNodesCount];
            _bestPathSearchQueue = new Queue<Node>(allNodesCount);

            for (var i = 0; i < allNodesCount; i++)
                _nodeEdges[i] = new List<Edge>();
        }

        public int TotalCost { get; private set; }

        public void Init()
        {
            var nodeId = 0;
            for (var node = 0; node < _n; node++)
                for (var time = 0; time < _maxTime; time++)
                    _nodes[node, time] = new Node() { Id = nodeId++ };

            for (var time = 0; time < _maxTime; time++)
                AddEdgePair(_nodes[0, time], _sink, time * _c, _k);

            for (var node = 0; node < _n; node++)
            {
                var from = _nodes[node, 0];
                for (var time = 1; time < _maxTime; time++)
                {
                    var to = _nodes[node, time];
                    AddEdgePair(from, to, 0, _k);
                    from = to;
                }
            }

            _isInQueue[_sink.Id] = true;
        }

        public void AddMemberHome(int home, int count)
        {
            _nodeEdges[_start.Id].Add(new Edge()
            {
                From = _start,
                To = _nodes[home, 0],
                Cost = 0,
                ResidualCapacity = count,
                Paired = FakeEdge,
            });
        }

        public void AddEdge(int from, int to)
        {
            for (var time = 0; time < _maxTime - 1; time++)
            {
                var nodeFrom = _nodes[from, time];
                var nodeTo = _nodes[to, time + 1];

                for (int people = 0, cost = 1; people < _k; people++, cost += 2)
                    AddEdgePair(nodeFrom, nodeTo, cost * _d, 1);
            }
        }

        public void IncreaseFlow()
        {
            FindBestPath();
            CommitBestPath();
            TotalCost += _bestCosts[_sink.Id];
        }

        private void FindBestPath()
        {
            for (var i = 0; i < _bestCosts.Length; i++)
                _bestCosts[i] = int.MaxValue;

            _bestCosts[_start.Id] = 0;
            _bestPathSearchQueue.Enqueue(_start);

            while (_bestPathSearchQueue.Count > 0)
            {
                var node = _bestPathSearchQueue.Dequeue();
                var costToNode = _bestCosts[node.Id];

                foreach (var edge in _nodeEdges[node.Id])
                {
                    if (edge.ResidualCapacity == 0)
                        continue;

                    var possibleCost = costToNode + edge.Cost;
                    if (possibleCost >= _bestCosts[edge.To.Id])
                        continue;

                    _bestCosts[edge.To.Id] = possibleCost;
                    _bestMoves[edge.To.Id] = edge;
                    if (_isInQueue[edge.To.Id])
                        continue;

                    _isInQueue[edge.To.Id] = true;
                    _bestPathSearchQueue.Enqueue(edge.To);
                }

                _isInQueue[node.Id] = false;
            }
        }

        private void CommitBestPath()
        {
            var cur = _bestMoves[_sink.Id];
            while (cur != null)
            {
                cur.ResidualCapacity--;
                cur.Paired.ResidualCapacity++;
                cur = _bestMoves[cur.From.Id];
            }
        }

        private void AddEdgePair(Node from, Node to, int cost, int capacity)
        {
            var forwardEdge = new Edge()
            {
                From = from,
                To = to,
                Cost = cost,
                ResidualCapacity = capacity,
            };

            var reverseEdge = new Edge()
            {
                From = to,
                To = from,
                Cost = -cost,
                ResidualCapacity = 0,
            };

            forwardEdge.Paired = reverseEdge;
            reverseEdge.Paired = forwardEdge;

            _nodeEdges[from.Id].Add(forwardEdge);
            _nodeEdges[to.Id].Add(reverseEdge);
        }
    }

    internal struct Node
    {
        public int Id { get; set; }
        public override string ToString() => Id.ToString();
    }

    internal sealed class Edge
    {
        public Node From { get; set; }
        public Node To { get; set; }
        public int Cost { get; set; }
        public int ResidualCapacity { get; set; }
        public Edge Paired { get; set; }
    }
}


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

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var solver = new Solver(n, m, k, c, d);
            solver.Init();

            var memberHomes = Console.ReadLine().Split().GroupBy(int.Parse);
            foreach (var memberHome in memberHomes)
                solver.AddMemberHome(memberHome.Key - 1, memberHome.Count());

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = int.Parse(xy[0]) - 1;
                var y = int.Parse(xy[1]) - 1;

                solver.AddEdge(x, y);
                solver.AddEdge(y, x);
            }

            for (var i = 0; i < k; i++)
                solver.IncreaseFlow();

            Console.WriteLine(solver.TotalCost);
        }
    }

    internal sealed class Solver
    {
        private static readonly Edge FakeEdge = new Edge();

        private readonly int _n, _m, _k, _c, _d;
        private readonly int _maxTime;
        private readonly Node _start, _sink;
        private readonly Node[,] _nodes;
        private readonly List<Edge>[] _nodeEdges;

        private readonly int[] _bestCosts;
        private readonly Edge[] _bestMoves;

        public Solver(int n, int m, int k, int c, int d)
        {
            _n = n;
            _m = m;
            _k = k;
            _c = c;
            _d = d;

            _maxTime = k + m;
            _nodes = new Node[n, _maxTime];

            _start = new Node() {Id = _nodes.Length};
            _sink = new Node() {Id = _nodes.Length + 1};

            var allNodesCount = _nodes.Length + 2;

            _nodeEdges = new List<Edge>[allNodesCount];
            _bestCosts = new int[allNodesCount];
            _bestMoves = new Edge[allNodesCount];

            for (var i = 0; i < allNodesCount; i++)
                _nodeEdges[i] = new List<Edge>();
        }

        public int TotalCost { get; private set; }

        public void Init()
        {
            var nodeId = 0;
            for (var node = 0; node < _n; node++)
                for (var time = 0; time < _maxTime; time++)
                    _nodes[node, time] = new Node() { Id = nodeId++ };

            for (var time = 0; time < _maxTime; time++)
                AddEdgePair(_nodes[0, time], _sink, time * _c, _k);

            for (var node = 0; node < _n; node++)
            {
                var from = _nodes[node, 0];
                for (var time = 1; time < _maxTime; time++)
                {
                    var to = _nodes[node, time];
                    AddEdgePair(from, to, 0, _k);
                    from = to;
                }
            }
        }

        public void AddMemberHome(int home, int count)
        {
            _nodeEdges[_start.Id].Add(new Edge()
            {
                From = _start,
                To = _nodes[home, 0],
                Cost = 0,
                ResidualCapacity = count,
                Paired = FakeEdge,
            });
        }

        public void AddEdge(int from, int to)
        {
            for (var time = 0; time < _maxTime - 1; time++)
            {
                var nodeFrom = _nodes[from, time];
                var nodeTo = _nodes[to, time + 1];

                for (int people = 0, cost = 1; people < _k; people++, cost += 2)
                    AddEdgePair(nodeFrom, nodeTo, cost * _d, 1);
            }
        }

        public void IncreaseFlow()
        {
            FindBestPath();
            CommitBestPath();
            TotalCost += _bestCosts[_sink.Id];
        }

        private void FindBestPath()
        {
            for (var i = 0; i < _bestCosts.Length; i++)
                _bestCosts[i] = int.MaxValue;

            _bestCosts[_start.Id] = 0;

            bool any;
            do
            {
                any = false;
                for (var nodeId = 0; nodeId < _nodeEdges.Length; nodeId++)
                {
                    var costToSource = _bestCosts[nodeId];
                    if (costToSource == int.MaxValue)
                        continue;

                    foreach (var edge in _nodeEdges[nodeId])
                    {
                        if (edge.ResidualCapacity == 0)
                            continue;

                        var newCost = costToSource + edge.Cost;
                        if (_bestCosts[edge.To.Id] <= newCost)
                            continue;

                        _bestCosts[edge.To.Id] = newCost;
                        _bestMoves[edge.To.Id] = edge;
                        any = true;
                    }
                }
            }
            while (any);
        }

        private void CommitBestPath()
        {
            var cur = _bestMoves[_sink.Id];
            while (cur != null)
            {
                cur.ResidualCapacity--;
                cur.Paired.ResidualCapacity++;
                cur = _bestMoves[cur.From.Id];
            }
        }

        private void AddEdgePair(Node from, Node to, int cost, int capacity)
        {
            var forwardEdge = new Edge()
            {
                From = from,
                To = to,
                Cost = cost,
                ResidualCapacity = capacity,
            };

            var reverseEdge = new Edge()
            {
                From = to,
                To = from,
                Cost = -cost,
                ResidualCapacity = 0,
            };

            forwardEdge.Paired = reverseEdge;
            reverseEdge.Paired = forwardEdge;

            _nodeEdges[from.Id].Add(forwardEdge);
            _nodeEdges[to.Id].Add(reverseEdge);
        }
    }

    internal struct Node
    {
        public int Id { get; set; }
        public override string ToString() => Id.ToString();
    }

    internal sealed class Edge
    {
        public Node From { get; set; }
        public Node To { get; set; }
        public int Cost { get; set; }
        public int ResidualCapacity { get; set; }
        public Edge Paired { get; set; }
    }
}


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

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var memberHomes = Console.ReadLine().Split().Select(int.Parse);
            var graph = ReadGraph(n, m, k);
            FindPathLengths(graph);

            var solver = new Solver(n, c, d);

            foreach (var memberHome in memberHomes)
                solver.AddDiscontentForMember(graph[memberHome]);

            Console.WriteLine(solver.Discontent);
        }

        private static GraphNode[] ReadGraph(int n, int m, int k)
        {
            var graph = new GraphNode[n + 1];
            for (var i = 1; i <= n; i++)
                graph[i] = new GraphNode(i, m);

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = graph[int.Parse(xy[0])];
                var y = graph[int.Parse(xy[1])];

                x.Edges.Add(new Edge() { Node = y, TimeInfo = new TimeInfo(k) });
                y.Edges.Add(new Edge() { Node = x, TimeInfo = new TimeInfo(k) });
            }

            return graph;
        }

        private static void FindPathLengths(GraphNode[] graph)
        {
            var queue = new Queue<GraphNode>(graph.Length);

            var node = graph[1];
            node.PathLength = 0;
            queue.Enqueue(node);

            while (queue.Count > 0)
            {
                node = queue.Dequeue();
                var newPathLength = node.PathLength + 1;

                foreach (var neighbour in node.Edges.Select(it => it.Node))
                {
                    if (neighbour.PathLength <= newPathLength)
                        continue;

                    neighbour.PathLength = newPathLength;
                    queue.Enqueue(neighbour);
                }
            }
        }
    }

    internal sealed class Solver
    {
        private readonly int _c, _d, _cPlusD;
        private readonly EdgeIndexWithTime[] _bestPath;

        private int _currentBestDiscontent, _bestPathLength;

        public Solver(int n, int c, int d)
        {
            _c = c;
            _d = d;
            _cPlusD = c + d;
            _bestPath = new EdgeIndexWithTime[n + 1];
        }

        public int Discontent { get; private set; }

        public void AddDiscontentForMember(GraphNode home)
        {
            _currentBestDiscontent = int.MaxValue;
            TryOptimize(home, 0, 0, 0);
            CommitBestPath(home);
            Discontent += _currentBestDiscontent;
        }

        private bool TryOptimize(GraphNode node, int time, int baseDiscontent, int bestPathIndex)
        {
            if (node.Id == 1)
            {
                if (baseDiscontent >= _currentBestDiscontent)
                    return false;

                _bestPathLength = bestPathIndex;
                _currentBestDiscontent = baseDiscontent;
                return true;
            }

            node.AlreadyInCurrentPath = true;

            var optimized = false;

            var nextBestPathIndex = bestPathIndex + 1;

            for (var idealContinuationDiscontent = baseDiscontent + node.PathLength * _cPlusD;
                idealContinuationDiscontent < _currentBestDiscontent;
                idealContinuationDiscontent += _c, ++time)
            {
                var nextTime = time + 1;
                baseDiscontent += _c;

                for (var edgeIndex = 0; edgeIndex < node.Edges.Count; edgeIndex++)
                {
                    var edge = node.Edges[edgeIndex];

                    var neighbour = edge.Node;
                    if (neighbour.AlreadyInCurrentPath)
                        continue;

                    var nextBaseDiscontent = baseDiscontent +
                                             CalculateDiscontentChange(edge.TimeInfo[time]);

                    if (!TryOptimize(neighbour, nextTime, nextBaseDiscontent, nextBestPathIndex))
                        continue;

                    _bestPath[bestPathIndex] = new EdgeIndexWithTime() {EdgeIndex = edgeIndex, Time = time};
                    optimized = true;
                    if (idealContinuationDiscontent >= _currentBestDiscontent)
                        break;
                }
            }

            node.AlreadyInCurrentPath = false;
            return optimized;
        }

        private void CommitBestPath(GraphNode current)
        {
            foreach (var edgeIndexWithTime in _bestPath.Take(_bestPathLength))
            {
                var edge = current.Edges[edgeIndexWithTime.EdgeIndex];
                ++edge.TimeInfo[edgeIndexWithTime.Time];
                current = edge.Node;
            }
        }

        private int CalculateDiscontentChange(int peopleWalkingTheSameTime)
        {
            var oldDiscontentD = peopleWalkingTheSameTime * peopleWalkingTheSameTime * _d;
            ++peopleWalkingTheSameTime;
            var newDiscontentD = peopleWalkingTheSameTime * peopleWalkingTheSameTime * _d;
            return newDiscontentD - oldDiscontentD;
        }

        private struct EdgeIndexWithTime
        {
            public int EdgeIndex { get; set; }
            public int Time { get; set; }
        }
    }

    internal sealed class GraphNode : IEquatable<GraphNode>
    {
        public GraphNode(int id, int m)
        {
            Id = id;
            Edges = new List<Edge>(m);
        }

        public int Id { get; }

        public int PathLength { get; set; } = 1000;

        public bool AlreadyInCurrentPath { get; set; }

        public List<Edge> Edges { get; }

        public bool Equals(GraphNode other) => Id == other?.Id;

        public override bool Equals(object obj) => obj is GraphNode graphNode && graphNode.Id == Id;

        public override int GetHashCode() => Id;
    }

    internal struct TimeInfo
    {
        private readonly Dictionary<int, int> _peopleCounts;

        public TimeInfo(int capacity) { _peopleCounts = new Dictionary<int, int>(capacity); }

        public int this[int time]
        {
            get
            {
                _peopleCounts.TryGetValue(time, out var peopleCount);
                return peopleCount;
            }

            set => _peopleCounts[time] = value;
        }
    }

    internal struct Edge
    {
        public GraphNode Node;
        public TimeInfo TimeInfo;
    }
}


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

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var solver = new Solver(n, m, k, c, d);
            solver.Init();

            var memberHomes = Console.ReadLine().Split().GroupBy(int.Parse);
            foreach (var memberHome in memberHomes)
                solver.AddMemberHome(memberHome.Key - 1, memberHome.Count());

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = int.Parse(xy[0]) - 1;
                var y = int.Parse(xy[1]) - 1;

                solver.AddEdge(x, y);
                solver.AddEdge(y, x);
            }

            for (var i = 0; i < k; i++)
                solver.IncreaseFlow();

            Console.WriteLine(solver.TotalCost);
        }
    }

    internal sealed class Solver
    {
        private static readonly Edge FakeEdge = new Edge();
        private readonly int _n, _m, _k, _c, _d;
        private readonly int _maxTime;
        private readonly Node _start, _sink;
        private readonly Node[,] _nodes;
        private readonly List<Edge>[] _nodeEdges;

        private readonly int[] _bestCosts;
        private readonly Edge[] _bestMoves;
        private readonly bool[] _isInQueue;
        private readonly Queue<Node> _bestPathSearchQueue;

        public Solver(int n, int m, int k, int c, int d)
        {
            _n = n;
            _m = m;
            _k = k;
            _c = c;
            _d = d;

            _maxTime = k + m;
            _nodes = new Node[n, _maxTime];

            _start = new Node() {Id = _nodes.Length};
            _sink = new Node() {Id = _nodes.Length + 1};

            var allNodesCount = _nodes.Length + 2;

            _nodeEdges = new List<Edge>[allNodesCount];
            _bestCosts = new int[allNodesCount];
            _bestMoves = new Edge[allNodesCount];
            _isInQueue = new bool[allNodesCount];
            _bestPathSearchQueue = new Queue<Node>(allNodesCount);

            for (var i = 0; i < _nodeEdges.Length; i++)
                _nodeEdges[i] = new List<Edge>();
        }

        public int TotalCost { get; private set; }

        public void Init()
        {
            var nodeId = 0;
            for (var node = 0; node < _n; node++)
                for (var time = 0; time < _maxTime; time++)
                    _nodes[node, time] = new Node() { Id = nodeId++ };

            for (var time = 0; time < _maxTime; time++)
            {
                var leaderHome = _nodes[0, time];

                _nodeEdges[leaderHome.Id].Add(new Edge()
                {
                    From = leaderHome,
                    To = _sink,
                    Flow = new Flow() { Capacity = _k },
                    Cost = time * _c,
                    Paired = FakeEdge,
                });
            }

            for (var node = 0; node < _n; node++)
                for (var time = 0; time < _maxTime - 1; time++)
                {
                    var from = _nodes[node, time];
                    var to = _nodes[node, time + 1];
                    _nodeEdges[from.Id].Add(new Edge()
                    {
                        From = from,
                        To = to,
                        Cost = 0,
                        Flow = new Flow() { Capacity = int.MaxValue },
                        Paired = FakeEdge,
                    });
                }

            _isInQueue[_sink.Id] = true;
        }

        public void AddMemberHome(int home, int count)
        {
            var target = _nodes[home, 0];

            _nodeEdges[_start.Id].Add(new Edge()
            {
                From = _start,
                To = target,
                Flow = new Flow() { Capacity = count },
                Cost = 0,
                Paired = FakeEdge,
            });
        }

        public void AddEdge(int from, int to)
        {
            for (var time = 0; time < _maxTime - 1; time++)
            {
                var nodeFrom = _nodes[from, time];
                var nodeTo = _nodes[to, time + 1];

                for (int people = 0, cost = 1; people < _k; people++, cost += 2)
                {
                    var mainEdge = new Edge()
                    {
                        From = nodeFrom,
                        To = nodeTo,
                        Flow = new Flow() { Capacity = 1 },
                        Cost = cost * _d,
                    };

                    var helpEdge = new Edge()
                    {
                        From = nodeTo,
                        To = nodeFrom,
                        Flow = new Flow() { Capacity = 0 },
                        Cost = -cost * _d,
                    };

                    mainEdge.Paired = helpEdge;
                    helpEdge.Paired = mainEdge;

                    _nodeEdges[nodeFrom.Id].Add(mainEdge);
                    _nodeEdges[nodeTo.Id].Add(helpEdge);
                }
            }
        }

        public void IncreaseFlow()
        {
            FindBestPath();
            var flow = FindFlow();
            CommitBestPath(flow);
        }

        private void FindBestPath()
        {
            for (var i = 0; i < _bestCosts.Length; i++)
                _bestCosts[i] = int.MaxValue;

            _bestCosts[_start.Id] = 0;
            _bestPathSearchQueue.Enqueue(_start);

            while (_bestPathSearchQueue.Count > 0)
            {
                var node = _bestPathSearchQueue.Dequeue();
                var costToNode = _bestCosts[node.Id];

                foreach (var edge in _nodeEdges[node.Id])
                {
                    if (edge.Flow.Filled)
                        continue;

                    var possibleCost = costToNode + edge.Cost;
                    if (possibleCost >= _bestCosts[edge.To.Id])
                        continue;

                    _bestCosts[edge.To.Id] = possibleCost;
                    _bestMoves[edge.To.Id] = edge;
                    if (_isInQueue[edge.To.Id])
                        continue;

                    _isInQueue[edge.To.Id] = true;
                    _bestPathSearchQueue.Enqueue(edge.To);
                }

                _isInQueue[node.Id] = false;
            }
        }

        private int FindFlow()
        {
            var minFlow = int.MaxValue;
            var cur = _bestMoves[_sink.Id];
            while (cur != null)
            {
                var flow = cur.Flow.Remaining;
                if (flow < minFlow)
                    minFlow = flow;

                cur = _bestMoves[cur.From.Id];
            }

            return minFlow;
        }

        private void CommitBestPath(int flow)
        {
            var cur = _bestMoves[_sink.Id];
            while (cur != null)
            {
                TotalCost += cur.Cost;
                cur.Flow.ActualFlow += flow;
                cur.Paired.Flow.ActualFlow -= flow;
                cur = _bestMoves[cur.From.Id];
            }
        }
    }

    internal struct Node
    {
        public int Id { get; set; }
        public override string ToString() => Id.ToString();
    }

    internal struct Flow
    {
        public int ActualFlow { get; set; }
        public int Capacity { get; set; }

        public int Remaining => Capacity - ActualFlow;
        public bool Filled => ActualFlow == Capacity;
    }

    internal sealed class Edge
    {
        public Node From { get; set; }

        public Node To { get; set; }

        public int Cost { get; set; }
        public Edge Paired { get; set; }
        public Flow Flow;
    }
}


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

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var memberHomes = Console.ReadLine().Split().Select(int.Parse);
            var graph = ReadGraph(n, m, k);

            var solver = new Solver(n, m, k, c, d);
            solver.Init(graph);

            foreach (var memberHomeId in memberHomes)
                solver.AddDiscontentForMember(memberHomeId);

            Console.WriteLine(solver.Discontent);
        }

        private static GraphNode[] ReadGraph(int n, int m, int k)
        {
            var graph = new GraphNode[n + 1];
            for (var i = 1; i <= n; i++)
                graph[i] = new GraphNode() { Id = i, Edges = new List<Edge>(m) };

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = graph[int.Parse(xy[0])];
                var y = graph[int.Parse(xy[1])];

                var edgeXy = new Edge() {To = y, PeopleByTime = new TimeInfo(k)};
                var edgeYx = new Edge() {To = x, PeopleByTime = new TimeInfo(k)};
                edgeXy.Paired = edgeYx;
                edgeYx.Paired = edgeXy;

                x.Edges.Add(edgeXy);
                y.Edges.Add(edgeYx);
            }

            return graph;
        }
    }

    internal sealed class Solver
    {
        private static readonly MoveInfo FakeBestMove = new MoveInfo() {Discontent = int.MaxValue};

        private readonly int _n, _c, _d, _maxTime;
        private readonly MoveInfo[,] _optimalMoves;
        private readonly Queue<MoveInfoWithStartTime> _recalculateQueue;

        public Solver(int n, int m, int k, int c, int d)
        {
            _n = n + 1;
            _maxTime = m + k + 1;
            _c = c;
            _d = d;
            _optimalMoves = new MoveInfo[_n, _maxTime];
            _recalculateQueue = new Queue<MoveInfoWithStartTime>(_optimalMoves.Length);
        }

        public int Discontent { get; private set; }

        public void Init(GraphNode[] graph)
        {
            var optimalPaths = CalculateInitialMoves(graph);
            for (var i = 1; i < graph.Length; i++)
            {
                var baseMove = optimalPaths[i];
                for (var startTime = 0; startTime < _maxTime; startTime++)
                {
                    _optimalMoves[i, startTime] = new MoveInfo()
                    {
                        Edge = baseMove.Edge,
                        Discontent = baseMove.Discontent,
                        Time = startTime,
                    };
                }
            }
        }

        public void AddDiscontentForMember(int homeId)
        {
            var optimalMove = _optimalMoves[homeId, 0];
            Discontent += optimalMove.Discontent;

            while (true)
            {
                ++optimalMove.Edge.PeopleByTime[optimalMove.Time];

                RecalculateDiscontents(optimalMove.Edge, optimalMove.Time);
                if (optimalMove.Edge.To.Id == 1)
                    return;

                optimalMove = _optimalMoves[optimalMove.Edge.To.Id, optimalMove.Time + 1];
            }
        }

        private void RecalculateDiscontents(Edge edge, int time)
        {
            EnqueueMovesThatTargetExactEdge(edge, time);

            while (_recalculateQueue.Count > 0)
            {
                var moveInfoWithStartTime = _recalculateQueue.Dequeue();
                var invalidatedMove = moveInfoWithStartTime.MoveInfo;
                var sourceNode = invalidatedMove.Edge.Paired.To;

                var bestMove = FindBestMoveInfo(sourceNode, moveInfoWithStartTime.StartTime);
                _optimalMoves[sourceNode.Id, moveInfoWithStartTime.StartTime] = bestMove;

                if (bestMove.Discontent != invalidatedMove.Discontent && moveInfoWithStartTime.StartTime != 0)
                    EnqueueMovesThatTargetExactNode(sourceNode, moveInfoWithStartTime.StartTime - 1);
            }
        }

        private MoveInfo FindBestMoveInfo(GraphNode sourceNode, int startTime)
        {
            var bestMove = FakeBestMove;

            for (int moveTime = startTime, waitDiscontent = _c;
                moveTime < _maxTime - 1;
                moveTime++, waitDiscontent += _c)
            {
                foreach (var canGoToEdge in sourceNode.Edges)
                {
                    var discontent = waitDiscontent +
                                     CalculateDComponent(canGoToEdge.PeopleByTime[moveTime], _d) +
                                     _optimalMoves[canGoToEdge.To.Id, moveTime + 1].Discontent;

                    if (discontent < bestMove.Discontent)
                        bestMove = new MoveInfo() {Edge = canGoToEdge, Time = moveTime, Discontent = discontent,};
                }
            }

            return bestMove;
        }

        private void EnqueueMovesThatTargetExactEdge(Edge edge, int time)
        {
            var sourceId = edge.Paired.To.Id;
            for (var t = 0; t <= time; t++)
            {
                var moveInfo = _optimalMoves[sourceId, t];
                if (moveInfo.Edge == edge && moveInfo.Time == time)
                    _recalculateQueue.Enqueue(new MoveInfoWithStartTime() { MoveInfo = moveInfo, StartTime = t });
            }
        }

        private void EnqueueMovesThatTargetExactNode(GraphNode toNode, int time)
        {
            foreach (var nodeId in toNode.Edges.Select(it => it.To.Id))
            {
                for (var t = 0; t <= time; t++)
                {
                    var moveInfo = _optimalMoves[nodeId, t];
                    if (moveInfo.Edge.To.Id == toNode.Id && moveInfo.Time == time)
                        _recalculateQueue.Enqueue(new MoveInfoWithStartTime() { MoveInfo = moveInfo, StartTime = t });
                }
            }
        }

        private MoveInfo[] CalculateInitialMoves(GraphNode[] graph)
        {
            var optimalPaths = new MoveInfo[_n];
            var queue = new Queue<GraphNode>(optimalPaths.Length);

            optimalPaths[1] = new MoveInfo() {Edge = GetFakeEdge(graph[1]),};
            queue.Enqueue(graph[1]);

            var moveCost = _c + _d;

            while (queue.Count > 0)
            {
                var node = queue.Dequeue();
                var nextNodeDiscontent = optimalPaths[node.Id].Discontent + moveCost;

                foreach (var edge in node.Edges)
                {
                    var existingPath = optimalPaths[edge.To.Id];
                    if (existingPath != null && existingPath.Discontent <= nextNodeDiscontent)
                        continue;

                    optimalPaths[edge.To.Id] = new MoveInfo()
                    {
                        Edge = edge.Paired,
                        Discontent = nextNodeDiscontent,
                    };

                    queue.Enqueue(edge.To);
                }
            }

            return optimalPaths;
        }

        private static int CalculateDComponent(int people, int d)
        {
            var oldValue = people * people * d;
            ++people;
            var newValue = people * people * d;
            return newValue - oldValue;
        }

        private static Edge GetFakeEdge(GraphNode to)
        {
            var edge = new Edge() {To = to, PeopleByTime = new TimeInfo(1)};
            edge.Paired = edge;
            return edge;
        }

        private struct MoveInfoWithStartTime
        {
            public MoveInfo MoveInfo { get; set; }
            public int StartTime { get; set; }
        }
    }

    internal sealed class GraphNode : IEquatable<GraphNode>
    {
        public int Id { get; set; }

        public List<Edge> Edges { get; set; }

        public bool Equals(GraphNode other) => Id == other?.Id;

        public override bool Equals(object obj) => obj is GraphNode graphNode && graphNode.Id == Id;

        public override int GetHashCode() => Id;
    }

    internal sealed class Edge
    {
        public GraphNode To { get; set; }
        public Edge Paired { get; set; }
        public TimeInfo PeopleByTime { get; set; }
    }

    internal sealed class TimeInfo
    {
        private readonly Dictionary<int, PeopleCount> _peopleCounts;

        public TimeInfo(int capacity) => _peopleCounts = new Dictionary<int, PeopleCount>(capacity);

        public PeopleCount this[int time]
        {
            get
            {
                _peopleCounts.TryGetValue(time, out var count);
                return count;
            }

            set => _peopleCounts[time] = value;
        }
    }

    internal struct PeopleCount
    {
        public int Value { get; set; }
        public static implicit operator PeopleCount(int v) => new PeopleCount() {Value = v};
        public static implicit operator int(PeopleCount v) => v.Value;
    }

    internal sealed class MoveInfo
    {
        public Edge Edge { get; set; }

        public int Time { get; set; }

        public int Discontent { get; set; }
    }
}


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

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var memberHomes = Console.ReadLine().Split().Select(int.Parse);
            var graph = ReadGraph(n, m, k);

            var solver = new Solver(n, m, k, c, d);
            solver.Init(graph);

            foreach (var memberHome in memberHomes)
                solver.AddDiscontentForMember(graph[memberHome]);

            Console.WriteLine(solver.Discontent);
        }

        private static GraphNode[] ReadGraph(int n, int m, int k)
        {
            var graph = new GraphNode[n + 1];
            for (var i = 1; i <= n; i++)
                graph[i] = new GraphNode() { Id = i, Edges = new List<Edge>(m) };

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = graph[int.Parse(xy[0])];
                var y = graph[int.Parse(xy[1])];

                var edgeXy = new Edge() {To = y, PeopleByTime = new TimeInfo(k)};
                var edgeYx = new Edge() {To = x, PeopleByTime = new TimeInfo(k)};
                edgeXy.Paired = edgeYx;
                edgeYx.Paired = edgeXy;

                x.Edges.Add(edgeXy);
                y.Edges.Add(edgeYx);
            }

            return graph;
        }
    }

    internal sealed class Solver
    {
        private static readonly MoveInfo FakeBestMove = new MoveInfo() {Discontent = int.MaxValue};

        private readonly int _n, _m, _k, _c, _d, _cPlusD, _mPlusK;
        private readonly MoveInfo[,] _optimalMoves;
        private readonly Queue<MoveInfoWithStartTime> _recalculateQueue;

        public Solver(int n, int m, int k, int c, int d)
        {
            _n = n;
            _m = m;
            _k = k;
            _c = c;
            _d = d;
            _cPlusD = c + d;
            _mPlusK = m + k;
            _optimalMoves = new MoveInfo[n + 1, _mPlusK];
            _recalculateQueue = new Queue<MoveInfoWithStartTime>(_optimalMoves.Length);
        }

        public int Discontent { get; private set; }

        public void Init(GraphNode[] graph)
        {
            var optimalPaths = CalculateInitialPaths(graph);
            for (var i = 1; i < graph.Length; i++)
            {
                var baseMove = optimalPaths[i];
                for (var startTime = 0; startTime < _m + _k; startTime++)
                {
                    _optimalMoves[i, startTime] = new MoveInfo()
                    {
                        Edge = baseMove.Edge,
                        Discontent = baseMove.Discontent,
                        Time = startTime,
                    };
                }
            }
        }

        public void AddDiscontentForMember(GraphNode home)
        {
            var optimalMove = _optimalMoves[home.Id, 0];
            Discontent += optimalMove.Discontent;

            while (true)
            {
                ++optimalMove.Edge.PeopleByTime[optimalMove.Time];
                RecalculateDiscontents(optimalMove.Edge, optimalMove.Time);
                if (optimalMove.Edge.To.Id == 1)
                    return;

                optimalMove = _optimalMoves[optimalMove.Edge.To.Id, optimalMove.Time + 1];
            }
        }

        private void RecalculateDiscontents(Edge edge, int time)
        {
            EnqueueMovesThatTargetExactEdge(edge, time);

            while (_recalculateQueue.Count > 0)
            {
                var moveInfoWithStartTime = _recalculateQueue.Dequeue();
                var invalidMove = moveInfoWithStartTime.MoveInfo;
                var sourceNode = invalidMove.Edge.Paired.To;

                var bestMove = FakeBestMove;

                for (int t = moveInfoWithStartTime.StartTime, waitDiscontent = _c;
                    t < _k + _m - 1;
                    t++, waitDiscontent += _c)
                {
                    foreach (var canGoToEdge in sourceNode.Edges)
                    {
                        var discontent = waitDiscontent +
                                         CalculateDComponent(canGoToEdge.PeopleByTime[t] + 1, _d) +
                                         _optimalMoves[canGoToEdge.To.Id, t + 1].Discontent;

                        if (discontent < bestMove.Discontent)
                            bestMove = new MoveInfo() {Edge = canGoToEdge, Time = t, Discontent = discontent,};
                    }
                }

                _optimalMoves[sourceNode.Id, moveInfoWithStartTime.StartTime] = bestMove;

                if (bestMove.Discontent != invalidMove.Discontent)
                    EnqueueMovesThatTargetExactNode(sourceNode, moveInfoWithStartTime.StartTime - 1);
            }
        }

        private void EnqueueMovesThatTargetExactEdge(Edge edge, int time)
        {
            var sourceId = edge.Paired.To.Id;
            for (var t = 0; t <= time; t++)
            {
                var moveInfo = _optimalMoves[sourceId, t];
                if (moveInfo.Edge == edge && moveInfo.Time == time)
                    _recalculateQueue.Enqueue(new MoveInfoWithStartTime() { MoveInfo = moveInfo, StartTime = t });
            }
        }

        private void EnqueueMovesThatTargetExactNode(GraphNode toNode, int time)
        {
            foreach (var nodeId in toNode.Edges.Select(it => it.To.Id))
            {
                for (var t = 0; t <= time; t++)
                {
                    var moveInfo = _optimalMoves[nodeId, t];
                    if (moveInfo.Edge.To.Id == toNode.Id && moveInfo.Time == time)
                        _recalculateQueue.Enqueue(new MoveInfoWithStartTime() { MoveInfo = moveInfo, StartTime = t });
                }
            }
        }

        private MoveInfo[] CalculateInitialPaths(GraphNode[] graph)
        {
            var optimalPaths = new MoveInfo[_n + 1];
            var queue = new Queue<GraphNode>(optimalPaths.Length);

            optimalPaths[1] = new MoveInfo() {Edge = GetFakeEdge(graph[1]),};
            queue.Enqueue(graph[1]);

            while (queue.Count > 0)
            {
                var node = queue.Dequeue();
                var nextNodeDiscontent = optimalPaths[node.Id].Discontent + _cPlusD;

                foreach (var edge in node.Edges)
                {
                    var existingPath = optimalPaths[edge.To.Id];
                    if (existingPath != null && existingPath.Discontent <= nextNodeDiscontent)
                        continue;

                    optimalPaths[edge.To.Id] = new MoveInfo()
                    {
                        Edge = edge.Paired,
                        Discontent = nextNodeDiscontent,
                    };

                    queue.Enqueue(edge.To);
                }
            }

            return optimalPaths;
        }

        private static int CalculateDComponent(PeopleCount people, int d) => people * people * d;

        private static Edge GetFakeEdge(GraphNode to)
        {
            var edge = new Edge() {To = to, PeopleByTime = new TimeInfo(1)};
            edge.Paired = edge;
            return edge;
        }

        private struct MoveInfoWithStartTime
        {
            public MoveInfo MoveInfo { get; set; }
            public int StartTime { get; set; }
        }
    }

    internal sealed class GraphNode : IEquatable<GraphNode>
    {
        public int Id { get; set; }

        public List<Edge> Edges { get; set; }

        public bool Equals(GraphNode other) => Id == other?.Id;

        public override bool Equals(object obj) => obj is GraphNode graphNode && graphNode.Id == Id;

        public override int GetHashCode() => Id;
    }

    internal sealed class Edge
    {
        public GraphNode To { get; set; }
        public Edge Paired { get; set; }
        public TimeInfo PeopleByTime { get; set; }
    }

    internal sealed class TimeInfo
    {
        private readonly Dictionary<int, PeopleCount> _peopleCounts;

        public TimeInfo(int capacity) => _peopleCounts = new Dictionary<int, PeopleCount>(capacity);

        public PeopleCount this[int time]
        {
            get
            {
                _peopleCounts.TryGetValue(time, out var count);
                return count;
            }

            set => _peopleCounts[time] = value;
        }
    }

    internal struct PeopleCount
    {
        public int Value { get; set; }
        public static implicit operator PeopleCount(int v) => new PeopleCount() {Value = v};
        public static implicit operator int(PeopleCount v) => v.Value;
    }

    internal sealed class MoveInfo
    {
        public Edge Edge { get; set; }

        public int Time { get; set; }

        public int Discontent { get; set; }
    }
}


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

namespace G.GangUp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var nmkcd = Console.ReadLine().Split();
            var n = int.Parse(nmkcd[0]);
            var m = int.Parse(nmkcd[1]);
            var k = int.Parse(nmkcd[2]);
            var c = int.Parse(nmkcd[3]);
            var d = int.Parse(nmkcd[4]);

            var memberHomes = Console.ReadLine().Split().Select(int.Parse);
            var graph = ReadGraph(n, m, k);
            FindPathLengths(graph);

            var solver = new Solver(n, c, d);

            foreach (var memberHome in memberHomes)
                solver.AddDiscontentForMember(graph[memberHome]);

            Console.WriteLine(solver.Discontent);
        }

        private static GraphNode[] ReadGraph(int n, int m, int k)
        {
            ++k;

            var graph = new GraphNode[n + 1];
            for (var i = 1; i <= n; i++)
                graph[i] = new GraphNode(i, m);

            for (var i = 0; i < m; i++)
            {
                var xy = Console.ReadLine().Split();
                var x = graph[int.Parse(xy[0])];
                var y = graph[int.Parse(xy[1])];

                x.Edges.Add(new Edge() { Node = y, TimeInfo = new TimeInfo(k) });
                y.Edges.Add(new Edge() { Node = x, TimeInfo = new TimeInfo(k) });
            }

            return graph;
        }

        private static void FindPathLengths(GraphNode[] graph)
        {
            var queue = new Queue<GraphNode>(graph.Length);

            var node = graph[1];
            node.PathLength = 0;
            queue.Enqueue(node);

            while (queue.Count > 0)
            {
                node = queue.Dequeue();
                var newPathLength = node.PathLength + 1;

                foreach (var neighbour in node.Edges.Select(it => it.Node))
                {
                    if (neighbour.PathLength <= newPathLength)
                        continue;

                    neighbour.PathLength = newPathLength;
                    queue.Enqueue(neighbour);
                }
            }
        }
    }

    internal sealed class Solver
    {
        private readonly int _c, _d, _cPlusD;
        private readonly EdgeIndexWithTime[] _bestPath;

        private int _currentBestDiscontent, _bestPathLength;

        public Solver(int n, int c, int d)
        {
            _c = c;
            _d = d;
            _cPlusD = c + d;
            _bestPath = new EdgeIndexWithTime[n + 1];
        }

        public int Discontent { get; private set; }

        public void AddDiscontentForMember(GraphNode home)
        {
            _currentBestDiscontent = int.MaxValue;
            TryOptimize(home, 0, 0, 0);
            CommitBestPath(home);
            Discontent += _currentBestDiscontent;
        }

        private bool TryOptimize(GraphNode node, int time, int baseDiscontent, int bestPathIndex)
        {
            if (node.Id == 1)
            {
                if (baseDiscontent >= _currentBestDiscontent)
                    return false;

                _bestPathLength = bestPathIndex;
                _currentBestDiscontent = baseDiscontent;
                return true;
            }

            node.AlreadyInCurrentPath = true;

            var optimized = false;

            var nextBestPathIndex = bestPathIndex + 1;

            for (var idealContinuationDiscontent = baseDiscontent + node.PathLength * _cPlusD;
                idealContinuationDiscontent < _currentBestDiscontent;
                idealContinuationDiscontent += _c, ++time)
            {
                var nextTime = time + 1;
                baseDiscontent += _c;

                for (var edgeIndex = 0; edgeIndex < node.Edges.Count; edgeIndex++)
                {
                    var edge = node.Edges[edgeIndex];

                    var neighbour = edge.Node;
                    if (neighbour.AlreadyInCurrentPath)
                        continue;

                    var nextBaseDiscontent = baseDiscontent +
                                             CalculateDiscontentChange(edge.TimeInfo[time]);

                    if (!TryOptimize(neighbour, nextTime, nextBaseDiscontent, nextBestPathIndex))
                        continue;

                    _bestPath[bestPathIndex] = new EdgeIndexWithTime() {EdgeIndex = edgeIndex, Time = time};
                    optimized = true;
                }
            }

            node.AlreadyInCurrentPath = false;
            return optimized;
        }

        private void CommitBestPath(GraphNode current)
        {
            foreach (var edgeIndexWithTime in _bestPath.Take(_bestPathLength))
            {
                var edge = current.Edges[edgeIndexWithTime.EdgeIndex];
                ++edge.TimeInfo[edgeIndexWithTime.Time];
                current = edge.Node;
            }
        }

        private int CalculateDiscontentChange(int peopleWalkingTheSameTime)
        {
            var oldDiscontentD = peopleWalkingTheSameTime * peopleWalkingTheSameTime * _d;
            ++peopleWalkingTheSameTime;
            var newDiscontentD = peopleWalkingTheSameTime * peopleWalkingTheSameTime * _d;
            return newDiscontentD - oldDiscontentD;
        }

        private struct EdgeIndexWithTime
        {
            public int EdgeIndex { get; set; }
            public int Time { get; set; }
        }
    }

    internal sealed class GraphNode : IEquatable<GraphNode>
    {
        public GraphNode(int id, int m)
        {
            Id = id;
            Edges = new List<Edge>(m);
        }

        public int Id { get; }

        public int PathLength { get; set; } = 1000;

        public bool AlreadyInCurrentPath { get; set; }

        public List<Edge> Edges { get; }

        public bool Equals(GraphNode other) => Id == other?.Id;

        public override bool Equals(object obj) => obj is GraphNode graphNode && graphNode.Id == Id;

        public override int GetHashCode() => Id;
    }

    internal struct TimeInfo
    {
        private readonly int[] _peopleCounts;

        public TimeInfo(int capacity) { _peopleCounts = new int[capacity]; }

        public int this[int time]
        {
            get => _peopleCounts[time];
            set => _peopleCounts[time] = value;
        }
    }

    internal struct Edge
    {
        public GraphNode Node;
        public TimeInfo TimeInfo;
    }
}


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

namespace codeforces
{

    public class Program
    {
        private const int MOD = 1000 * 1000 * 1000 + 7;
        private const int NMax = 1000;

        private static int k;
        private static int pA;
        private static int pB;
        private static int ipB;
        private static int[,] dp = new int[NMax, NMax];
        private static bool[,] marked = new bool[NMax, NMax];

        private static int Add(int a, int b)
        {
            a += b;
            if (a >= MOD)
            {
                a -= MOD;
            }
            return a;
        }

        private static int Mult(int a, int b)
        {
            return (int)(1L * a * b % MOD);
        }

        private static int BinPow(int a, int n)
        {
            int result = 1;
            while (n > 0)
            {
                if (n % 2 == 1)
                {
                    result = Mult(result, a);
                }
                a = Mult(a, a);
                n /= 2;
            }
            return result;
        }

        private static int Solve(int count, int tk)
        {
            if (tk >= k)
            {
                return tk;
            }
            if (count + tk >= k)
            {
                return Add(Add(count, tk), ipB);
            }
            if (marked[count, tk])
            {
                return dp[count, tk];
            }
            marked[count, tk] = true;
            dp[count, tk] = Add(Mult(Solve(count + 1, tk), pA), Mult(Solve(count, tk + count), pB));
            return dp[count, tk];
        }

        private static void Main(string[] args)
        {
            var values = Console.ReadLine().Split(' ');
            k = Convert.ToInt32(values[0]);
            int pa = Convert.ToInt32(values[1]);
            int pb = Convert.ToInt32(values[2]);
            pA = Mult(pa, BinPow(Add(pa, pb), MOD - 2));
            pB = Mult(pb, BinPow(Add(pa, pb), MOD - 2));
            ipB = Mult(pa, BinPow(pb, MOD - 2));
            Console.WriteLine(Solve(1, 0));
        }
    }
}


using System;
using System.Linq;
using System.Collections.Generic;
using System.Numerics;
using Debug = System.Diagnostics.Debug;
using SB = System.Text.StringBuilder;
using Number = System.Int64;
using KV = System.Collections.Generic.KeyValuePair<int, long>;
namespace Program {
    public class Solver {
        public void Solve() {
            var k = ri;
            var pa = ri;
            var pb = ri;
            var p = pa * ModInt.Inverse(pa + pb);

            var q = pb * ModInt.Inverse(pa + pb);
            var invq = ModInt.Inverse(q);
            var dp = new ModInt[k + 5, k + 5];
            for (int i = 0; i < k + 5; i++)
                for (int j = 0; j < k + 5; j++)
                    dp[i, j].num = -1;
            Func<int, int, ModInt> dfs = null;
            dfs = (a, cnt) => {
                if (cnt >= k) return cnt;
                if (a + cnt >= k) {
                    return cnt + a + invq - 1;
                }
                if (dp[a, cnt].num != -1) return dp[a, cnt];
                ModInt ret = new ModInt(0);
                // a を出す
                ret += p * dfs(a + 1, cnt);
                // b を出す
                ret += q * dfs(a, cnt + a);

                return dp[a, cnt] = ret;
            };
            Console.WriteLine(dfs(1, 0));

        }
        const long INF = 1L << 60;
        int[] dx = { -1, 0, 1, 0 };
        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 < n; ++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.Select(x => x.ToString()).ToArray());
        //return string.Join(st, ie);
    }

    static public void Main() {
        Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
        var solver = new Program.Solver();
        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

#region ModInt
public struct ModInt {
    public const long Mod = (long)1e9 + 7;
    public long num;
    public ModInt(long n) { num = n; }
    public override string ToString() { return num.ToString(); }
    public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
    public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
    public static ModInt operator *(ModInt l, ModInt r) { return new ModInt((int)(l.num * r.num % Mod)); }
    public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }
    public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }
    public static ModInt Pow(long v, long k) {
        long ret = 1;
        for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
            if ((k & 1) == 1) ret = ret * v % Mod;
        return new ModInt(ret);
    }
    public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
}
#endregion


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

namespace Mysterious_numbers
{
    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 void Main(string[] args)
        {
            string[] ss = reader.ReadLine().Split(' ');

            int n = int.Parse(ss[0]);
            int k = int.Parse(new string(ss[1].Reverse().ToArray()));

            writer.WriteLine(n + k);
            writer.Flush();
        }
    }
}


using System;
// you can also use other imports, for example:
using System.Collections.Generic;
using System.Linq;

// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");

//mcs HelloWorld.cs
//mono HelloWorld.exe
public class HelloWorld {

	public static void Main(string[] args)
	{
		var line  = Console.ReadLine().Split(' ');
		var a = Convert.ToInt32(line[0]);
		var b = Convert.ToInt32(line[1]);
		solve(a,b);
		//tests();
	}

	public static void tests()
	{
		solve(3, 14);
		solve(27, 12);
		solve(100, 200);
		solve(31415,92653); //67044
	}

	public static void solve(int a, int b)
	{
		var rev = reverse(b);

		Console.WriteLine(a+rev);

	}

	public static int reverse(int n)
	{
		var rev = 0;
		while (n > 0)
		{
			rev = rev * 10 + n % 10;
			n = n / 10;
		}
		return rev;
	}

}


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

namespace Comp1
{
    class TaskA
    {
        static void Main(string[] args)
        {

            long a, b;
            string str;
            string[] s = new string[2];
            str = Console.ReadLine();
            s = str.Split();
            a = long.Parse(s[0]);
            char[] arr = s[1].ToCharArray();
            Array.Reverse(arr);
            string ss = new string(arr);
            b = long.Parse(ss);

            Console.WriteLine(a + b);
        }
    }
}


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

namespace Codeforces
{
#if _ONLINE_JUDGE_
	[OnlineJudge.Task("Codeforces 171A")]
#endif
	class Task171A
	{
		private InputTokenizer input = new InputTokenizer();
		private TextWriter output = Console.Out;

		private void Solve()
		{
			string n, m;
			input.Line().Read(out n).Read(out m);
			output.WriteLine(int.Parse(n) + int.Parse(new String(m.Reverse().ToArray())));
		}

		public static void Main()
		{
			var obj = new Task171A();
			obj.Solve();
		}

		#region
		private class InputTokenizer
		{
			private List<string> _tokens = new List<string>();
			private int _offset = 0;

			public InputTokenizer()
			{
			}

			public InputTokenizer String(String s)
			{
				_tokens.AddRange(s.Split(new char[] { ' ', '\n', '\t', '\r' }, StringSplitOptions.RemoveEmptyEntries));
				return this;
			}

			public InputTokenizer Line()
			{
				return String(Console.In.ReadLine());
			}

			public InputTokenizer Read(out int v)
			{
				v = int.Parse(_tokens[_offset++]);
				return this;
			}

			public InputTokenizer Read(int n, out int[] v)
			{
				v = new int[n];
				for (int i = 0; i < n; ++i) Read(out v[i]);
				return this;
			}

			public InputTokenizer Read(out long v)
			{
				v = long.Parse(_tokens[_offset++]);
				return this;
			}

			public InputTokenizer Read(int n, out long[] v)
			{
				v = new long[n];
				for (int i = 0; i < n; ++i) Read(out v[i]);
				return this;
			}

			public InputTokenizer Read(out ulong v)
			{
				v = ulong.Parse(_tokens[_offset++]);
				return this;
			}

			public InputTokenizer Read(int n, out ulong[] v)
			{
				v = new ulong[n];
				for (int i = 0; i < n; ++i) Read(out v[i]);
				return this;
			}

			public InputTokenizer Read(out double v)
			{
				v = double.Parse(_tokens[_offset++].Replace('.', ','));
				return this;
			}

			public InputTokenizer Read(int n, out double[] v)
			{
				v = new double[n];
				for (int i = 0; i < n; ++i) Read(out v[i]);
				return this;
			}

			public InputTokenizer Read(out string v)
			{
				v = _tokens[_offset++];
				return this;
			}

			public InputTokenizer Read(int n, out string[] v)
			{
				v = new string[n];
				for (int i = 0; i < n; ++i) Read(out v[i]);
				return this;
			}
		}
		#endregion
	}
}


using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        string[] inp = Console.ReadLine().Split(' ');
        char[] s = inp[0].ToCharArray();
        char[] b = inp[1].ToCharArray();
        for (int i = 0; i <= b.GetUpperBound(0)/2; i++)
        {
            char swap = b[i];
            b[i] = b[b.GetUpperBound(0) - i];
            b[b.GetUpperBound(0) - i] = swap;
        }
        string a = "";
        string g = "";
        for (int i = 0; i <= b.GetUpperBound(0); i++)
        {
            a += b[i];
        }
        for (int i = 0; i <= s.GetUpperBound(0); i++)
        {
            g += s[i];
        }
        int outy = int.Parse(a) + int.Parse(g);
        Console.WriteLine(outy);
    }
}


using System; using System.Linq;

class P {
  static void Main(){
    var s = Console.ReadLine().Split(' ');
    var res = long.Parse(s[0]) + long.Parse(new string(s[1].Reverse().ToArray()));
    Console.Write(res);
  }
}


using System;
 class Program
    {
        public static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
            char[] data = input[1].ToCharArray();
            {
                char temp;
                for (int i = data.Length - 1, j = 0, lim = data.Length / 2; j < lim; ++j, --i)
                {
                    temp = data[i];
                    data[i] = data[j];
                    data[j] = temp;
                }
            }
            Console.WriteLine((int.Parse(input[0])+int.Parse(new string(data))));
        }
    }


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

namespace TaskA
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            string[] inpvals = input.Split(' ');
            int a = int.Parse(inpvals[0]);
            int b = 0;
            if (inpvals[1] != "0")
            {
                List<char> brr = inpvals[1].ToList<char>();
                brr.Reverse();

                int zc = 0;
                while (brr[zc] == '0') zc++;
                StringBuilder srtb = new StringBuilder(brr.Count - zc);
                for (int i = zc; i < brr.Count; i++)
                {
                    srtb.Append(brr[i]);
                }

                if (srtb.Length > 0)
                {
                    b = int.Parse(srtb.ToString());
                }
            }
            Console.WriteLine(a + b);
        }
    }
}


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

namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] str = Console.ReadLine().Split(' ');
            string h = str[0];
            string h1 = str[1];
            string h2 = "";
            for (int i = h1.Length - 1; i >= 0; i--)
            {
                h2 = h2 + h1[i];
            }
            long a = Int64.Parse(h);
            long b = Int64.Parse(h2);
            Console.WriteLine(a + b);
        }
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using System.Linq;

namespace Codeforces
{
    internal class Program
    {
        private const string Test = "D1";

        private static void Solve()
        {
            var input = ReadIntArray();
            var a = input[0];
            var b = input[1];
            var res = 0;
            while (b >= 1)
            {
                res = res*10 + (b%10);
                b/=10;
            }
            res += a;
            Console.WriteLine(res);
        }

        private static void Main()
        {
            if (Debugger.IsAttached)
            {
                Console.SetIn(new StreamReader(String.Format(@"..\..\..\..\Tests\{0}.in", Test)));
            }

            Solve();

            if (Debugger.IsAttached)
            {
                Console.In.Close();
                Console.SetIn(new StreamReader(Console.OpenStandardInput()));
                Console.ReadLine();
            }
        }

        #region Reader

        private static string Read()
        {
            return Console.ReadLine();
        }

        private static string[] ReadArray()
        {
            return Console.ReadLine().Split(' ');
        }

        private static List<int> ReadIntArray()
        {
            var input = Console.ReadLine().Split(' ').Select(Int32.Parse).ToList();
            return input;
        }

        private static int ReadInt()
        {
            return Int32.Parse(Console.ReadLine());
        }

        private static long ReadLong()
        {
            return long.Parse(Console.ReadLine());
        }

        private static int ReadNextInt(string[] input, int index)
        {
            return Int32.Parse(input[index]);
        }

        #endregion
    }
}


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

namespace ConsoleApplication4
{
    class Program
    {

        static void Main(string[] args)
        {
            string[] ss = Console.ReadLine().Split();
            int n = int.Parse(ss[0]);
            string q = ss[1];
            string w = "";
            for (int i = q.Length - 1; i >= 0; i--)
            {
                w += q[i];
            }
            Console.WriteLine(n+int.Parse(w));
        }
    }
}


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

namespace _158Csharp
{
    class Program
    {
        static void Main(string[] args)
        {
            int n, m;
            string s = Console.ReadLine();
            string[] p = s.Split(new string[] { " " }, StringSplitOptions.None);
            n = Convert.ToInt32(p[0]);
            List<char> ch = new List<char>();

            string ss = p[1];

            for (int i = 0; i < p[1].Length; i++)
                ch.Add(ss[i]);
            ch.Reverse();
            ss = "";
            for (int i = 0; i < ch.Count; i++)
                ss += ch[i];
            //ss = Convert.ToString(ch);
            //Console.WriteLine(ss);
            m = Convert.ToInt32(ss);
            Console.WriteLine(n + m);
        }

    }
}


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

namespace CodeForces
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Split(new char[] {' '});
            int a = Convert.ToInt32(input[0]);

            StringBuilder str = new StringBuilder(input[1]);
            for (int i = 0; i < str.Length / 2; i++)
            {
                char t = str[i];
                str[i] = str[str.Length - 1 - i];
                str[str.Length - 1 - i] = t;
            }

            int b = Convert.ToInt32(str.ToString());
            Console.WriteLine(a + b);
        }
    }
}


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

namespace ConsoleApplication1
{
    class Program
    {
        private static int ReadIntToSpace()
        {
            string temp = "";
            char c = (char)Console.Read();
            while (c != ' ')
            {
                temp += c;
                c = (char)Console.Read();
            }
            return int.Parse(temp);
        }
        static void Main(string[] args)
        {
            int a = ReadIntToSpace();
            int b = int.Parse(Console.ReadLine());
            int i;
            string bb ="";
            for (i = b.ToString().Length-1; i >=0; i--)
            {
                bb += b.ToString()[i];
            }
            Console.WriteLine(a+int.Parse(bb));
            Console.ReadLine();
        }
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;

public class Solver
{
    #region I/O
    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
        #if ONLINE_JUDGE
        reader = Console.In;
        writer = Console.Out;
        #else
        reader = new StreamReader("..\\..\\input.txt");
        writer = new StreamWriter("..\\..\\output.txt");
        #endif
        Solver solver = new Solver();

        try
        {
            object result = solver.Solve();
            if (result != null)
            {
                writer.WriteLine(result);
                Console.Error.WriteLine(result);
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine(ex);
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read helpers

    static Queue<string> currentLineTokens = new Queue<string>();

    public static string ReadToken()
    {
        if (currentLineTokens.Count == 0)
        {
            currentLineTokens = new Queue<string>(reader.ReadLine().Trim().Split(' '));
        }
        return currentLineTokens.Dequeue();
    }

    public static string[] ReadTokens(bool fromCurrentLine = false)
    {
        string[] split;
        if (fromCurrentLine)
        {
            if (currentLineTokens.Count == 0)
                return new string[0];
            split = currentLineTokens.ToArray();
            currentLineTokens.Clear();
        }
        else
        {
            split = reader.ReadLine().Trim().Split(' ');
        }
        return split;
    }

    public static int ReadInt()
    {
        return int.Parse(ReadToken());
    }

    public static long ReadLong()
    {
        return long.Parse(ReadToken());
    }

    public static double ReadDouble()
    {
        return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
    }

    public static int[] ReadIntArray(bool fromCurrentLine = false)
    {
        string[] tokens = ReadTokens(fromCurrentLine);
        return tokens.Select(int.Parse).ToArray();
    }

    public static long[] ReadLongArray(bool fromCurrentLine = false)
    {
        string[] tokens = ReadTokens(fromCurrentLine);
        return tokens.Select(long.Parse).ToArray();
    }

    public static double[] ReadDoubleArray(bool fromCurrentLine = false)
    {
        string[] tokens = ReadTokens(fromCurrentLine);
        return tokens.Select(double.Parse).ToArray();
    }

    public static int[][] ReadIntMatrix(int numberOfRows)
    {
        int[][] matrix = new int[numberOfRows][];
        for (int i = 0; i < numberOfRows; i++)
            matrix[i] = ReadIntArray();
        return matrix;
    }

    public static string[] ReadLines(int quantity)
    {
        string[] lines = new string[quantity];
        for (int i = 0; i < quantity; i++)
        {
            lines[i] = reader.ReadLine().Trim();
        }
        return lines;
    }

    #endregion

    public object Solve()
    {
        long a = ReadLong();
        long b = ReadLong();

        b = long.Parse(new string(b.ToString().Reverse().ToArray()));

        return a + b;
    }
}


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

namespace TaskA
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            string[] inpvals = input.Split(' ');
            int a = int.Parse(inpvals[0]);
            List<char> barr = inpvals[1].ToList<char>();
            barr.Reverse();
            int zercount = 0;
            while (barr[zercount] == '0') zercount++;
            int l = inpvals[1].Length - zercount;
            StringBuilder strb = new StringBuilder(l);
            for (int i = 0; i < l; i++)
            {
                strb.Append(barr[zercount + i]);
            }
            string bs = strb.ToString();
            int b = 0;
            if (bs.Length > 0) b= int.Parse(bs);
            Console.Write(a + b);
        }
    }
}


using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        string[] inp = Console.ReadLine().Split(' ');
        char[] s = inp[0].ToCharArray();
        char[] b = inp[1].ToCharArray();
        for (int i = 0; i <= b.GetUpperBound(0)/2; i++)
        {
            char swap = b[i];
            b[i] = b[b.GetUpperBound(0) - i];
            b[b.GetUpperBound(0) - i] = swap;
        }
        string a = "";
        string g = "";
        for (int i = 0; i <= b.GetUpperBound(0); i++)
        {
            a += b[i];
        }
        for (int i = 0; i <= s.GetUpperBound(0); i++)
        {
            g += s[i];
        }
        int outy = int.Parse(a) + int.Parse(g);
        Console.WriteLine(outy);
        Console.ReadKey();
    }
}


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

namespace CodeForces
{
    class Program
    {
        static void Main(string[] args)
        {
            string a, b;
            a = Console.ReadLine();
            b = Console.ReadLine();

            StringBuilder str = new StringBuilder(b);
            for (int i = 0; i < str.Length / 2; i++)
            {
                char t = str[i];
                str[i] = str[str.Length - 1 - i];
                str[str.Length - 1 - i] = t;
            }

            b = str.ToString();
            Console.WriteLine(Convert.ToInt32(a) + Convert.ToInt32(b));
        }
    }
}


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

namespace TaskA
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            string[] inpvals = input.Split(' ');
            int a = int.Parse(inpvals[0]);
            List<char> barr = inpvals[1].ToList<char>();
            barr.Reverse();
            int zercount = 0;
            while (barr[zercount] == '0') zercount++;
            int l = inpvals[1].Length - zercount;
            StringBuilder strb = new StringBuilder(l);
            for (int i = 0; i < l; i++)
            {
                strb.Append(barr[zercount + i]);
            }
            int b = int.Parse(strb.ToString());
            Console.Write(a + b);
        }
    }
}


using System;
using System.Collections.Generic;

class Program
{
static void Main()
{
string[] inp = Console.ReadLine().Split(' ');
char[] s = inp[0].ToCharArray();
char[] b = inp[1].ToCharArray();
for (int i = 0; i <= b.GetUpperBound(0); i++)
{
char swap = b[i];
b[i] = b[b.GetUpperBound(0) - i];
b[b.GetUpperBound(0)-i] = swap;
}
int outy = int.Parse(s.ToString()) + int.Parse(b.ToString());
Console.WriteLine(outy);
}
}


using System;
// you can also use other imports, for example:
using System.Collections.Generic;
using System.Linq;

// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");

//mcs HelloWorld.cs
//mono HelloWorld.exe
public class HelloWorld {

	public static void Main(string[] args)
	{
		var line  = Console.ReadLine().Split(' ');
		var a = Convert.ToInt32(line[0]);
		var b = Convert.ToInt32(line[1]);
		solve(a,b);
		//tests();
	}

	public static void tests()
	{
		solve(3, 14);
		solve(27, 12);
		solve(100, 200);
	}

	public static void solve(int a, int b)
	{
		var ast = a.ToString();
		var bst = b.ToString();
		if (ast.Length > bst.Length)
		{
			bst = bst.PadLeft(ast.Length,'0');
		}
		if (bst.Length > ast.Length)
		{
			ast = ast.PadLeft(bst.Length, '0');
		}
		var res = "";
		var n = ast.Length - 1;
		//Console.WriteLine(ast + " " + bst);
		for (var i = 0; i <= n; i++)
		{
			res += (char.GetNumericValue(ast[i]) + char.GetNumericValue(bst[n-i])).ToString();
		}

		Console.WriteLine(res);

	}

}


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

namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] str = Console.ReadLine().Split(' ');
            string h = str[0];
            string h1 = str[1];
            if (h.Length != h1.Length)
            {
                if (h.Length < h1.Length)
                {
                    string q = h;
                    h = q;
                }
                long qwe = h.Length - h1.Length;
                for (int i = 0; i < qwe; i++)
                {
                    h1 = "0" + h1;
                }
            }
            string h2 = "";
            for (int i = h1.Length - 1; i >= 0; i--)
            {
                h2 = h2 + h1[i];
            }
            Console.WriteLine(Int64.Parse(h) + Int64.Parse(h2));
        }
    }
}


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

namespace _158Csharp
{
    class Program
    {
        static void Main(string[] args)
        {
            //int n, m;
            string s = Console.ReadLine();
            //string[] p = s.Split(new string[] { " " }, StringSplitOptions.None);
            Console.WriteLine(44);

        }

    }
}


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

namespace AprilFools
{
    internal class Program
    {
        private const string TestIn = @"..\..\In\Text.in";
        private const string TestOut = @"..\..\In\Text.out";

        private static void Solve()
        {
            var input = ReadArray();
            var res = Convert.ToInt32(input[0]);

            var r2 = Convert.ToInt32(string.Join("", input[1].ToCharArray().Reverse().ToArray()));

            Console.WriteLine(res+r2);
        }

        private static void Main()
        {
            if (Debugger.IsAttached)
            {
                Console.SetIn(new StreamReader(TestIn));
                Console.SetOut(new StreamWriter(TestOut));
            }

            Solve();

            if (Debugger.IsAttached)
            {
                Console.In.Close();
                Console.Out.Close();
                Console.SetIn(new StreamReader(Console.OpenStandardInput()));
                Console.ReadLine();
            }
        }

        #region Reader

        private static string Read()
        {
            return Console.ReadLine();
        }

        private static string[] ReadArray()
        {
            return Console.ReadLine().Split(' ');
        }

        private static List<int> ReadIntArray()
        {
            var input = Console.ReadLine().Split(' ').Select(Int32.Parse).ToList();
            return input;
        }

        private static int ReadInt()
        {
            return Int32.Parse(Console.ReadLine());
        }

        private static long ReadLong()
        {
            return long.Parse(Console.ReadLine());
        }

        private static int ReadNextInt(string[] input, int index)
        {
            return Int32.Parse(input[index]);
        }

        #endregion
    }
}