Arnie the Worm has finished eating an apple house yet again and decided to move. He made up his mind on the plan, the way the rooms are located and how they are joined by corridors. He numbered all the rooms from 1 to n. All the corridors are bidirectional.

Arnie wants the new house to look just like the previous one. That is, it should have exactly n rooms and, if a corridor from room i to room j existed in the old house, it should be built in the new one. 

We know that during the house constructing process Arnie starts to eat an apple starting from some room and only stops when he eats his way through all the corridors and returns to the starting room. It is also known that Arnie eats without stopping. That is, until Arnie finishes constructing the house, he is busy every moment of his time gnawing a new corridor. Arnie doesn't move along the already built corridors.

However, gnawing out corridors in one and the same order any time you change a house is a very difficult activity. That's why Arnie, knowing the order in which the corridors were located in the previous house, wants to gnaw corridors in another order. It is represented as a list of rooms in the order in which they should be visited. The new list should be lexicographically smallest, but it also should be strictly lexicographically greater than the previous one. Help the worm. 

Input

The first line contains two integers n and m (3 ≤ n ≤ 100, 3 ≤ m ≤ 2000). It is the number of rooms and corridors in Arnie's house correspondingly. The next line contains m + 1 positive integers that do not exceed n. They are the description of Arnie's old path represented as a list of rooms he visited during the gnawing. It is guaranteed that the last number in the list coincides with the first one.

The first room described in the list is the main entrance, that's why Arnie should begin gnawing from it.

You may assume that there is no room which is connected to itself and there is at most one corridor between any pair of rooms. However, it is possible to find some isolated rooms which are disconnected from others.

Output

Print m + 1 positive integers that do not exceed n. Those numbers are the description of the new path, according to which Arnie should gnaw out his new house. If it is impossible to find new path you should print out No solution. The first number in your answer should be equal to the last one. Also it should be equal to the main entrance.

Examples

Input

3 3
1 2 3 1


Output

1 3 2 1 

Input

3 3
1 3 2 1


Output

No solution
/**
 * Created by IntelliJ IDEA.
 * User: aircube
 * Date: 11.01.11
 * Time: 4:14
 * To change this template use File | Settings | File Templates.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.StringTokenizer;


public class TaskD {
    BufferedReader br;
    PrintWriter out;
    StringTokenizer st;

    public static void main(String[] args) throws IOException {
        new TaskD().run();
    }

    void run() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        st = null;
        out = new PrintWriter(System.out) ;

        solve();


        br.close();
        out.close();
    }

    ArrayList<Edge> g [] ;
    class Edge implements Comparable<Edge> {
        int to ;
        boolean valid ;
        boolean bridge;
        boolean direct;

        Edge(int to, boolean valid) {
            this.to = to;
            this.valid = valid;
        }

        public int compareTo(Edge edge) {
            return to - edge.to;
        }
    }

    Edge pointer [][] ;
    int n;
    void ae(int u, int v) {
        pointer[u][v].valid = true;
        pointer[v][u].valid = true;
    }
    void re(int u, int v) {
        pointer[u][v].valid = false;
        pointer[v][u].valid = false;
    }


    void solve() throws IOException {
        n = nextInt();
        int m = nextInt();
        pointer = new Edge[n][n];
        g = new ArrayList[n];
        for (int i = 0; i < n; ++i) {
            g[i] = new ArrayList<Edge>() ;
        }
        int order[] = new int[m + 1];
        for (int i = 0; i < order.length; ++i)
            order[i] = nextInt() - 1;
        for (int i = 0; i < order.length - 1; ++i) {
            int u = order[i];
            int v = order[i + 1];
            Edge tmp = new Edge(v, false);
            Edge tmp1 = new Edge(u, false);
            pointer[u][v] = tmp;
            pointer[v][u] = tmp1;
            g[u].add(tmp);
            g[v].add(tmp1);
        }
        for (int i = 0; i < n; ++i) {
            Collections.sort(g[i]);
        }
        int last = -1;
        for (int i = 0; i < order.length - 1; ++i) {
            ae(order[i], order[i + 1]);
        }
        int tt = Integer.MAX_VALUE / 10;
        for (int i = 0; i < order.length - 1; ++i) {
            calcBridges() ;
            for(Edge edge : g[order[i]]) {
                if (edge.valid && !edge.bridge) {
                    if (edge.to > order[i + 1]) {
                        if (i + 1 > last || i + 1 == last && edge.to < tt) {
                            tt = edge.to;
                            last = i + 1;
                        }
                    }
                }
            }
            re(order[i], order[i + 1]);
        }
        if (last == -1) {
            out.print("No solution");
        } else {
            for (int i = 0; i < order.length - 1; ++i)
                ae(order[i], order[i + 1]);
            // v last
            for (int i = 0; i < last - 1; ++i) {
                re(order[i], order[i + 1]);
            }
            for (int i = 0; i < last; ++i) {
                out.print(order[i] + 1);
                out.print(" ");
            }
            order[last] = tt;
            re(order[last - 1], tt);
            out.print(order[last] +  1);
            out.print(" ");
            for (int i = last; i < order.length - 1; ++i) {
                calcBridges();
                boolean f = false;
                for (Edge edge : g[order[i]]) {
                    if (edge.valid && !edge.bridge) {
                        re(order[i], edge.to);
                        order[i + 1] = edge.to;
                        out.print(edge.to + 1);
                        out.print(" ");
                        f = true;
                        break;
                    }
                }
                if (!f) {
                    for (Edge edge : g[order[i]]) {
                        if (edge.valid) {
                            re(order[i], edge.to);
                            order[i + 1] = edge.to;
                            out.print(edge.to + 1);
                            out.print(" ");
                            f = true;
                            break;
                        }
                    }
                }
            }
        }

    }

    int list [] ;
    int ptr = 0;
    private void calcBridges() {
        boolean vertex[] = new boolean[n];
        for (int i = 0; i < n; ++i) {
            for(Edge edge  : g[i]) {
                if (edge.valid) {
                    vertex[edge.to] = vertex[i] = true;
                }
                edge.direct = true;
                edge.bridge = false;
            }
        }
        int cnt = 0;
        for (int i =0 ; i < vertex.length; ++i)
            if (vertex[i]) ++ cnt;
        list = new int[cnt];
        boolean used[] = new boolean[n];
        ptr = 0;
        for (int i = 0; i < vertex.length; ++i) {
            if (vertex[i] && !used[i]) {
                dfs0(i, used);
            }
        }
        int comp[] = new int[n];
        Arrays.fill(comp, -1);
        int com = 1;
        for (int i = 0; i < list.length; ++i) {
            if (comp[list[i]] == -1) {
                dfs1(list[i], com ++, comp);
            }
        }
        for (int i = 0; i < list.length; ++i) {
            for (Edge edge : g[list[i]]) {
                if (comp[list[i]] != comp[edge.to]) {
                    edge.bridge = true;
                }
            }
        }
    }

    private void dfs1(int cur, int com, int [] comp) {
        comp[cur] = com;
        for (Edge edge : g[cur]) {
            if (edge.valid && edge.direct && comp[edge.to] == -1) {
                dfs1(edge.to, com, comp);
            }
        }
    }

    private void dfs0(int cur, boolean[] used) {
        used[cur] = true;
        list[ptr ++] = cur;
        for(Edge edge : g[cur]) {
            if (edge.valid) {
                if (!used[edge.to]) {
                    edge.direct = false;
                    dfs0(edge.to, used);
                }
            }
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }
    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }
    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }
    BigInteger nextBigInteger() throws IOException {
        return new BigInteger(nextToken());
    }
    String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(br.readLine());
        }
        return st.nextToken();
    }
}