#include <stdio.h>
#include <stdlib.h>

int A[100000];
int W[100000];

typedef struct _PW {
  int pos;
  int wgt;
} PW;

PW findSet(int pos) {
  int tgt;
  PW pw;
  pw.pos = pos;
  tgt = A[pos];
  pw.wgt = 0;

  while (pw.pos != tgt) {
    pw.wgt += W[pw.pos];
    pw.pos = tgt;
    tgt = A[pw.pos];
  }

  return pw;
}

int diff(int s, int d) {
  
  PW spw, dpw;
  spw = findSet(s);
  dpw = findSet(d);

  if (spw.pos != dpw.pos) return -1;
  
  return abs(spw.wgt - dpw.wgt);
}

void relate(int pos, int dis, int wgt) {
  int tgt, flg;
  tgt = A[pos];
  flg = 1;
  while (flg) {
    if (pos == tgt) {
      A[pos] = dis;
      W[pos] = wgt;
      flg = 0;
    }
    else {
      wgt -= W[pos];
      if (wgt < 0) {
        A[pos] = dis;
        W[pos] += wgt;
        A[dis] = tgt;
        W[dis] = wgt * (-1);
        flg = 0;
      }
      else {
        pos = tgt;
        tgt = A[pos];
      }
    }
  }
}

int main() {
	int i, n, q, x, y, z;
	int code, ans;

	scanf("%d %d", &n, &q);

	for (i = 0; i < n; i++) {
		A[i] = i;
		W[i] = 0;
	}

	for (i = 0; i < q; i++) {
		scanf("%d", &code);
    if (code) {
      scanf("%d %d", &x, &y);
      ans = diff(x, y);
      if (ans < 0) printf("?\n");
      else printf("%d\n", ans);
    }
    else {
      scanf("%d %d %d", &x, &y, &z);
      relate(x, y, z);
    }
	}

  return 0;
}
