#include <bits/stdc++.h>
using namespace std;
map<pair<long long, long long>, long long> m;
void getPath(long long v, long long u, vector<long long> &path) {
  vector<long long> path1, path2;
  path1.push_back(v);
  path2.push_back(u);
  while (v > 1) {
    v /= 2;
    path1.push_back(v);
  }
  while (u > 1) {
    u /= 2;
    path2.push_back(u);
  }
  int i1 = path1.size() - 1, i2 = path2.size() - 1;
  long long lcs;
  while (i1 >= 0 && i2 >= 0 && path1[i1] == path2[i2]) {
    lcs = path1[i1];
    i1--;
    i2--;
  }
  int i;
  for (i = 0; path1[i] != lcs; i++) path.push_back(path1[i]);
  path.push_back(lcs);
  for (i = path2.size() - 1; path2[i] != lcs; i--)
    ;
  for (--i; i >= 0; i--) path.push_back(path2[i]);
}
void update(long long v, long long u, int w) {
  vector<long long> path;
  getPath(v, u, path);
  pair<long long, long long> edge;
  for (int i = 0; i < path.size() - 1; i++) {
    if (path[i] < path[i + 1]) {
      edge.first = path[i];
      edge.second = path[i + 1];
    } else {
      edge.first = path[i + 1];
      edge.second = path[i];
    }
    m[edge] += w;
  }
}
long long query(long long v, long long u) {
  long long sum = 0;
  vector<long long> path;
  getPath(v, u, path);
  pair<long long, long long> edge;
  for (int i = 0; i < path.size() - 1; i++) {
    if (path[i] < path[i + 1]) {
      edge.first = path[i];
      edge.second = path[i + 1];
    } else {
      edge.first = path[i + 1];
      edge.second = path[i];
    }
    sum += m[edge];
  }
  return sum;
}
int main() {
  int q, op;
  cin >> q;
  long long v, u, w;
  for (int i = 0; i < q; i++) {
    cin >> op >> v >> u;
    if (v > u) swap(v, u);
    if (op == 1) {
      cin >> w;
      update(v, u, w);
    } else
      cout << query(v, u) << '\n';
  }
  return 0;
}
