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

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

    auto G = new int[][](n + 1, n + 1);
    foreach(i; 0..n + 1){
        foreach(j; 0..n + 1){
            G[i][j] = i == j ? 0 : 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;
            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;
            foreach(Unused2; 0..n){
                int min = int.max;
                int u;
                foreach(i; 1..n + 1){
                    if(!MST[i] && min > d[i]){
                        min = d[i];
                        u = i;
                    }
                }
                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;
        }
    }
}