#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;
const int MOD = 998244353;
const int MAX_VAL = 3001; // Ci 的值最大為 3000,所以 DP 狀態的第二維需要到 3001 (索引 0 到 3000)
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector<int> a(n);
vector<int> b(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
for (int i = 0; i < n; ++i) {
cin >> b[i];
}
// dp[i][j]: 表示考慮序列 C 的前 i+1 個元素 (C_0, ..., C_i),且 C_i = j 的合法序列數量。
// 這裡使用 0-based 索引,所以 i 從 0 到 N-1
vector<vector<int>> dp(n, vector<int>(MAX_VAL, 0));
// 基底 (i = 0, 對應序列 C 的第一個元素 C_0)
// C_0 可以取 A[0] 到 B[0] 之間的值
for (int j = a[0]; j <= b[0]; ++j) {
dp[0][j] = 1;
}
// 迭代計算 (i 從 1 到 N-1, 對應序列 C 的第 2 到 N 個元素)
for (int i = 1; i < n; ++i) {
// 計算前一層 dp[i-1] 的前綴和
vector<int> prefix_sum(MAX_VAL, 0);
prefix_sum[0] = dp[i - 1][0];
for (int j = 1; j < MAX_VAL; ++j) {
prefix_sum[j] = (prefix_sum[j - 1] + dp[i - 1][j]) % MOD;
}
// 計算當前層 dp[i]
// 當前元素 C_i 可以取 A[i] 到 B[i] 之間的值 j
for (int j = a[i]; j <= b[i]; ++j) {
// C_{i-1} 的值 k 必須滿足 A[i-1] <= k <= B[i-1] 且 k <= C_i = j
// 所以 k 的範圍是 [A[i-1], min(B[i-1], j)]
int upper_bound_prev = min(b[i - 1], j);
int lower_bound_prev = a[i - 1];
long long count_prev = 0;
if (lower_bound_prev <= upper_bound_prev) {
// 使用前綴和計算 dp[i-1] 在範圍 [lower_bound_prev, upper_bound_prev] 的和
long long sum_up_to_upper = prefix_sum[upper_bound_prev];
long long sum_up_to_lower_minus_1 = 0;
if (lower_bound_prev > 0) {
sum_up_to_lower_minus_1 = prefix_sum[lower_bound_prev - 1];
}
count_prev = (sum_up_to_upper - sum_up_to_lower_minus_1 + MOD) % MOD; // 處理負數結果
} else {
// 這個範圍不可能有 C_{i-1} 的值,數量為 0
count_prev = 0;
}
dp[i][j] = count_prev;
}
}
// 計算最終答案
// 最終答案是考慮到 C_{N-1} 時,所有可能的 C_{N-1} 值 (A[N-1] 到 B[N-1]) 對應的合法序列數量總和
long long final_answer = 0;
for (int j = a[n - 1]; j <= b[n - 1]; ++j) {
final_answer = (final_answer + dp[n - 1][j]) % MOD;
}
cout << final_answer << endl;
return 0;
}