import std.stdio, std.string, std.algorithm, std.range, std.conv;

void main(){
    while(true){
        auto input = readln.split;
        int n = input[0].to!int, k = input[1].to!int;

        if(n == 0 && k == 0) break;
        auto G = new int[][](n + 1, n + 1);
        foreach(ref g; G){
            g[] = int.max;
        }

        foreach(Unused; 0..k){
            input = readln.split;
            int op = input[0].to!int;
            if(op == 1){
                int a = input[1].to!int, b = input[2].to!int, cost = input[3].to!int;
                if(cost < G[a][b]){
                    G[a][b] = cost;
                    G[b][a] = cost;
                }
            }else if(op == 0){
                int start = input[1].to!int, end = input[2].to!int;
                auto d = new int[](n + 1);
                auto MST = new bool[](n + 1);
                d[] = int.max;
                d[start] = 0;
                while(true){
                    int min = int.max;
                    int u;
                    foreach(i; 1..n + 1){
                        if(!MST[i] && min > d[i]){
                            min = d[i];
                            u = i;
                        }
                    }
                    if(u == 0) break;
                    MST[u] = true;
                    foreach(v; 1..n + 1){
                        if(!MST[v] && G[u][v] != int.max && G[u][v] + d[u] < d[v]){
                            d[v] = G[u][v] + d[u];
                        }
                    }
                }
                if(d[end] == int.max) (-1).writeln;
                else d[end].writeln;
            }
        }
    }
}