diff --git a/LICENSE b/LICENSE index 244538035e830..67950460d436d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2023 PostHog Inc. +Copyright (c) 2020-2024 PostHog Inc. Portions of this software are licensed as follows: diff --git a/ee/clickhouse/models/test/__snapshots__/test_cohort.ambr b/ee/clickhouse/models/test/__snapshots__/test_cohort.ambr index 6ebddd1cbbe62..692074cd2912d 100644 --- a/ee/clickhouse/models/test/__snapshots__/test_cohort.ambr +++ b/ee/clickhouse/models/test/__snapshots__/test_cohort.ambr @@ -32,7 +32,8 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 0 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohort.test_cohortpeople_with_not_in_cohort_operator @@ -66,7 +67,8 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 0 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohort.test_cohortpeople_with_not_in_cohort_operator.1 @@ -115,7 +117,8 @@ HAVING max(is_deleted) = 0 AND (((((NOT has(['something1'], replaceRegexpAll(JSONExtractRaw(argMax(person.properties, version), '$some_prop'), '^"|"$', ''))))))) SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = behavior_query.person_id WHERE 1 = 1 - AND ((((performed_event_condition_X_level_level_0_level_0_level_0_0)))) SETTINGS optimize_aggregation_in_order=1 ) as person + AND ((((performed_event_condition_X_level_level_0_level_0_level_0_0)))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ) as person UNION ALL SELECT person_id, cohort_id, @@ -126,7 +129,8 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 0 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohort.test_cohortpeople_with_not_in_cohort_operator_and_no_precalculation @@ -181,7 +185,8 @@ HAVING max(is_deleted) = 0 AND (((((NOT has(['something1'], replaceRegexpAll(JSONExtractRaw(argMax(person.properties, version), '$some_prop'), '^"|"$', ''))))))) SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = behavior_query.person_id WHERE 1 = 1 - AND ((((performed_event_condition_X_level_level_0_level_0_level_0_0)))) SETTINGS optimize_aggregation_in_order=1 ) )) + AND ((((performed_event_condition_X_level_level_0_level_0_level_0_0)))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ) )) ''' # --- # name: TestCohort.test_cohortpeople_with_not_in_cohort_operator_for_behavioural_cohorts @@ -211,7 +216,8 @@ AND event IN ['signup'] GROUP BY person_id) behavior_query WHERE 1 = 1 - AND (((first_time_condition_X_level_level_0_level_0_0))) SETTINGS optimize_aggregation_in_order=1 ) as person + AND (((first_time_condition_X_level_level_0_level_0_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ) as person UNION ALL SELECT person_id, cohort_id, @@ -222,7 +228,8 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 0 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohort.test_cohortpeople_with_not_in_cohort_operator_for_behavioural_cohorts.1 @@ -257,7 +264,8 @@ GROUP BY person_id) behavior_query WHERE 1 = 1 AND ((((performed_event_condition_X_level_level_0_level_0_level_0_0)) - AND ((((NOT first_time_condition_X_level_level_0_level_1_level_0_level_0_level_0_0)))))) SETTINGS optimize_aggregation_in_order=1 ) as person + AND ((((NOT first_time_condition_X_level_level_0_level_1_level_0_level_0_level_0_0)))))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ) as person UNION ALL SELECT person_id, cohort_id, @@ -268,7 +276,8 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 0 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohort.test_static_cohort_precalculated diff --git a/ee/clickhouse/queries/enterprise_cohort_query.py b/ee/clickhouse/queries/enterprise_cohort_query.py index cc2400615c573..0629c6757a93c 100644 --- a/ee/clickhouse/queries/enterprise_cohort_query.py +++ b/ee/clickhouse/queries/enterprise_cohort_query.py @@ -85,7 +85,7 @@ def get_query(self) -> tuple[str, dict[str, Any]]: {q} WHERE 1 = 1 {conditions} - SETTINGS optimize_aggregation_in_order=1 + SETTINGS optimize_aggregation_in_order = 1, join_algorithm = 'auto' """ return final_query, self.params diff --git a/ee/clickhouse/queries/test/__snapshots__/test_cohort_query.ambr b/ee/clickhouse/queries/test/__snapshots__/test_cohort_query.ambr index 56940008f5007..02b9e77db69c2 100644 --- a/ee/clickhouse/queries/test/__snapshots__/test_cohort_query.ambr +++ b/ee/clickhouse/queries/test/__snapshots__/test_cohort_query.ambr @@ -46,7 +46,8 @@ WHERE 1 = 1 AND ((((performed_event_condition_None_level_level_0_level_0_level_0_0) OR (performed_event_condition_None_level_level_0_level_0_level_1_0)) - AND ((first_time_condition_None_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order=1 + AND ((first_time_condition_None_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_cohort_filter_with_another_cohort_with_event_sequence @@ -117,7 +118,8 @@ AND (((has(['test'], replaceRegexpAll(JSONExtractRaw(argMax(person.properties, version), 'name'), '^"|"$', ''))))) SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = funnel_query.person_id WHERE 1 = 1 AND ((((steps_0)) - AND (steps_1))) SETTINGS optimize_aggregation_in_order=1 + AND (steps_1))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_cohort_filter_with_extra @@ -159,7 +161,8 @@ HAVING max(is_deleted) = 0 AND ((((has(['test'], replaceRegexpAll(JSONExtractRaw(argMax(person.properties, version), 'name'), '^"|"$', '')))))) SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = behavior_query.person_id WHERE 1 = 1 - AND (((performed_event_condition_None_level_level_0_level_0_0))) SETTINGS optimize_aggregation_in_order=1 + AND (((performed_event_condition_None_level_level_0_level_0_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_cohort_filter_with_extra.1 @@ -197,7 +200,8 @@ HAVING max(is_deleted) = 0 SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = behavior_query.person_id WHERE 1 = 1 AND ((((has(['test'], replaceRegexpAll(JSONExtractRaw(person_props, 'name'), '^"|"$', '')))) - OR ((performed_event_condition_None_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order=1 + OR ((performed_event_condition_None_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_performed_event_sequence @@ -240,7 +244,8 @@ AND timestamp >= now() - INTERVAL 7 day )) GROUP BY person_id) funnel_query WHERE 1 = 1 - AND (((steps_0))) SETTINGS optimize_aggregation_in_order=1 + AND (((steps_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_performed_event_sequence_and_clause_with_additional_event @@ -288,7 +293,8 @@ GROUP BY person_id) funnel_query WHERE 1 = 1 AND (((steps_0) - OR (performed_event_multiple_condition_None_level_level_0_level_1_0))) SETTINGS optimize_aggregation_in_order=1 + OR (performed_event_multiple_condition_None_level_level_0_level_1_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_performed_event_sequence_with_person_properties @@ -351,7 +357,8 @@ AND ((has(['test@posthog.com'], replaceRegexpAll(JSONExtractRaw(argMax(person.properties, version), 'email'), '^"|"$', '')))) SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = funnel_query.person_id WHERE 1 = 1 AND (((steps_0) - AND (performed_event_multiple_condition_None_level_level_0_level_1_0))) SETTINGS optimize_aggregation_in_order=1 + AND (performed_event_multiple_condition_None_level_level_0_level_1_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_performed_event_with_event_filters_and_explicit_date @@ -378,7 +385,8 @@ AND timestamp >= now() - INTERVAL 4 day GROUP BY person_id) behavior_query WHERE 1 = 1 - AND (((performed_event_condition_None_level_level_0_level_0_0))) SETTINGS optimize_aggregation_in_order=1 + AND (((performed_event_condition_None_level_level_0_level_0_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_person @@ -416,7 +424,8 @@ HAVING max(is_deleted) = 0 SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = behavior_query.person_id WHERE 1 = 1 AND (((performed_event_condition_None_level_level_0_level_0_0) - OR (has(['test@posthog.com'], replaceRegexpAll(JSONExtractRaw(person_props, '$sample_field'), '^"|"$', ''))))) SETTINGS optimize_aggregation_in_order=1 + OR (has(['test@posthog.com'], replaceRegexpAll(JSONExtractRaw(person_props, '$sample_field'), '^"|"$', ''))))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_person_materialized @@ -454,7 +463,8 @@ HAVING max(is_deleted) = 0 SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = behavior_query.person_id WHERE 1 = 1 AND (((performed_event_condition_None_level_level_0_level_0_0) - OR (has(['test@posthog.com'], "pmat_$sample_field")))) SETTINGS optimize_aggregation_in_order=1 + OR (has(['test@posthog.com'], "pmat_$sample_field")))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_person_properties_with_pushdowns @@ -506,7 +516,8 @@ AND ((((performed_event_condition_None_level_level_0_level_0_level_0_0) OR (performed_event_condition_None_level_level_0_level_0_level_1_0) OR (has(['special'], replaceRegexpAll(JSONExtractRaw(person_props, 'name'), '^"|"$', '')))) - AND ((first_time_condition_None_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order=1 + AND ((first_time_condition_None_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_person_props_only @@ -596,7 +607,8 @@ (SELECT person_id as id FROM person_static_cohort WHERE cohort_id = 2 - AND team_id = 2)))) SETTINGS optimize_aggregation_in_order=1 + AND team_id = 2)))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_static_cohort_filter_with_extra @@ -646,7 +658,8 @@ FROM person_static_cohort WHERE cohort_id = 2 AND team_id = 2)) - AND (performed_event_condition_None_level_level_0_level_1_0))) SETTINGS optimize_aggregation_in_order=1 + AND (performed_event_condition_None_level_level_0_level_1_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_static_cohort_filter_with_extra.2 @@ -687,7 +700,8 @@ FROM person_static_cohort WHERE cohort_id = 2 AND team_id = 2))) - OR ((performed_event_condition_None_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order=1 + OR ((performed_event_condition_None_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohortQuery.test_unwrapping_static_cohort_filter_hidden_in_layers_of_cohorts @@ -742,6 +756,7 @@ FROM person_static_cohort WHERE cohort_id = 2 AND team_id = 2))) - OR (performed_event_condition_None_level_level_0_level_1_0))) SETTINGS optimize_aggregation_in_order=1 + OR (performed_event_condition_None_level_level_0_level_1_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- diff --git a/ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiments.ambr b/ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiments.ambr index 188d66cab5843..97d5902e16e2f 100644 --- a/ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiments.ambr +++ b/ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiments.ambr @@ -1035,7 +1035,8 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 1 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestExperimentAuxiliaryEndpoints.test_create_exposure_cohort_for_experiment_with_custom_action_filters_exposure.1 @@ -1095,7 +1096,8 @@ AND timestamp >= now() - INTERVAL 6 day GROUP BY person_id) behavior_query WHERE 1 = 1 - AND (((performed_event_condition_X_level_level_0_level_0_0))) SETTINGS optimize_aggregation_in_order=1 ) as person + AND (((performed_event_condition_X_level_level_0_level_0_0))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ) as person UNION ALL SELECT person_id, cohort_id, @@ -1106,6 +1108,7 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 1 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- diff --git a/frontend/__snapshots__/scenes-app-insights--funnel-top-to-bottom-breakdown-edit--light.png b/frontend/__snapshots__/scenes-app-insights--funnel-top-to-bottom-breakdown-edit--light.png index f6cfa36a3526c..3c6c4b808427d 100644 Binary files a/frontend/__snapshots__/scenes-app-insights--funnel-top-to-bottom-breakdown-edit--light.png and b/frontend/__snapshots__/scenes-app-insights--funnel-top-to-bottom-breakdown-edit--light.png differ diff --git a/frontend/__snapshots__/scenes-app-sidepanels--side-panel-docs--dark.png b/frontend/__snapshots__/scenes-app-sidepanels--side-panel-docs--dark.png index 17cbc47a38452..a3e04b0c7f7dd 100644 Binary files a/frontend/__snapshots__/scenes-app-sidepanels--side-panel-docs--dark.png and b/frontend/__snapshots__/scenes-app-sidepanels--side-panel-docs--dark.png differ diff --git a/frontend/__snapshots__/scenes-app-sidepanels--side-panel-docs--light.png b/frontend/__snapshots__/scenes-app-sidepanels--side-panel-docs--light.png index 157ae9ad6515d..85b6a5d19efbb 100644 Binary files a/frontend/__snapshots__/scenes-app-sidepanels--side-panel-docs--light.png and b/frontend/__snapshots__/scenes-app-sidepanels--side-panel-docs--light.png differ diff --git a/frontend/public/services/mailjet.png b/frontend/public/services/mailjet.png new file mode 100644 index 0000000000000..dc3afa3b8ef4e Binary files /dev/null and b/frontend/public/services/mailjet.png differ diff --git a/frontend/src/layout/ErrorBoundary/ErrorBoundary.tsx b/frontend/src/layout/ErrorBoundary/ErrorBoundary.tsx index cb3212d21ab1e..28b171d53e1d7 100644 --- a/frontend/src/layout/ErrorBoundary/ErrorBoundary.tsx +++ b/frontend/src/layout/ErrorBoundary/ErrorBoundary.tsx @@ -1,12 +1,13 @@ import './ErrorBoundary.scss' -import { IconChevronDown } from '@posthog/icons' import { ErrorBoundary as SentryErrorBoundary, getCurrentHub } from '@sentry/react' -import { HelpButton } from 'lib/components/HelpButton/HelpButton' +import { useActions } from 'kea' +import { supportLogic } from 'lib/components/Support/supportLogic' import { LemonButton } from 'lib/lemon-ui/LemonButton' export function ErrorBoundary({ children }: { children?: React.ReactNode }): JSX.Element { const isSentryInitialized = !!getCurrentHub().getClient() + const { openSupportForm } = useActions(supportLogic) return ( }> - Contact PostHog - - } - customKey="error-boundary" - contactOnly - /> + openSupportForm({ kind: 'bug', isEmailFormOpen: true })} + targetBlank + className="mt-2" + > + Email an engineer + )} diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 83b6a6f5493af..ac2169e4c671f 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -1025,10 +1025,14 @@ const api = { return new ApiRequest().insightsActivity(teamId) }, [ActivityScope.PLUGIN]: () => { - return new ApiRequest().pluginsActivity() + return activityLogProps.id + ? new ApiRequest().pluginConfig(activityLogProps.id as number, teamId).withAction('activity') + : new ApiRequest().plugins().withAction('activity') }, [ActivityScope.PLUGIN_CONFIG]: () => { - return new ApiRequest().pluginsActivity() + return activityLogProps.id + ? new ApiRequest().pluginConfig(activityLogProps.id as number, teamId).withAction('activity') + : new ApiRequest().plugins().withAction('activity') }, [ActivityScope.DATA_MANAGEMENT]: () => { return new ApiRequest().dataManagementActivity() diff --git a/frontend/src/lib/components/ActivityLog/activityLogLogic.plugin.test.tsx b/frontend/src/lib/components/ActivityLog/activityLogLogic.plugin.test.tsx index f628239b75321..6010f55e044ef 100644 --- a/frontend/src/lib/components/ActivityLog/activityLogLogic.plugin.test.tsx +++ b/frontend/src/lib/components/ActivityLog/activityLogLogic.plugin.test.tsx @@ -16,7 +16,10 @@ describe('the activity log logic', () => { }) describe('humanizing plugins', () => { - const pluginTestSetup = makeTestSetup(ActivityScope.PLUGIN, '/api/organizations/:id/plugins/activity') + const pluginTestSetup = makeTestSetup( + ActivityScope.PLUGIN, + '/api/projects/:id/plugin_configs/:config_id/activity' + ) it('can handle installation of a plugin', async () => { const logic = await pluginTestSetup('the installed plugin', 'installed', null) const actual = logic.values.humanizedActivity diff --git a/frontend/src/lib/components/ActivityLog/complex.sql b/frontend/src/lib/components/ActivityLog/complex.sql deleted file mode 100644 index 377778eff333d..0000000000000 --- a/frontend/src/lib/components/ActivityLog/complex.sql +++ /dev/null @@ -1,27 +0,0 @@ -SELECT - count() AS total, - toStartOfDay(min_timestamp) AS day_start, - breakdown_value AS breakdown_value -FROM - (SELECT - min(timestamp) AS min_timestamp, - argMin(breakdown_value, timestamp) AS breakdown_value - FROM - (SELECT - person_id, - timestamp, - ifNull(nullIf(toString(properties.$browser), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - events AS e SAMPLE 1 - WHERE - and(equals(event, '$pageview'), lessOrEquals(timestamp, assumeNotNull(toDateTime('2025-01-20 23:59:59')))) - ) - GROUP BY - person_id - ) -WHERE - greaterOrEquals(min_timestamp, toStartOfDay(assumeNotNull(toDateTime('2020-01-09 00:00:00')))) -GROUP BY - day_start, - breakdown_value -LIMIT 50000 diff --git a/frontend/src/lib/components/ActivityLog/full_query.sql b/frontend/src/lib/components/ActivityLog/full_query.sql deleted file mode 100644 index b7129f83c64f4..0000000000000 --- a/frontend/src/lib/components/ActivityLog/full_query.sql +++ /dev/null @@ -1,41 +0,0 @@ -SELECT - arrayMap(number -> plus(toStartOfDay(assumeNotNull(toDateTime('2024-07-16 00:00:00'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(toDateTime('2024-07-16 00:00:00'))), toStartOfDay(assumeNotNull(toDateTime('2024-07-23 23:59:59'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> equals(x, _match_date), _days_for_count), _index), 1))), date) AS total -FROM - (SELECT - sum(total) AS count, - day_start - FROM (SELECT - count() AS total, - day_start, - breakdown_value - FROM ( - SELECT - min(timestamp) as day_start, - argMin(breakdown_value, timestamp) AS breakdown_value, - FROM - ( - SELECT - person_id, - toStartOfDay(timestamp) AS timestamp, - ifNull(nullIf(toString(person.properties.email), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - events AS e SAMPLE 1 - WHERE - and(lessOrEquals(timestamp, assumeNotNull(toDateTime('2024-07-23 23:59:59'))), equals(properties.$browser, 'Safari')) - ) - WHERE - greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(toDateTime('2024-07-16 00:00:00')))) - GROUP BY - person_id - ) - GROUP BY - day_start, - breakdown_value) - GROUP BY - day_start - ORDER BY - day_start ASC) -ORDER BY - arraySum(total) DESC -LIMIT 50000 diff --git a/frontend/src/lib/components/ActivityLog/weekly.sql b/frontend/src/lib/components/ActivityLog/weekly.sql deleted file mode 100644 index 579249842508c..0000000000000 --- a/frontend/src/lib/components/ActivityLog/weekly.sql +++ /dev/null @@ -1,45 +0,0 @@ -SELECT - arrayMap(number -> plus(toStartOfDay(assumeNotNull(toDateTime('2024-07-16 00:00:00'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(toDateTime('2024-07-16 00:00:00'))), toStartOfDay(assumeNotNull(toDateTime('2024-07-23 23:59:59'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> equals(x, _match_date), _days_for_count), _index), 1))), date) AS total -FROM - (SELECT - sum(total) AS count, - day_start - FROM - (SELECT - counts AS total, - toStartOfDay(timestamp) AS day_start - FROM - (SELECT - d.timestamp, - count(DISTINCT actor_id) AS counts - FROM - (SELECT - minus(toStartOfDay(assumeNotNull(toDateTime('2024-07-23 23:59:59'))), toIntervalDay(number)) AS timestamp - FROM - numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(toDateTime('2024-07-16 00:00:00'))), toIntervalDay(7)), assumeNotNull(toDateTime('2024-07-23 23:59:59')))) AS numbers) AS d - CROSS JOIN (SELECT - timestamp AS timestamp, - e.person_id AS actor_id - FROM - events AS e SAMPLE 1 - WHERE - and(equals(event, '$pageview'), greaterOrEquals(timestamp, minus(assumeNotNull(toDateTime('2024-07-16 00:00:00')), toIntervalDay(7))), lessOrEquals(timestamp, assumeNotNull(toDateTime('2024-07-23 23:59:59')))) - GROUP BY - timestamp, - actor_id) AS e - WHERE - and(lessOrEquals(e.timestamp, plus(d.timestamp, toIntervalDay(1))), greater(e.timestamp, minus(d.timestamp, toIntervalDay(6)))) - GROUP BY - d.timestamp - ORDER BY - d.timestamp ASC) - WHERE - and(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(toDateTime('2024-07-16 00:00:00')))), lessOrEquals(timestamp, assumeNotNull(toDateTime('2024-07-23 23:59:59'))))) - GROUP BY - day_start - ORDER BY - day_start ASC) -ORDER BY - arraySum(total) DESC -LIMIT 50000 diff --git a/frontend/src/lib/components/RestrictedArea.tsx b/frontend/src/lib/components/RestrictedArea.tsx index fbcfc2b1b0d9c..85177456b1c0e 100644 --- a/frontend/src/lib/components/RestrictedArea.tsx +++ b/frontend/src/lib/components/RestrictedArea.tsx @@ -1,5 +1,4 @@ import { useValues } from 'kea' -import { Tooltip } from 'lib/lemon-ui/Tooltip' import { useMemo } from 'react' import { organizationLogic } from '../../scenes/organizationLogic' @@ -61,21 +60,3 @@ export function useRestrictedArea({ scope, minimumAccessLevel }: UseRestrictedAr return restrictionReason } - -export function RestrictedArea({ - Component, - minimumAccessLevel, - scope = RestrictionScope.Organization, -}: RestrictedAreaProps): JSX.Element { - const restrictionReason = useRestrictedArea({ minimumAccessLevel, scope }) - - return restrictionReason ? ( - - - - - - ) : ( - - ) -} diff --git a/frontend/src/lib/lemon-ui/LemonButton/LemonButton.tsx b/frontend/src/lib/lemon-ui/LemonButton/LemonButton.tsx index 11e44d7a5e4d8..cefc0e536df6e 100644 --- a/frontend/src/lib/lemon-ui/LemonButton/LemonButton.tsx +++ b/frontend/src/lib/lemon-ui/LemonButton/LemonButton.tsx @@ -63,6 +63,8 @@ export interface LemonButtonPropsBase disabled?: boolean /** Like plain `disabled`, except we enforce a reason to be shown in the tooltip. */ disabledReason?: string | null | false + /** Class for the wrapping div when the button is disabled */ + disabledReasonWrapperClass?: string noPadding?: boolean size?: 'xsmall' | 'small' | 'medium' | 'large' 'data-attr'?: string @@ -116,6 +118,7 @@ export const LemonButton: React.FunctionComponent {/* If the button is a `button` element and disabled, wrap it in a div so that the tooltip works */} - {disabled && ButtonComponent === 'button' ?
{workingButton}
: workingButton} + {disabled && ButtonComponent === 'button' ? ( +
{workingButton}
+ ) : ( + workingButton + )} ) } diff --git a/frontend/src/queries/examples.ts b/frontend/src/queries/examples.ts index 7cbad0eccc4f3..26046b44356d2 100644 --- a/frontend/src/queries/examples.ts +++ b/frontend/src/queries/examples.ts @@ -289,8 +289,9 @@ limit 100`, const HogQLForDataWarehouse: HogQLQuery = { kind: NodeKind.HogQLQuery, - query: `select toDate(timestamp) as timestamp, event as event - from events + query: `select toDate(timestamp) as timestamp, count() +from events +group by timestamp limit 100`, explain: true, } diff --git a/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.tsx b/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.tsx index 874fdcd292e70..f991ee5fb8920 100644 --- a/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.tsx +++ b/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.tsx @@ -8,7 +8,7 @@ import { IconPencil, IconX } from '@posthog/icons' import { BindLogic, useActions, useValues } from 'kea' import { PropertyFilterIcon } from 'lib/components/PropertyFilters/components/PropertyFilterIcon' import { PropertyKeyInfo } from 'lib/components/PropertyKeyInfo' -import { RestrictedArea, RestrictedComponentProps, RestrictionScope } from 'lib/components/RestrictedArea' +import { RestrictionScope, useRestrictedArea } from 'lib/components/RestrictedArea' import { TaxonomicFilter } from 'lib/components/TaxonomicFilter/TaxonomicFilter' import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types' import { TeamMembershipLevel } from 'lib/constants' @@ -86,6 +86,10 @@ export function ColumnConfigurator({ query, setQuery }: ColumnConfiguratorProps) } function ColumnConfiguratorModal({ query }: ColumnConfiguratorProps): JSX.Element { + const restrictionReason = useRestrictedArea({ + minimumAccessLevel: TeamMembershipLevel.Admin, + scope: RestrictionScope.Project, + }) const { modalVisible, columns, saveAsDefault } = useValues(columnConfiguratorLogic) const { hideModal, moveColumn, setColumns, selectColumn, unselectColumn, save, toggleSaveAsDefault } = useActions(columnConfiguratorLogic) @@ -184,24 +188,14 @@ function ColumnConfiguratorModal({ query }: ColumnConfiguratorProps): JSX.Elemen {isEventsQuery(query.source) && query.showPersistentColumnConfigurator ? ( - - ) - }} - minimumAccessLevel={TeamMembershipLevel.Admin} - scope={RestrictionScope.Project} + ) : null} diff --git a/frontend/src/queries/nodes/DataVisualization/Components/Charts/LineGraph.tsx b/frontend/src/queries/nodes/DataVisualization/Components/Charts/LineGraph.tsx index e719e99616f94..97ac3930b9088 100644 --- a/frontend/src/queries/nodes/DataVisualization/Components/Charts/LineGraph.tsx +++ b/frontend/src/queries/nodes/DataVisualization/Components/Charts/LineGraph.tsx @@ -19,7 +19,7 @@ import { ensureTooltip } from 'scenes/insights/views/LineGraph/LineGraph' import { themeLogic } from '~/layout/navigation-3000/themeLogic' import { ChartDisplayType, GraphType } from '~/types' -import { dataVisualizationLogic } from '../../dataVisualizationLogic' +import { dataVisualizationLogic, formatDataWithSettings } from '../../dataVisualizationLogic' import { displayLogic } from '../../displayLogic' Chart.register(annotationPlugin) @@ -155,7 +155,7 @@ export const LineGraph = (): JSX.Element => { // TODO: A lot of this is v similar to the trends LineGraph - considering merging these tooltip: { enabled: false, - mode: 'nearest', + mode: 'index', intersect: false, external({ tooltip }: { chart: Chart; tooltip: TooltipModel }) { if (!canvasRef.current) { @@ -179,9 +179,9 @@ export const LineGraph = (): JSX.Element => { tooltipRoot.render(
({ + dataSource={yData.map(({ data, column, settings }) => ({ series: column.name, - data: data[referenceDataPoint.dataIndex], + data: formatDataWithSettings(data[referenceDataPoint.dataIndex], settings), }))} columns={[ { diff --git a/frontend/src/queries/nodes/DataVisualization/Components/SeriesTab.tsx b/frontend/src/queries/nodes/DataVisualization/Components/SeriesTab.tsx index d26e0b23faae7..077d48a70d545 100644 --- a/frontend/src/queries/nodes/DataVisualization/Components/SeriesTab.tsx +++ b/frontend/src/queries/nodes/DataVisualization/Components/SeriesTab.tsx @@ -1,12 +1,15 @@ -import { IconPlusSmall, IconTrash } from '@posthog/icons' -import { LemonButton, LemonLabel, LemonSelect } from '@posthog/lemon-ui' +import { IconGear, IconPlusSmall, IconTrash } from '@posthog/icons' +import { LemonButton, LemonInput, LemonLabel, LemonSelect, Popover } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' +import { Form } from 'kea-forms' +import { LemonField } from 'lib/lemon-ui/LemonField' -import { dataVisualizationLogic } from '../dataVisualizationLogic' +import { AxisSeries, dataVisualizationLogic } from '../dataVisualizationLogic' +import { ySeriesLogic } from './ySeriesLogic' export const SeriesTab = (): JSX.Element => { const { columns, xData, yData, responseLoading } = useValues(dataVisualizationLogic) - const { updateXSeries, updateYSeries, addYSeries, deleteYSeries } = useActions(dataVisualizationLogic) + const { updateXSeries, addYSeries } = useActions(dataVisualizationLogic) const options = columns.map(({ name, label }) => ({ value: name, @@ -29,29 +32,8 @@ export const SeriesTab = (): JSX.Element => { }} /> Y-axis - {(yData ?? [null]).map((series, index) => ( -
- { - const column = columns.find((n) => n.name === value) - if (column) { - updateYSeries(index, column.name) - } - }} - /> - } - status="danger" - title="Delete Y-series" - noPadding - onClick={() => deleteYSeries(index)} - /> -
+ {yData.map((series, index) => ( + ))} {
) } + +const YSeries = ({ series, index }: { series: AxisSeries; index: number }): JSX.Element => { + const { columns, responseLoading, dataVisualizationProps } = useValues(dataVisualizationLogic) + const { updateYSeries, deleteYSeries } = useActions(dataVisualizationLogic) + + const seriesLogicProps = { series, seriesIndex: index, dataVisualizationProps } + const seriesLogic = ySeriesLogic(seriesLogicProps) + + const { isSettingsOpen, canOpenSettings } = useValues(seriesLogic) + const { setSettingsOpen, submitFormatting } = useActions(seriesLogic) + + const options = columns.map(({ name, label }) => ({ + value: name, + label, + })) + + return ( +
+ { + const column = columns.find((n) => n.name === value) + if (column) { + updateYSeries(index, column.name) + } + }} + /> + + + + + + + + + + + + + + + } + visible={isSettingsOpen} + placement="bottom" + onClickOutside={() => submitFormatting()} + > + } + noPadding + onClick={() => setSettingsOpen(true)} + disabledReason={!canOpenSettings && 'Select a column first'} + disabledReasonWrapperClass="flex" + /> + + } + status="danger" + title="Delete Y-series" + noPadding + onClick={() => deleteYSeries(index)} + /> +
+ ) +} diff --git a/frontend/src/queries/nodes/DataVisualization/Components/ySeriesLogic.ts b/frontend/src/queries/nodes/DataVisualization/Components/ySeriesLogic.ts new file mode 100644 index 0000000000000..cd2e4b5c34c6e --- /dev/null +++ b/frontend/src/queries/nodes/DataVisualization/Components/ySeriesLogic.ts @@ -0,0 +1,66 @@ +import { actions, connect, kea, key, path, props, reducers, selectors } from 'kea' +import { forms } from 'kea-forms' + +import { + AxisSeries, + dataVisualizationLogic, + DataVisualizationLogicProps, + EmptyYAxisSeries, +} from '../dataVisualizationLogic' +import type { ySeriesLogicType } from './ySeriesLogicType' + +export interface YSeriesLogicProps { + series: AxisSeries + seriesIndex: number + dataVisualizationProps: DataVisualizationLogicProps +} + +export const ySeriesLogic = kea([ + path(['queries', 'nodes', 'DataVisualization', 'Components', 'ySeriesLogic']), + key((props) => props.series?.column?.name ?? `new-${props.seriesIndex}`), + connect((props: YSeriesLogicProps) => ({ + actions: [dataVisualizationLogic(props.dataVisualizationProps), ['updateYSeries']], + })), + props({ series: EmptyYAxisSeries } as YSeriesLogicProps), + actions({ + setSettingsOpen: (open: boolean) => ({ open }), + }), + reducers({ + isSettingsOpen: [ + false as boolean, + { + setSettingsOpen: (_, { open }) => open, + }, + ], + }), + selectors({ + canOpenSettings: [ + (_s, p) => [p.series], + (series) => { + return series !== EmptyYAxisSeries + }, + ], + }), + forms(({ actions, props }) => ({ + formatting: { + defaults: { + prefix: props.series?.settings?.formatting?.prefix ?? '', + suffix: props.series?.settings?.formatting?.suffix ?? '', + style: props.series?.settings?.formatting?.style ?? 'none', + decimalPlaces: props.series?.settings?.formatting?.decimalPlaces ?? '', + }, + submit: async (format) => { + actions.updateYSeries(props.seriesIndex, props.series.column.name, { + formatting: { + prefix: format.prefix, + suffix: format.suffix, + style: format.style, + decimalPlaces: + format.decimalPlaces === '' ? undefined : parseInt(format.decimalPlaces.toString(), 10), + }, + }) + actions.setSettingsOpen(false) + }, + }, + })), +]) diff --git a/frontend/src/queries/nodes/DataVisualization/dataVisualizationLogic.ts b/frontend/src/queries/nodes/DataVisualization/dataVisualizationLogic.ts index 6d952e01fb809..79d02dd974d13 100644 --- a/frontend/src/queries/nodes/DataVisualization/dataVisualizationLogic.ts +++ b/frontend/src/queries/nodes/DataVisualization/dataVisualizationLogic.ts @@ -1,10 +1,11 @@ import { actions, afterMount, connect, kea, key, listeners, path, props, reducers, selectors } from 'kea' import { subscriptions } from 'kea-subscriptions' +import mergeObject from 'lodash.merge' import { insightSceneLogic } from 'scenes/insights/insightSceneLogic' import { teamLogic } from 'scenes/teamLogic' import { insightVizDataCollectionId } from '~/queries/nodes/InsightViz/InsightViz' -import { AnyResponseType, ChartAxis, DataVisualizationNode } from '~/queries/schema' +import { AnyResponseType, ChartAxis, ChartSettingsFormatting, DataVisualizationNode } from '~/queries/schema' import { QueryContext } from '~/queries/types' import { ChartDisplayType, InsightLogicProps, ItemMode } from '~/types' @@ -24,9 +25,14 @@ export interface Column { dataIndex: number } +export interface AxisSeriesSettings { + formatting?: ChartSettingsFormatting +} + export interface AxisSeries { column: Column data: T[] + settings?: AxisSeriesSettings } export interface DataVisualizationLogicProps { @@ -38,6 +44,52 @@ export interface DataVisualizationLogicProps { cachedResults?: AnyResponseType } +export interface SelectedYAxis { + name: string + settings: AxisSeriesSettings +} + +export const EmptyYAxisSeries: AxisSeries = { + column: { + name: 'None', + type: 'None', + label: 'None', + dataIndex: -1, + }, + data: [], +} + +const DefaultAxisSettings: AxisSeriesSettings = { + formatting: { + prefix: '', + suffix: '', + }, +} + +export const formatDataWithSettings = (data: number, settings?: AxisSeriesSettings): string => { + const decimalPlaces = settings?.formatting?.decimalPlaces + + let dataAsString = `${decimalPlaces ? data.toFixed(decimalPlaces) : data}` + + if (settings?.formatting?.style === 'number') { + dataAsString = data.toLocaleString(undefined, { maximumFractionDigits: decimalPlaces }) + } + + if (settings?.formatting?.style === 'percent') { + dataAsString = `${data.toLocaleString(undefined, { maximumFractionDigits: decimalPlaces })}%` + } + + if (settings?.formatting?.prefix) { + dataAsString = `${settings.formatting.prefix}${dataAsString}` + } + + if (settings?.formatting?.suffix) { + dataAsString = `${dataAsString}${settings.formatting.suffix}` + } + + return dataAsString +} + export const dataVisualizationLogic = kea([ key((props) => props.key), path(['queries', 'nodes', 'DataVisualization', 'dataVisualizationLogic']), @@ -63,11 +115,12 @@ export const dataVisualizationLogic = kea([ updateXSeries: (columnName: string) => ({ columnName, }), - updateYSeries: (seriesIndex: number, columnName: string) => ({ + updateYSeries: (seriesIndex: number, columnName: string, settings?: AxisSeriesSettings) => ({ seriesIndex, columnName, + settings, }), - addYSeries: (columnName?: string) => ({ columnName }), + addYSeries: (columnName?: string, settings?: AxisSeriesSettings) => ({ columnName, settings }), deleteYSeries: (seriesIndex: number) => ({ seriesIndex }), clearAxis: true, setQuery: (node: DataVisualizationNode) => ({ node }), @@ -88,28 +141,36 @@ export const dataVisualizationLogic = kea([ }, ], selectedYAxis: [ - null as (string | null)[] | null, + null as (SelectedYAxis | null)[] | null, { clearAxis: () => null, - addYSeries: (state, { columnName }) => { + addYSeries: (state, { columnName, settings }) => { if (!state && columnName !== undefined) { - return [columnName] + return [{ name: columnName, settings: settings ?? DefaultAxisSettings }] } if (!state) { return [null] } - return [...state, columnName === undefined ? null : columnName] + return [ + ...state, + columnName === undefined + ? null + : { name: columnName, settings: settings ?? DefaultAxisSettings }, + ] }, - updateYSeries: (state, { seriesIndex, columnName }) => { + updateYSeries: (state, { seriesIndex, columnName, settings }) => { if (!state) { return null } const ySeries = [...state] - ySeries[seriesIndex] = columnName + ySeries[seriesIndex] = { + name: columnName, + settings: mergeObject(ySeries[seriesIndex]?.settings ?? {}, settings), + } return ySeries }, deleteYSeries: (state, { seriesIndex }) => { @@ -192,41 +253,47 @@ export const dataVisualizationLogic = kea([ ], yData: [ (state) => [state.selectedYAxis, state.response, state.columns], - (ySeries, response, columns): null | AxisSeries[] => { + (ySeries, response, columns): AxisSeries[] => { if (!response || ySeries === null || ySeries.length === 0) { - return null + return [EmptyYAxisSeries] } const data: any[] = response?.['results'] ?? response?.['result'] ?? [] return ySeries - .map((name): AxisSeries | null => { - if (!name) { - return { - column: { - name: 'None', - type: 'None', - label: 'None', - dataIndex: -1, - }, - data: [], - } + .map((series): AxisSeries | null => { + if (!series) { + return EmptyYAxisSeries } - const column = columns.find((n) => n.name === name) + const column = columns.find((n) => n.name === series.name) if (!column) { - return null + return EmptyYAxisSeries } return { column, data: data.map((n) => { try { - return parseInt(n[column.dataIndex], 10) + const multiplier = series.settings.formatting?.style === 'percent' ? 100 : 1 + + if (series.settings.formatting?.decimalPlaces) { + return parseFloat( + (parseFloat(n[column.dataIndex]) * multiplier).toFixed( + series.settings.formatting.decimalPlaces + ) + ) + } + + const isInt = Number.isInteger(n[column.dataIndex]) + return isInt + ? parseInt(n[column.dataIndex], 10) * multiplier + : parseFloat(n[column.dataIndex]) * multiplier } catch { return 0 } }), + settings: series.settings, } }) .filter((series): series is AxisSeries => Boolean(series)) @@ -260,6 +327,7 @@ export const dataVisualizationLogic = kea([ } }, ], + dataVisualizationProps: [() => [(_, props) => props], (props): DataVisualizationLogicProps => props], }), listeners(({ props }) => ({ setQuery: ({ node }) => { @@ -290,7 +358,7 @@ export const dataVisualizationLogic = kea([ if (yAxis && yAxis.length) { yAxis.forEach((axis) => { - actions.addYSeries(axis.column) + actions.addYSeries(axis.column, axis.settings) }) } } @@ -325,22 +393,23 @@ export const dataVisualizationLogic = kea([ }, selectedXAxis: (value: string | null) => { if (props.setQuery) { - const yColumns = values.selectedYAxis?.filter((n: string | null): n is string => Boolean(n)) ?? [] + const yColumns = + values.selectedYAxis?.filter((n: SelectedYAxis | null): n is SelectedYAxis => Boolean(n)) ?? [] const xColumn: ChartAxis | undefined = value !== null ? { column: value } : undefined props.setQuery({ ...props.query, chartSettings: { ...(props.query.chartSettings ?? {}), - yAxis: yColumns.map((n) => ({ column: n })), + yAxis: yColumns.map((n) => ({ column: n.name, settings: n.settings })), xAxis: xColumn, }, }) } }, - selectedYAxis: (value: (string | null)[] | null) => { + selectedYAxis: (value: (SelectedYAxis | null)[] | null) => { if (props.setQuery) { - const yColumns = value?.filter((n: string | null): n is string => Boolean(n)) ?? [] + const yColumns = value?.filter((n: SelectedYAxis | null): n is SelectedYAxis => Boolean(n)) ?? [] const xColumn: ChartAxis | undefined = values.selectedXAxis !== null ? { column: values.selectedXAxis } : undefined @@ -348,7 +417,7 @@ export const dataVisualizationLogic = kea([ ...props.query, chartSettings: { ...(props.query.chartSettings ?? {}), - yAxis: yColumns.map((n) => ({ column: n })), + yAxis: yColumns.map((n) => ({ column: n.name, settings: n.settings })), xAxis: xColumn, }, }) diff --git a/frontend/src/queries/schema.json b/frontend/src/queries/schema.json index 798d89e51aa27..cbe0a87dc0822 100644 --- a/frontend/src/queries/schema.json +++ b/frontend/src/queries/schema.json @@ -1993,6 +1993,15 @@ "properties": { "column": { "type": "string" + }, + "settings": { + "additionalProperties": false, + "properties": { + "formatting": { + "$ref": "#/definitions/ChartSettingsFormatting" + } + }, + "type": "object" } }, "required": ["column"], @@ -2013,6 +2022,46 @@ ], "type": "string" }, + "ChartSettings": { + "additionalProperties": false, + "properties": { + "goalLines": { + "items": { + "$ref": "#/definitions/GoalLine" + }, + "type": "array" + }, + "xAxis": { + "$ref": "#/definitions/ChartAxis" + }, + "yAxis": { + "items": { + "$ref": "#/definitions/ChartAxis" + }, + "type": "array" + } + }, + "type": "object" + }, + "ChartSettingsFormatting": { + "additionalProperties": false, + "properties": { + "decimalPlaces": { + "type": "number" + }, + "prefix": { + "type": "string" + }, + "style": { + "enum": ["none", "number", "percent"], + "type": "string" + }, + "suffix": { + "type": "string" + } + }, + "type": "object" + }, "ClickhouseQueryProgress": { "additionalProperties": false, "properties": { @@ -2670,25 +2719,7 @@ "additionalProperties": false, "properties": { "chartSettings": { - "additionalProperties": false, - "properties": { - "goalLines": { - "items": { - "$ref": "#/definitions/GoalLine" - }, - "type": "array" - }, - "xAxis": { - "$ref": "#/definitions/ChartAxis" - }, - "yAxis": { - "items": { - "$ref": "#/definitions/ChartAxis" - }, - "type": "array" - } - }, - "type": "object" + "$ref": "#/definitions/ChartSettings" }, "display": { "$ref": "#/definitions/ChartDisplayType" diff --git a/frontend/src/queries/schema.ts b/frontend/src/queries/schema.ts index a3e982f83fd58..cd162e2fa36b0 100644 --- a/frontend/src/queries/schema.ts +++ b/frontend/src/queries/schema.ts @@ -551,9 +551,19 @@ export interface GoalLine { export interface ChartAxis { column: string + settings?: { + formatting?: ChartSettingsFormatting + } +} + +export interface ChartSettingsFormatting { + prefix?: string + suffix?: string + style?: 'none' | 'number' | 'percent' + decimalPlaces?: number } -interface ChartSettings { +export interface ChartSettings { xAxis?: ChartAxis yAxis?: ChartAxis[] goalLines?: GoalLine[] diff --git a/frontend/src/scenes/PreflightCheck/preflightLogic.tsx b/frontend/src/scenes/PreflightCheck/preflightLogic.tsx index 0fd08035c75fc..f55a8b6c97c44 100644 --- a/frontend/src/scenes/PreflightCheck/preflightLogic.tsx +++ b/frontend/src/scenes/PreflightCheck/preflightLogic.tsx @@ -273,6 +273,12 @@ export const preflightLogic = kea([ return preflight?.is_debug }, ], + disableNavigationHooks: [ + (s) => [s.preflight], + (preflight): boolean | undefined => { + return preflight?.dev_disable_navigation_hooks + }, + ], }), listeners(({ values, actions }) => ({ handlePreflightFinished: () => { diff --git a/frontend/src/scenes/early-access-features/InstructionsModal.tsx b/frontend/src/scenes/early-access-features/InstructionsModal.tsx index 61c87c650a8c0..6da1831f1242a 100644 --- a/frontend/src/scenes/early-access-features/InstructionsModal.tsx +++ b/frontend/src/scenes/early-access-features/InstructionsModal.tsx @@ -3,8 +3,9 @@ import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' import EarlyAccessFeatureImage from 'public/early-access-feature-demo.png' import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' +import { urls } from 'scenes/urls' -import { FeatureFlagType } from '~/types' +import { FeatureFlagType, PipelineStage, Region } from '~/types' interface InstructionsModalProps { flag: FeatureFlagType['key'] @@ -25,7 +26,15 @@ export function InstructionsModal({ onClose, visible, flag }: InstructionsModalP header: 'Option 1: Widget Site App', content: (
- Give your users a prebuilt widget{' '} + Give your users a{' '} + + prebuilt widget + {' '} to opt-in to features
diff --git a/frontend/src/scenes/insights/insightSceneLogic.tsx b/frontend/src/scenes/insights/insightSceneLogic.tsx index 75e99677715a4..8ecaf9f4de564 100644 --- a/frontend/src/scenes/insights/insightSceneLogic.tsx +++ b/frontend/src/scenes/insights/insightSceneLogic.tsx @@ -29,7 +29,7 @@ export const insightSceneLogic = kea([ path(['scenes', 'insights', 'insightSceneLogic']), connect(() => ({ logic: [eventUsageLogic], - values: [teamLogic, ['currentTeam'], sceneLogic, ['activeScene'], preflightLogic, ['isDev']], + values: [teamLogic, ['currentTeam'], sceneLogic, ['activeScene'], preflightLogic, ['disableNavigationHooks']], })), actions({ setInsightId: (insightId: InsightShortId) => ({ insightId }), @@ -322,8 +322,7 @@ export const insightSceneLogic = kea([ return false } - if (values.isDev) { - // TRICKY: We disable beforeUnload handling in dev, but ONLY for insights + if (values.disableNavigationHooks) { return false } diff --git a/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.tsx b/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.tsx index bf6a1c8f67a94..7cf2c2d226164 100644 --- a/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.tsx +++ b/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.tsx @@ -267,8 +267,6 @@ export function InsightsTable({ columns.push(...valueColumns) } - const totalItems = indexedResults.length - return ( { - const isPrevious = !!item.compare && item.compare_label === 'previous' - const adjustedIndex = isPrevious ? item.seriesIndex - totalItems / 2 : item.seriesIndex - return getTrendLikeSeriesColor(adjustedIndex, isPrevious) - } + ? (item) => + getTrendLikeSeriesColor(item.colorIndex, !!item.compare && item.compare_label === 'previous') : undefined } firstColumnSticky diff --git a/frontend/src/scenes/insights/views/InsightsTable/columns/SeriesColumn.tsx b/frontend/src/scenes/insights/views/InsightsTable/columns/SeriesColumn.tsx index b7a058c4f69b7..a77df94c46270 100644 --- a/frontend/src/scenes/insights/views/InsightsTable/columns/SeriesColumn.tsx +++ b/frontend/src/scenes/insights/views/InsightsTable/columns/SeriesColumn.tsx @@ -25,14 +25,12 @@ export function SeriesColumnItem({ }: SeriesColumnItemProps): JSX.Element { const showCountedByTag = !!indexedResults.find(({ action }) => action?.math && action.math !== 'total') - const totalItems = indexedResults.length const isPrevious = !!item.compare && item.compare_label === 'previous' - const adjustedIndex = isPrevious ? item.seriesIndex - totalItems / 2 : item.seriesIndex return (
, totalDatasets: number): ChartDataset { + function processDataset(dataset: ChartDataset): ChartDataset { const isPrevious = !!dataset.compare && dataset.compare_label === 'previous' - const adjustedIndex = isPrevious ? dataset.seriesIndex - totalDatasets / 2 : dataset.seriesIndex const mainColor = dataset?.status ? getBarColorFromStatus(dataset.status) - : getTrendLikeSeriesColor(adjustedIndex, isPrevious && !isArea) + : getTrendLikeSeriesColor(dataset?.colorIndex ?? dataset.seriesIndex, isPrevious && !isArea) const hoverColor = dataset?.status ? getBarColorFromStatus(dataset.status, true) : mainColor const areaBackgroundColor = hexToRGBA(mainColor, 0.5) const areaIncompletePattern = createPinstripePattern(areaBackgroundColor, isDarkModeOn) @@ -391,7 +390,7 @@ export function LineGraph_({ } } - datasets = datasets.map((dataset) => processDataset(dataset, datasets.length)) + datasets = datasets.map(processDataset) const seriesNonZeroMax = Math.max(...datasets.flatMap((d) => d.data).filter((n) => !!n && n !== LOG_ZERO)) const seriesNonZeroMin = Math.min(...datasets.flatMap((d) => d.data).filter((n) => !!n && n !== LOG_ZERO)) diff --git a/frontend/src/scenes/notebooks/Nodes/NodeWrapper.tsx b/frontend/src/scenes/notebooks/Nodes/NodeWrapper.tsx index 64f079536d670..c0ddb29364f2d 100644 --- a/frontend/src/scenes/notebooks/Nodes/NodeWrapper.tsx +++ b/frontend/src/scenes/notebooks/Nodes/NodeWrapper.tsx @@ -259,11 +259,13 @@ function NodeWrapper(props: NodeWrapperP {Settings && editingNodeId === nodeId && containerSize === 'small' ? (
- + + +
) : null} @@ -278,7 +280,12 @@ function NodeWrapper(props: NodeWrapperP onClick={!expanded && expandOnClick ? () => setExpanded(true) : undefined} onMouseDown={onResizeStart} > - + + +
)} diff --git a/frontend/src/scenes/pipeline/Pipeline.tsx b/frontend/src/scenes/pipeline/Pipeline.tsx index da7612b887287..c988f6d5f132a 100644 --- a/frontend/src/scenes/pipeline/Pipeline.tsx +++ b/frontend/src/scenes/pipeline/Pipeline.tsx @@ -1,11 +1,12 @@ import { useValues } from 'kea' import { router } from 'kea-router' -import { LemonTabs } from 'lib/lemon-ui/LemonTabs' +import { ActivityLog } from 'lib/components/ActivityLog/ActivityLog' +import { ConcreteLemonTab, LemonTabs } from 'lib/lemon-ui/LemonTabs' import { DataWarehouseManagedSourcesTable } from 'scenes/data-warehouse/settings/DataWarehouseManagedSourcesTable' import { SceneExport } from 'scenes/sceneTypes' import { urls } from 'scenes/urls' -import { PipelineTab } from '~/types' +import { ActivityScope, PipelineTab } from '~/types' import { AppsManagement } from './AppsManagement' import { Destinations } from './destinations/Destinations' @@ -22,40 +23,32 @@ export function Pipeline(): JSX.Element { const { currentTab } = useValues(pipelineLogic) const { hasEnabledImportApps } = useValues(importAppsLogic) - let tabToContent: Partial> = { - [PipelineTab.Overview]: , - [PipelineTab.Transformations]: , - [PipelineTab.Destinations]: , - [PipelineTab.SiteApps]: , - [PipelineTab.DataImport]: , - } + const tabs: Pick, 'key' | 'content'>[] = [ + { key: PipelineTab.Overview, content: }, + { key: PipelineTab.Transformations, content: }, + { key: PipelineTab.Destinations, content: }, + { key: PipelineTab.SiteApps, content: }, + { key: PipelineTab.DataImport, content: }, + ] + // Import apps are deprecated, we only show the tab if there are some still enabled if (hasEnabledImportApps) { - tabToContent = { - ...tabToContent, - [PipelineTab.ImportApps]: , - } + tabs.push({ key: PipelineTab.ImportApps, content: }) } if (canGloballyManagePlugins) { - tabToContent = { - ...tabToContent, - [PipelineTab.AppsManagement]: , - } + tabs.push({ key: PipelineTab.AppsManagement, content: }) } + tabs.push({ key: PipelineTab.History, content: }) + return (
router.actions.push(urls.pipeline(tab as PipelineTab))} - tabs={Object.entries(tabToContent).map(([tab, content]) => ({ - label: ( - - {humanFriendlyTabName(tab as PipelineTab)}{' '} - - ), - key: tab, - content: content, + tabs={tabs.map((tab) => ({ + ...tab, + label: humanFriendlyTabName(tab.key), }))} />
diff --git a/frontend/src/scenes/pipeline/PipelineNode.tsx b/frontend/src/scenes/pipeline/PipelineNode.tsx index ea982b3826889..fe0523e8810f8 100644 --- a/frontend/src/scenes/pipeline/PipelineNode.tsx +++ b/frontend/src/scenes/pipeline/PipelineNode.tsx @@ -67,7 +67,7 @@ export function PipelineNode(params: { stage?: string; id?: string } = {}): JSX. tabToContent[PipelineNodeTab.Runs] = } - if ([PipelineBackend.Plugin, PipelineBackend.BatchExport].includes(node.backend)) { + if (node.backend === PipelineBackend.Plugin) { tabToContent[PipelineNodeTab.History] = } diff --git a/frontend/src/scenes/pipeline/hogfunctions/hogFunctionConfigurationLogic.tsx b/frontend/src/scenes/pipeline/hogfunctions/hogFunctionConfigurationLogic.tsx index e176509417927..45915794da5f9 100644 --- a/frontend/src/scenes/pipeline/hogfunctions/hogFunctionConfigurationLogic.tsx +++ b/frontend/src/scenes/pipeline/hogfunctions/hogFunctionConfigurationLogic.tsx @@ -340,7 +340,8 @@ export const hogFunctionConfigurationLogic = kea { - switch (tab) { - case PipelineTab.Overview: - return 'Overview' - case PipelineTab.Transformations: - return 'Transformations' - case PipelineTab.Destinations: - return 'Destinations' - case PipelineTab.DataImport: - return 'Data import' - case PipelineTab.SiteApps: - return 'Site apps' - case PipelineTab.ImportApps: - return 'Legacy sources' - case PipelineTab.AppsManagement: - return 'Apps management' - } + return capitalizeFirstLetter(tab).replace(/[-_]/g, ' ') } export const pipelineLogic = kea([ @@ -46,7 +33,7 @@ export const pipelineLogic = kea([ selectors(() => ({ breadcrumbs: [ (s) => [s.currentTab], - (tab): Breadcrumb[] => { + (tab: PipelineTab): Breadcrumb[] => { return [ { key: Scene.Pipeline, name: 'Data pipeline' }, { @@ -56,6 +43,15 @@ export const pipelineLogic = kea([ ] }, ], + + activityFilters: [ + () => [], + (): ActivityFilters | null => { + return { + scope: ActivityScope.PLUGIN, + } + }, + ], })), actionToUrl(({ values }) => { return { diff --git a/frontend/src/scenes/pipeline/pipelineNodeLogic.tsx b/frontend/src/scenes/pipeline/pipelineNodeLogic.tsx index a96681205f778..03459d488c5da 100644 --- a/frontend/src/scenes/pipeline/pipelineNodeLogic.tsx +++ b/frontend/src/scenes/pipeline/pipelineNodeLogic.tsx @@ -4,7 +4,8 @@ import { capitalizeFirstLetter } from 'lib/utils' import { Scene } from 'scenes/sceneTypes' import { urls } from 'scenes/urls' -import { Breadcrumb, PipelineNodeTab, PipelineStage } from '~/types' +import { ActivityFilters } from '~/layout/navigation-3000/sidepanel/panels/activity/activityForSceneLogic' +import { ActivityScope, Breadcrumb, PipelineNodeTab, PipelineStage } from '~/types' import type { pipelineNodeLogicType } from './pipelineNodeLogicType' import { NODE_STAGE_TO_PIPELINE_TAB } from './pipelineNodeNewLogic' @@ -73,6 +74,18 @@ export const pipelineNodeLogic = kea([ ], ], + activityFilters: [ + (s) => [s.node], + (node): ActivityFilters | null => { + return node.backend === PipelineBackend.Plugin + ? { + scope: ActivityScope.PLUGIN, + item_id: `${node.id}`, + } + : null + }, + ], + nodeBackend: [ (s) => [s.node], (node): PipelineBackend => { diff --git a/frontend/src/scenes/session-recordings/player/playerMetaLogic.ts b/frontend/src/scenes/session-recordings/player/playerMetaLogic.ts index a4f1e2667ae36..56f574c407712 100644 --- a/frontend/src/scenes/session-recordings/player/playerMetaLogic.ts +++ b/frontend/src/scenes/session-recordings/player/playerMetaLogic.ts @@ -31,7 +31,7 @@ export const playerMetaLogic = kea([ sessionRecordingPlayerLogic(props), ['scale', 'currentTimestamp', 'currentPlayerTime', 'currentSegment'], sessionRecordingsListPropertiesLogic, - ['recordingPropertiesById'], + ['recordingPropertiesById', 'recordingPropertiesLoading'], ], actions: [ sessionRecordingDataLogic(props), @@ -139,7 +139,7 @@ export const playerMetaLogic = kea([ })), listeners(({ actions, values }) => ({ loadRecordingMetaSuccess: () => { - if (values.sessionPlayerMetaData) { + if (values.sessionPlayerMetaData && !values.recordingPropertiesLoading) { actions.maybeLoadPropertiesForSessions([values.sessionPlayerMetaData]) } }, diff --git a/frontend/src/scenes/settings/project/AddMembersModal.tsx b/frontend/src/scenes/settings/project/AddMembersModal.tsx index ea355fa6429e0..cd010afc77bff 100644 --- a/frontend/src/scenes/settings/project/AddMembersModal.tsx +++ b/frontend/src/scenes/settings/project/AddMembersModal.tsx @@ -2,7 +2,6 @@ import { IconPlus } from '@posthog/icons' import { LemonButton, LemonModal, LemonSelect, LemonSelectOption } from '@posthog/lemon-ui' import { useValues } from 'kea' import { Form } from 'kea-forms' -import { RestrictedComponentProps } from 'lib/components/RestrictedArea' import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic' import { usersLemonSelectOptions } from 'lib/components/UserSelectItem' import { TeamMembershipLevel } from 'lib/constants' @@ -17,7 +16,7 @@ import { AvailableFeature } from '~/types' import { teamMembersLogic } from './teamMembersLogic' -export function AddMembersModalWithButton({ isRestricted }: RestrictedComponentProps): JSX.Element { +export function AddMembersModalWithButton({ disabledReason }: { disabledReason: string | null }): JSX.Element { const { addableMembers, allMembersLoading } = useValues(teamMembersLogic) const { currentTeam } = useValues(teamLogic) const { guardAvailableFeature } = useValues(upgradeModalLogic) @@ -42,7 +41,7 @@ export function AddMembersModalWithButton({ isRestricted }: RestrictedComponentP }) } icon={} - disabled={isRestricted} + disabledReason={disabledReason} > Add members to project diff --git a/frontend/src/scenes/settings/project/ManagedReverseProxy.tsx b/frontend/src/scenes/settings/project/ManagedReverseProxy.tsx index dc753a32a35ab..8e0f527984b02 100644 --- a/frontend/src/scenes/settings/project/ManagedReverseProxy.tsx +++ b/frontend/src/scenes/settings/project/ManagedReverseProxy.tsx @@ -16,6 +16,8 @@ import { useActions, useValues } from 'kea' import { Form } from 'kea-forms' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' import { PayGateMini } from 'lib/components/PayGateMini/PayGateMini' +import { RestrictionScope, useRestrictedArea } from 'lib/components/RestrictedArea' +import { OrganizationMembershipLevel } from 'lib/constants' import { LemonField } from 'lib/lemon-ui/LemonField' import { LemonMarkdown } from 'lib/lemon-ui/LemonMarkdown' @@ -34,6 +36,11 @@ export function ManagedReverseProxy(): JSX.Element { const { formState, proxyRecords, proxyRecordsLoading } = useValues(proxyLogic) const { showForm, deleteRecord } = useActions(proxyLogic) + const restrictionReason = useRestrictedArea({ + minimumAccessLevel: OrganizationMembershipLevel.Admin, + scope: RestrictionScope.Organization, + }) + const maxRecordsReached = proxyRecords.length >= MAX_PROXY_RECORDS const recordsWithMessages = proxyRecords.filter((record) => !!record.message) @@ -84,7 +91,8 @@ export function ManagedReverseProxy(): JSX.Element { className: 'flex justify-center', render: function Render(_, { id, status }) { return ( - status != 'deleting' && ( + status != 'deleting' && + !restrictionReason && ( ) : ( - }> - New managed proxy - +
+ } + disabledReason={restrictionReason} + > + New managed proxy + +
) ) : ( diff --git a/frontend/src/scenes/settings/project/ProjectAccessControl.tsx b/frontend/src/scenes/settings/project/ProjectAccessControl.tsx index fbe81e1942624..5ba42e3a9f2de 100644 --- a/frontend/src/scenes/settings/project/ProjectAccessControl.tsx +++ b/frontend/src/scenes/settings/project/ProjectAccessControl.tsx @@ -1,7 +1,7 @@ import { IconCrown, IconLeave, IconLock, IconUnlock } from '@posthog/icons' import { LemonButton, LemonSelect, LemonSelectOption, LemonSnack, LemonSwitch, LemonTable } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' -import { RestrictedArea, RestrictionScope, useRestrictedArea } from 'lib/components/RestrictedArea' +import { RestrictionScope, useRestrictedArea } from 'lib/components/RestrictedArea' import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic' import { OrganizationMembershipLevel, TeamMembershipLevel } from 'lib/constants' import { IconCancel } from 'lib/lemon-ui/icons' @@ -133,6 +133,10 @@ function ActionsComponent(member: FusedTeamMemberType): JSX.Element | null { export function ProjectTeamMembers(): JSX.Element | null { const { user } = useValues(userLogic) const { allMembers, allMembersLoading } = useValues(teamMembersLogic) + const restrictionReason = useRestrictedArea({ + minimumAccessLevel: OrganizationMembershipLevel.Admin, + scope: RestrictionScope.Project, + }) if (!user) { return null @@ -187,11 +191,7 @@ export function ProjectTeamMembers(): JSX.Element | null { <>

Members with Project Access - +

{ await expectLogic(logic, () => { builtDataNodeLogic.actions.loadDataSuccess(insight) }).toMatchValues({ - indexedResults: [{ ...trendResult.result[0], id: 0, seriesIndex: 0 }], + indexedResults: [{ ...trendResult.result[0], id: 0, seriesIndex: 0, colorIndex: 0 }], }) }) diff --git a/frontend/src/scenes/trends/trendsDataLogic.ts b/frontend/src/scenes/trends/trendsDataLogic.ts index c9bad2bb81650..c4e767137d737 100644 --- a/frontend/src/scenes/trends/trendsDataLogic.ts +++ b/frontend/src/scenes/trends/trendsDataLogic.ts @@ -158,7 +158,21 @@ export const trendsDataLogic = kea([ defaultLifecyclesOrder.indexOf(String(a.status)) ) } - return indexedResults.map((result, index) => ({ ...result, id: index })) + + /** Unique series in the results, determined by `item.label` and `item.action.order`. */ + const uniqSeries = Array.from( + // :TRICKY: Stickiness insights don't have an `action` object, despite + // types here not reflecting that. + new Set(indexedResults.map((item) => `${item.label}_${item.action?.order}`)) + ) + + // Give current and previous versions of the same dataset the same colorIndex + return indexedResults.map((item, index) => { + const colorIndex = uniqSeries.findIndex( + (identifier) => identifier === `${item.label}_${item.action?.order}` + ) + return { ...item, colorIndex: colorIndex, id: index } + }) }, ], diff --git a/frontend/src/scenes/trends/types.ts b/frontend/src/scenes/trends/types.ts index d0cb7ea6cc8a0..af9f06e502c44 100644 --- a/frontend/src/scenes/trends/types.ts +++ b/frontend/src/scenes/trends/types.ts @@ -16,6 +16,10 @@ export interface IndexedTrendResult extends TrendResult { * specific order (e.g. for pie chart). The series index is used e.g. to * get series color correctly. */ seriesIndex: number + /** An index computed in trendsDataLogic that is used to generate colors. This index is the same for current and previous + * series with the same label. The previous series is given a slightly lighter version of the same color. + * */ + colorIndex: number } export interface TrendActors { diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 964667b36ec58..bb3e1bb7638dd 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -660,6 +660,7 @@ export enum PipelineTab { DataImport = 'data-import', ImportApps = 'legacy-sources', AppsManagement = 'apps-management', + History = 'history', } export enum PipelineStage { @@ -2965,6 +2966,7 @@ export interface PreflightStatus { buffer_conversion_seconds?: number object_storage: boolean public_egress_ip_addresses?: string[] + dev_disable_navigation_hooks?: boolean } export enum ItemMode { // todo: consolidate this and dashboardmode diff --git a/hogql_parser/HogQLParser.cpp b/hogql_parser/HogQLParser.cpp index 00d7c0e7b68de..e2021ef8c06ae 100644 --- a/hogql_parser/HogQLParser.cpp +++ b/hogql_parser/HogQLParser.cpp @@ -581,7 +581,7 @@ void hogqlparserParserInitialize() { 1265,5,105,0,0,1262,1265,3,152,76,0,1263,1265,3,154,77,0,1264,1261,1, 0,0,0,1264,1262,1,0,0,0,1264,1263,1,0,0,0,1265,161,1,0,0,0,1266,1267, 3,166,83,0,1267,1268,5,122,0,0,1268,1269,3,148,74,0,1269,163,1,0,0,0, - 1270,1271,5,128,0,0,1271,1272,3,160,80,0,1272,1273,5,147,0,0,1273,165, + 1270,1271,5,128,0,0,1271,1272,3,134,67,0,1272,1273,5,147,0,0,1273,165, 1,0,0,0,1274,1277,5,110,0,0,1275,1277,3,168,84,0,1276,1274,1,0,0,0,1276, 1275,1,0,0,0,1277,167,1,0,0,0,1278,1282,5,142,0,0,1279,1281,3,170,85, 0,1280,1279,1,0,0,0,1281,1284,1,0,0,0,1282,1280,1,0,0,0,1282,1283,1,0, @@ -11733,8 +11733,8 @@ tree::TerminalNode* HogQLParser::PlaceholderContext::LBRACE() { return getToken(HogQLParser::LBRACE, 0); } -HogQLParser::IdentifierContext* HogQLParser::PlaceholderContext::identifier() { - return getRuleContext(0); +HogQLParser::NestedIdentifierContext* HogQLParser::PlaceholderContext::nestedIdentifier() { + return getRuleContext(0); } tree::TerminalNode* HogQLParser::PlaceholderContext::RBRACE() { @@ -11770,7 +11770,7 @@ HogQLParser::PlaceholderContext* HogQLParser::placeholder() { setState(1270); match(HogQLParser::LBRACE); setState(1271); - identifier(); + nestedIdentifier(); setState(1272); match(HogQLParser::RBRACE); diff --git a/hogql_parser/HogQLParser.h b/hogql_parser/HogQLParser.h index d5a5253ad25f0..acabb96a0baa5 100644 --- a/hogql_parser/HogQLParser.h +++ b/hogql_parser/HogQLParser.h @@ -2411,7 +2411,7 @@ class HogQLParser : public antlr4::Parser { PlaceholderContext(antlr4::ParserRuleContext *parent, size_t invokingState); virtual size_t getRuleIndex() const override; antlr4::tree::TerminalNode *LBRACE(); - IdentifierContext *identifier(); + NestedIdentifierContext *nestedIdentifier(); antlr4::tree::TerminalNode *RBRACE(); diff --git a/hogql_parser/HogQLParser.interp b/hogql_parser/HogQLParser.interp index e31bf92fee7e9..183059ec0fd79 100644 --- a/hogql_parser/HogQLParser.interp +++ b/hogql_parser/HogQLParser.interp @@ -414,4 +414,4 @@ stringContentsFull atn: -[4, 1, 159, 1311, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 1, 0, 5, 0, 178, 8, 0, 10, 0, 12, 0, 181, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 3, 1, 187, 8, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 196, 8, 3, 1, 4, 1, 4, 1, 4, 5, 4, 201, 8, 4, 10, 4, 12, 4, 204, 9, 4, 1, 4, 3, 4, 207, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 221, 8, 5, 1, 6, 1, 6, 3, 6, 225, 8, 6, 1, 6, 3, 6, 228, 8, 6, 1, 7, 1, 7, 3, 7, 232, 8, 7, 1, 7, 3, 7, 235, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 242, 8, 8, 1, 8, 1, 8, 3, 8, 246, 8, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 5, 9, 253, 8, 9, 10, 9, 12, 9, 256, 9, 9, 1, 9, 1, 9, 3, 9, 260, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 269, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 277, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 284, 8, 12, 1, 12, 1, 12, 3, 12, 288, 8, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 294, 8, 12, 1, 12, 1, 12, 1, 12, 3, 12, 299, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 307, 8, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 314, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 320, 8, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 3, 16, 332, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 5, 18, 338, 8, 18, 10, 18, 12, 18, 341, 9, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 5, 20, 352, 8, 20, 10, 20, 12, 20, 355, 9, 20, 1, 20, 3, 20, 358, 8, 20, 1, 21, 1, 21, 1, 21, 3, 21, 363, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 371, 8, 22, 10, 22, 12, 22, 374, 9, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 382, 8, 23, 1, 24, 3, 24, 385, 8, 24, 1, 24, 1, 24, 3, 24, 389, 8, 24, 1, 24, 3, 24, 392, 8, 24, 1, 24, 1, 24, 3, 24, 396, 8, 24, 1, 24, 3, 24, 399, 8, 24, 1, 24, 3, 24, 402, 8, 24, 1, 24, 3, 24, 405, 8, 24, 1, 24, 3, 24, 408, 8, 24, 1, 24, 1, 24, 3, 24, 412, 8, 24, 1, 24, 1, 24, 3, 24, 416, 8, 24, 1, 24, 3, 24, 419, 8, 24, 1, 24, 3, 24, 422, 8, 24, 1, 24, 3, 24, 425, 8, 24, 1, 24, 1, 24, 3, 24, 429, 8, 24, 1, 24, 3, 24, 432, 8, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 441, 8, 26, 1, 27, 1, 27, 1, 27, 1, 28, 3, 28, 447, 8, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 466, 8, 29, 10, 29, 12, 29, 469, 9, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 3, 32, 485, 8, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 502, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 508, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 514, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 525, 8, 36, 3, 36, 527, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 3, 39, 538, 8, 39, 1, 39, 3, 39, 541, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 547, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 555, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 5, 39, 561, 8, 39, 10, 39, 12, 39, 564, 9, 39, 1, 40, 3, 40, 567, 8, 40, 1, 40, 1, 40, 1, 40, 3, 40, 572, 8, 40, 1, 40, 3, 40, 575, 8, 40, 1, 40, 3, 40, 578, 8, 40, 1, 40, 1, 40, 3, 40, 582, 8, 40, 1, 40, 1, 40, 3, 40, 586, 8, 40, 1, 40, 3, 40, 589, 8, 40, 3, 40, 591, 8, 40, 1, 40, 3, 40, 594, 8, 40, 1, 40, 1, 40, 3, 40, 598, 8, 40, 1, 40, 1, 40, 3, 40, 602, 8, 40, 1, 40, 3, 40, 605, 8, 40, 3, 40, 607, 8, 40, 3, 40, 609, 8, 40, 1, 41, 1, 41, 1, 41, 3, 41, 614, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 625, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 631, 8, 43, 1, 44, 1, 44, 1, 44, 5, 44, 636, 8, 44, 10, 44, 12, 44, 639, 9, 44, 1, 45, 1, 45, 3, 45, 643, 8, 45, 1, 45, 1, 45, 3, 45, 647, 8, 45, 1, 45, 1, 45, 3, 45, 651, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 657, 8, 46, 3, 46, 659, 8, 46, 1, 47, 1, 47, 1, 47, 5, 47, 664, 8, 47, 10, 47, 12, 47, 667, 9, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 3, 49, 674, 8, 49, 1, 49, 3, 49, 677, 8, 49, 1, 49, 3, 49, 680, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 699, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 713, 8, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 727, 8, 56, 10, 56, 12, 56, 730, 9, 56, 1, 56, 3, 56, 733, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 742, 8, 56, 10, 56, 12, 56, 745, 9, 56, 1, 56, 3, 56, 748, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 757, 8, 56, 10, 56, 12, 56, 760, 9, 56, 1, 56, 3, 56, 763, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 770, 8, 56, 1, 56, 1, 56, 3, 56, 774, 8, 56, 1, 57, 1, 57, 1, 57, 5, 57, 779, 8, 57, 10, 57, 12, 57, 782, 9, 57, 1, 57, 3, 57, 785, 8, 57, 1, 58, 1, 58, 1, 58, 3, 58, 790, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 4, 58, 797, 8, 58, 11, 58, 12, 58, 798, 1, 58, 1, 58, 3, 58, 803, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 827, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 844, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 850, 8, 58, 1, 58, 3, 58, 853, 8, 58, 1, 58, 3, 58, 856, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 866, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 872, 8, 58, 1, 58, 3, 58, 875, 8, 58, 1, 58, 3, 58, 878, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 886, 8, 58, 1, 58, 3, 58, 889, 8, 58, 1, 58, 1, 58, 3, 58, 893, 8, 58, 1, 58, 3, 58, 896, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 910, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 927, 8, 58, 1, 58, 1, 58, 1, 58, 3, 58, 932, 8, 58, 1, 58, 1, 58, 3, 58, 936, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 942, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 949, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 961, 8, 58, 1, 58, 1, 58, 3, 58, 965, 8, 58, 1, 58, 3, 58, 968, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 977, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 991, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 1030, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 1038, 8, 58, 5, 58, 1040, 8, 58, 10, 58, 12, 58, 1043, 9, 58, 1, 59, 1, 59, 1, 59, 5, 59, 1048, 8, 59, 10, 59, 12, 59, 1051, 9, 59, 1, 59, 3, 59, 1054, 8, 59, 1, 60, 1, 60, 3, 60, 1058, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 1064, 8, 61, 10, 61, 12, 61, 1067, 9, 61, 1, 61, 3, 61, 1070, 8, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 1077, 8, 61, 10, 61, 12, 61, 1080, 9, 61, 1, 61, 3, 61, 1083, 8, 61, 3, 61, 1085, 8, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 5, 62, 1093, 8, 62, 10, 62, 12, 62, 1096, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 5, 62, 1104, 8, 62, 10, 62, 12, 62, 1107, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 1115, 8, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 1122, 8, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 1135, 8, 63, 1, 64, 1, 64, 1, 64, 5, 64, 1140, 8, 64, 10, 64, 12, 64, 1143, 9, 64, 1, 64, 3, 64, 1146, 8, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 1158, 8, 65, 1, 66, 1, 66, 1, 66, 1, 66, 3, 66, 1164, 8, 66, 1, 66, 3, 66, 1167, 8, 66, 1, 67, 1, 67, 1, 67, 5, 67, 1172, 8, 67, 10, 67, 12, 67, 1175, 9, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1186, 8, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1192, 8, 68, 5, 68, 1194, 8, 68, 10, 68, 12, 68, 1197, 9, 68, 1, 69, 1, 69, 1, 69, 3, 69, 1202, 8, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 3, 70, 1209, 8, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 5, 71, 1216, 8, 71, 10, 71, 12, 71, 1219, 9, 71, 1, 71, 3, 71, 1222, 8, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 1232, 8, 73, 3, 73, 1234, 8, 73, 1, 74, 3, 74, 1237, 8, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 1245, 8, 74, 1, 75, 1, 75, 1, 75, 3, 75, 1250, 8, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 3, 79, 1260, 8, 79, 1, 80, 1, 80, 1, 80, 3, 80, 1265, 8, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 3, 83, 1277, 8, 83, 1, 84, 1, 84, 5, 84, 1281, 8, 84, 10, 84, 12, 84, 1284, 9, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 3, 85, 1293, 8, 85, 1, 86, 1, 86, 5, 86, 1297, 8, 86, 10, 86, 12, 86, 1300, 9, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 3, 87, 1309, 8, 87, 1, 87, 0, 3, 78, 116, 136, 88, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 0, 16, 2, 0, 18, 18, 74, 74, 2, 0, 44, 44, 51, 51, 3, 0, 1, 1, 4, 4, 8, 8, 4, 0, 1, 1, 3, 4, 8, 8, 80, 80, 2, 0, 51, 51, 73, 73, 2, 0, 1, 1, 4, 4, 2, 0, 7, 7, 22, 23, 2, 0, 30, 30, 49, 49, 2, 0, 71, 71, 76, 76, 3, 0, 10, 10, 50, 50, 90, 90, 2, 0, 41, 41, 53, 53, 1, 0, 107, 108, 2, 0, 118, 118, 139, 139, 7, 0, 21, 21, 38, 38, 55, 56, 70, 70, 78, 78, 97, 97, 103, 103, 16, 0, 1, 13, 15, 20, 22, 28, 30, 30, 32, 37, 39, 42, 44, 51, 53, 54, 58, 58, 60, 69, 71, 77, 79, 83, 85, 92, 94, 96, 98, 99, 101, 102, 4, 0, 20, 20, 30, 30, 39, 39, 48, 48, 1479, 0, 179, 1, 0, 0, 0, 2, 186, 1, 0, 0, 0, 4, 188, 1, 0, 0, 0, 6, 190, 1, 0, 0, 0, 8, 197, 1, 0, 0, 0, 10, 220, 1, 0, 0, 0, 12, 222, 1, 0, 0, 0, 14, 229, 1, 0, 0, 0, 16, 236, 1, 0, 0, 0, 18, 249, 1, 0, 0, 0, 20, 261, 1, 0, 0, 0, 22, 270, 1, 0, 0, 0, 24, 278, 1, 0, 0, 0, 26, 300, 1, 0, 0, 0, 28, 315, 1, 0, 0, 0, 30, 324, 1, 0, 0, 0, 32, 329, 1, 0, 0, 0, 34, 333, 1, 0, 0, 0, 36, 335, 1, 0, 0, 0, 38, 344, 1, 0, 0, 0, 40, 348, 1, 0, 0, 0, 42, 362, 1, 0, 0, 0, 44, 366, 1, 0, 0, 0, 46, 381, 1, 0, 0, 0, 48, 384, 1, 0, 0, 0, 50, 433, 1, 0, 0, 0, 52, 436, 1, 0, 0, 0, 54, 442, 1, 0, 0, 0, 56, 446, 1, 0, 0, 0, 58, 452, 1, 0, 0, 0, 60, 470, 1, 0, 0, 0, 62, 473, 1, 0, 0, 0, 64, 476, 1, 0, 0, 0, 66, 486, 1, 0, 0, 0, 68, 489, 1, 0, 0, 0, 70, 493, 1, 0, 0, 0, 72, 526, 1, 0, 0, 0, 74, 528, 1, 0, 0, 0, 76, 531, 1, 0, 0, 0, 78, 546, 1, 0, 0, 0, 80, 608, 1, 0, 0, 0, 82, 613, 1, 0, 0, 0, 84, 624, 1, 0, 0, 0, 86, 626, 1, 0, 0, 0, 88, 632, 1, 0, 0, 0, 90, 640, 1, 0, 0, 0, 92, 658, 1, 0, 0, 0, 94, 660, 1, 0, 0, 0, 96, 668, 1, 0, 0, 0, 98, 673, 1, 0, 0, 0, 100, 681, 1, 0, 0, 0, 102, 685, 1, 0, 0, 0, 104, 689, 1, 0, 0, 0, 106, 698, 1, 0, 0, 0, 108, 712, 1, 0, 0, 0, 110, 714, 1, 0, 0, 0, 112, 773, 1, 0, 0, 0, 114, 775, 1, 0, 0, 0, 116, 935, 1, 0, 0, 0, 118, 1044, 1, 0, 0, 0, 120, 1057, 1, 0, 0, 0, 122, 1084, 1, 0, 0, 0, 124, 1121, 1, 0, 0, 0, 126, 1134, 1, 0, 0, 0, 128, 1136, 1, 0, 0, 0, 130, 1157, 1, 0, 0, 0, 132, 1166, 1, 0, 0, 0, 134, 1168, 1, 0, 0, 0, 136, 1185, 1, 0, 0, 0, 138, 1198, 1, 0, 0, 0, 140, 1208, 1, 0, 0, 0, 142, 1212, 1, 0, 0, 0, 144, 1223, 1, 0, 0, 0, 146, 1233, 1, 0, 0, 0, 148, 1236, 1, 0, 0, 0, 150, 1249, 1, 0, 0, 0, 152, 1251, 1, 0, 0, 0, 154, 1253, 1, 0, 0, 0, 156, 1255, 1, 0, 0, 0, 158, 1259, 1, 0, 0, 0, 160, 1264, 1, 0, 0, 0, 162, 1266, 1, 0, 0, 0, 164, 1270, 1, 0, 0, 0, 166, 1276, 1, 0, 0, 0, 168, 1278, 1, 0, 0, 0, 170, 1292, 1, 0, 0, 0, 172, 1294, 1, 0, 0, 0, 174, 1308, 1, 0, 0, 0, 176, 178, 3, 2, 1, 0, 177, 176, 1, 0, 0, 0, 178, 181, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 182, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 182, 183, 5, 0, 0, 1, 183, 1, 1, 0, 0, 0, 184, 187, 3, 6, 3, 0, 185, 187, 3, 10, 5, 0, 186, 184, 1, 0, 0, 0, 186, 185, 1, 0, 0, 0, 187, 3, 1, 0, 0, 0, 188, 189, 3, 116, 58, 0, 189, 5, 1, 0, 0, 0, 190, 191, 5, 52, 0, 0, 191, 195, 3, 160, 80, 0, 192, 193, 5, 115, 0, 0, 193, 194, 5, 122, 0, 0, 194, 196, 3, 4, 2, 0, 195, 192, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 7, 1, 0, 0, 0, 197, 202, 3, 160, 80, 0, 198, 199, 5, 116, 0, 0, 199, 201, 3, 160, 80, 0, 200, 198, 1, 0, 0, 0, 201, 204, 1, 0, 0, 0, 202, 200, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 203, 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 205, 207, 5, 116, 0, 0, 206, 205, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 9, 1, 0, 0, 0, 208, 221, 3, 12, 6, 0, 209, 221, 3, 14, 7, 0, 210, 221, 3, 18, 9, 0, 211, 221, 3, 20, 10, 0, 212, 221, 3, 22, 11, 0, 213, 221, 3, 26, 13, 0, 214, 221, 3, 24, 12, 0, 215, 221, 3, 28, 14, 0, 216, 221, 3, 30, 15, 0, 217, 221, 3, 36, 18, 0, 218, 221, 3, 32, 16, 0, 219, 221, 3, 34, 17, 0, 220, 208, 1, 0, 0, 0, 220, 209, 1, 0, 0, 0, 220, 210, 1, 0, 0, 0, 220, 211, 1, 0, 0, 0, 220, 212, 1, 0, 0, 0, 220, 213, 1, 0, 0, 0, 220, 214, 1, 0, 0, 0, 220, 215, 1, 0, 0, 0, 220, 216, 1, 0, 0, 0, 220, 217, 1, 0, 0, 0, 220, 218, 1, 0, 0, 0, 220, 219, 1, 0, 0, 0, 221, 11, 1, 0, 0, 0, 222, 224, 5, 72, 0, 0, 223, 225, 3, 4, 2, 0, 224, 223, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 227, 1, 0, 0, 0, 226, 228, 5, 150, 0, 0, 227, 226, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 13, 1, 0, 0, 0, 229, 231, 5, 84, 0, 0, 230, 232, 3, 4, 2, 0, 231, 230, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 234, 1, 0, 0, 0, 233, 235, 5, 150, 0, 0, 234, 233, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 15, 1, 0, 0, 0, 236, 245, 5, 14, 0, 0, 237, 238, 5, 130, 0, 0, 238, 241, 3, 160, 80, 0, 239, 240, 5, 115, 0, 0, 240, 242, 3, 160, 80, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 243, 1, 0, 0, 0, 243, 244, 5, 149, 0, 0, 244, 246, 1, 0, 0, 0, 245, 237, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 248, 3, 36, 18, 0, 248, 17, 1, 0, 0, 0, 249, 250, 5, 93, 0, 0, 250, 254, 3, 36, 18, 0, 251, 253, 3, 16, 8, 0, 252, 251, 1, 0, 0, 0, 253, 256, 1, 0, 0, 0, 254, 252, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 255, 259, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 257, 258, 5, 29, 0, 0, 258, 260, 3, 36, 18, 0, 259, 257, 1, 0, 0, 0, 259, 260, 1, 0, 0, 0, 260, 19, 1, 0, 0, 0, 261, 262, 5, 40, 0, 0, 262, 263, 5, 130, 0, 0, 263, 264, 3, 4, 2, 0, 264, 265, 5, 149, 0, 0, 265, 268, 3, 10, 5, 0, 266, 267, 5, 25, 0, 0, 267, 269, 3, 10, 5, 0, 268, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 21, 1, 0, 0, 0, 270, 271, 5, 100, 0, 0, 271, 272, 5, 130, 0, 0, 272, 273, 3, 4, 2, 0, 273, 274, 5, 149, 0, 0, 274, 276, 3, 10, 5, 0, 275, 277, 5, 150, 0, 0, 276, 275, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 23, 1, 0, 0, 0, 278, 279, 5, 33, 0, 0, 279, 283, 5, 130, 0, 0, 280, 284, 3, 6, 3, 0, 281, 284, 3, 30, 15, 0, 282, 284, 3, 4, 2, 0, 283, 280, 1, 0, 0, 0, 283, 281, 1, 0, 0, 0, 283, 282, 1, 0, 0, 0, 283, 284, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287, 5, 150, 0, 0, 286, 288, 3, 4, 2, 0, 287, 286, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 293, 5, 150, 0, 0, 290, 294, 3, 6, 3, 0, 291, 294, 3, 30, 15, 0, 292, 294, 3, 4, 2, 0, 293, 290, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 293, 292, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 296, 5, 149, 0, 0, 296, 298, 3, 10, 5, 0, 297, 299, 5, 150, 0, 0, 298, 297, 1, 0, 0, 0, 298, 299, 1, 0, 0, 0, 299, 25, 1, 0, 0, 0, 300, 301, 5, 33, 0, 0, 301, 302, 5, 130, 0, 0, 302, 303, 5, 52, 0, 0, 303, 306, 3, 160, 80, 0, 304, 305, 5, 116, 0, 0, 305, 307, 3, 160, 80, 0, 306, 304, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 309, 5, 42, 0, 0, 309, 310, 3, 4, 2, 0, 310, 311, 5, 149, 0, 0, 311, 313, 3, 10, 5, 0, 312, 314, 5, 150, 0, 0, 313, 312, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 27, 1, 0, 0, 0, 315, 316, 5, 31, 0, 0, 316, 317, 3, 160, 80, 0, 317, 319, 5, 130, 0, 0, 318, 320, 3, 8, 4, 0, 319, 318, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 322, 5, 149, 0, 0, 322, 323, 3, 36, 18, 0, 323, 29, 1, 0, 0, 0, 324, 325, 3, 4, 2, 0, 325, 326, 5, 115, 0, 0, 326, 327, 5, 122, 0, 0, 327, 328, 3, 4, 2, 0, 328, 31, 1, 0, 0, 0, 329, 331, 3, 4, 2, 0, 330, 332, 5, 150, 0, 0, 331, 330, 1, 0, 0, 0, 331, 332, 1, 0, 0, 0, 332, 33, 1, 0, 0, 0, 333, 334, 5, 150, 0, 0, 334, 35, 1, 0, 0, 0, 335, 339, 5, 128, 0, 0, 336, 338, 3, 2, 1, 0, 337, 336, 1, 0, 0, 0, 338, 341, 1, 0, 0, 0, 339, 337, 1, 0, 0, 0, 339, 340, 1, 0, 0, 0, 340, 342, 1, 0, 0, 0, 341, 339, 1, 0, 0, 0, 342, 343, 5, 147, 0, 0, 343, 37, 1, 0, 0, 0, 344, 345, 3, 4, 2, 0, 345, 346, 5, 115, 0, 0, 346, 347, 3, 4, 2, 0, 347, 39, 1, 0, 0, 0, 348, 353, 3, 38, 19, 0, 349, 350, 5, 116, 0, 0, 350, 352, 3, 38, 19, 0, 351, 349, 1, 0, 0, 0, 352, 355, 1, 0, 0, 0, 353, 351, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 357, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, 358, 5, 116, 0, 0, 357, 356, 1, 0, 0, 0, 357, 358, 1, 0, 0, 0, 358, 41, 1, 0, 0, 0, 359, 363, 3, 44, 22, 0, 360, 363, 3, 48, 24, 0, 361, 363, 3, 124, 62, 0, 362, 359, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 361, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 365, 5, 0, 0, 1, 365, 43, 1, 0, 0, 0, 366, 372, 3, 46, 23, 0, 367, 368, 5, 95, 0, 0, 368, 369, 5, 1, 0, 0, 369, 371, 3, 46, 23, 0, 370, 367, 1, 0, 0, 0, 371, 374, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 372, 373, 1, 0, 0, 0, 373, 45, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 375, 382, 3, 48, 24, 0, 376, 377, 5, 130, 0, 0, 377, 378, 3, 44, 22, 0, 378, 379, 5, 149, 0, 0, 379, 382, 1, 0, 0, 0, 380, 382, 3, 164, 82, 0, 381, 375, 1, 0, 0, 0, 381, 376, 1, 0, 0, 0, 381, 380, 1, 0, 0, 0, 382, 47, 1, 0, 0, 0, 383, 385, 3, 50, 25, 0, 384, 383, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 386, 1, 0, 0, 0, 386, 388, 5, 79, 0, 0, 387, 389, 5, 24, 0, 0, 388, 387, 1, 0, 0, 0, 388, 389, 1, 0, 0, 0, 389, 391, 1, 0, 0, 0, 390, 392, 3, 52, 26, 0, 391, 390, 1, 0, 0, 0, 391, 392, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 395, 3, 114, 57, 0, 394, 396, 3, 54, 27, 0, 395, 394, 1, 0, 0, 0, 395, 396, 1, 0, 0, 0, 396, 398, 1, 0, 0, 0, 397, 399, 3, 56, 28, 0, 398, 397, 1, 0, 0, 0, 398, 399, 1, 0, 0, 0, 399, 401, 1, 0, 0, 0, 400, 402, 3, 60, 30, 0, 401, 400, 1, 0, 0, 0, 401, 402, 1, 0, 0, 0, 402, 404, 1, 0, 0, 0, 403, 405, 3, 62, 31, 0, 404, 403, 1, 0, 0, 0, 404, 405, 1, 0, 0, 0, 405, 407, 1, 0, 0, 0, 406, 408, 3, 64, 32, 0, 407, 406, 1, 0, 0, 0, 407, 408, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 410, 5, 102, 0, 0, 410, 412, 7, 0, 0, 0, 411, 409, 1, 0, 0, 0, 411, 412, 1, 0, 0, 0, 412, 415, 1, 0, 0, 0, 413, 414, 5, 102, 0, 0, 414, 416, 5, 89, 0, 0, 415, 413, 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 418, 1, 0, 0, 0, 417, 419, 3, 66, 33, 0, 418, 417, 1, 0, 0, 0, 418, 419, 1, 0, 0, 0, 419, 421, 1, 0, 0, 0, 420, 422, 3, 58, 29, 0, 421, 420, 1, 0, 0, 0, 421, 422, 1, 0, 0, 0, 422, 424, 1, 0, 0, 0, 423, 425, 3, 68, 34, 0, 424, 423, 1, 0, 0, 0, 424, 425, 1, 0, 0, 0, 425, 428, 1, 0, 0, 0, 426, 429, 3, 72, 36, 0, 427, 429, 3, 74, 37, 0, 428, 426, 1, 0, 0, 0, 428, 427, 1, 0, 0, 0, 428, 429, 1, 0, 0, 0, 429, 431, 1, 0, 0, 0, 430, 432, 3, 76, 38, 0, 431, 430, 1, 0, 0, 0, 431, 432, 1, 0, 0, 0, 432, 49, 1, 0, 0, 0, 433, 434, 5, 102, 0, 0, 434, 435, 3, 128, 64, 0, 435, 51, 1, 0, 0, 0, 436, 437, 5, 88, 0, 0, 437, 440, 5, 108, 0, 0, 438, 439, 5, 102, 0, 0, 439, 441, 5, 85, 0, 0, 440, 438, 1, 0, 0, 0, 440, 441, 1, 0, 0, 0, 441, 53, 1, 0, 0, 0, 442, 443, 5, 34, 0, 0, 443, 444, 3, 78, 39, 0, 444, 55, 1, 0, 0, 0, 445, 447, 7, 1, 0, 0, 446, 445, 1, 0, 0, 0, 446, 447, 1, 0, 0, 0, 447, 448, 1, 0, 0, 0, 448, 449, 5, 5, 0, 0, 449, 450, 5, 47, 0, 0, 450, 451, 3, 114, 57, 0, 451, 57, 1, 0, 0, 0, 452, 453, 5, 101, 0, 0, 453, 454, 3, 160, 80, 0, 454, 455, 5, 6, 0, 0, 455, 456, 5, 130, 0, 0, 456, 457, 3, 98, 49, 0, 457, 467, 5, 149, 0, 0, 458, 459, 5, 116, 0, 0, 459, 460, 3, 160, 80, 0, 460, 461, 5, 6, 0, 0, 461, 462, 5, 130, 0, 0, 462, 463, 3, 98, 49, 0, 463, 464, 5, 149, 0, 0, 464, 466, 1, 0, 0, 0, 465, 458, 1, 0, 0, 0, 466, 469, 1, 0, 0, 0, 467, 465, 1, 0, 0, 0, 467, 468, 1, 0, 0, 0, 468, 59, 1, 0, 0, 0, 469, 467, 1, 0, 0, 0, 470, 471, 5, 69, 0, 0, 471, 472, 3, 116, 58, 0, 472, 61, 1, 0, 0, 0, 473, 474, 5, 99, 0, 0, 474, 475, 3, 116, 58, 0, 475, 63, 1, 0, 0, 0, 476, 477, 5, 36, 0, 0, 477, 484, 5, 11, 0, 0, 478, 479, 7, 0, 0, 0, 479, 480, 5, 130, 0, 0, 480, 481, 3, 114, 57, 0, 481, 482, 5, 149, 0, 0, 482, 485, 1, 0, 0, 0, 483, 485, 3, 114, 57, 0, 484, 478, 1, 0, 0, 0, 484, 483, 1, 0, 0, 0, 485, 65, 1, 0, 0, 0, 486, 487, 5, 37, 0, 0, 487, 488, 3, 116, 58, 0, 488, 67, 1, 0, 0, 0, 489, 490, 5, 64, 0, 0, 490, 491, 5, 11, 0, 0, 491, 492, 3, 88, 44, 0, 492, 69, 1, 0, 0, 0, 493, 494, 5, 64, 0, 0, 494, 495, 5, 11, 0, 0, 495, 496, 3, 114, 57, 0, 496, 71, 1, 0, 0, 0, 497, 498, 5, 54, 0, 0, 498, 501, 3, 116, 58, 0, 499, 500, 5, 116, 0, 0, 500, 502, 3, 116, 58, 0, 501, 499, 1, 0, 0, 0, 501, 502, 1, 0, 0, 0, 502, 507, 1, 0, 0, 0, 503, 504, 5, 102, 0, 0, 504, 508, 5, 85, 0, 0, 505, 506, 5, 11, 0, 0, 506, 508, 3, 114, 57, 0, 507, 503, 1, 0, 0, 0, 507, 505, 1, 0, 0, 0, 507, 508, 1, 0, 0, 0, 508, 527, 1, 0, 0, 0, 509, 510, 5, 54, 0, 0, 510, 513, 3, 116, 58, 0, 511, 512, 5, 102, 0, 0, 512, 514, 5, 85, 0, 0, 513, 511, 1, 0, 0, 0, 513, 514, 1, 0, 0, 0, 514, 515, 1, 0, 0, 0, 515, 516, 5, 61, 0, 0, 516, 517, 3, 116, 58, 0, 517, 527, 1, 0, 0, 0, 518, 519, 5, 54, 0, 0, 519, 520, 3, 116, 58, 0, 520, 521, 5, 61, 0, 0, 521, 524, 3, 116, 58, 0, 522, 523, 5, 11, 0, 0, 523, 525, 3, 114, 57, 0, 524, 522, 1, 0, 0, 0, 524, 525, 1, 0, 0, 0, 525, 527, 1, 0, 0, 0, 526, 497, 1, 0, 0, 0, 526, 509, 1, 0, 0, 0, 526, 518, 1, 0, 0, 0, 527, 73, 1, 0, 0, 0, 528, 529, 5, 61, 0, 0, 529, 530, 3, 116, 58, 0, 530, 75, 1, 0, 0, 0, 531, 532, 5, 81, 0, 0, 532, 533, 3, 94, 47, 0, 533, 77, 1, 0, 0, 0, 534, 535, 6, 39, -1, 0, 535, 537, 3, 136, 68, 0, 536, 538, 5, 28, 0, 0, 537, 536, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 540, 1, 0, 0, 0, 539, 541, 3, 86, 43, 0, 540, 539, 1, 0, 0, 0, 540, 541, 1, 0, 0, 0, 541, 547, 1, 0, 0, 0, 542, 543, 5, 130, 0, 0, 543, 544, 3, 78, 39, 0, 544, 545, 5, 149, 0, 0, 545, 547, 1, 0, 0, 0, 546, 534, 1, 0, 0, 0, 546, 542, 1, 0, 0, 0, 547, 562, 1, 0, 0, 0, 548, 549, 10, 3, 0, 0, 549, 550, 3, 82, 41, 0, 550, 551, 3, 78, 39, 4, 551, 561, 1, 0, 0, 0, 552, 554, 10, 4, 0, 0, 553, 555, 3, 80, 40, 0, 554, 553, 1, 0, 0, 0, 554, 555, 1, 0, 0, 0, 555, 556, 1, 0, 0, 0, 556, 557, 5, 47, 0, 0, 557, 558, 3, 78, 39, 0, 558, 559, 3, 84, 42, 0, 559, 561, 1, 0, 0, 0, 560, 548, 1, 0, 0, 0, 560, 552, 1, 0, 0, 0, 561, 564, 1, 0, 0, 0, 562, 560, 1, 0, 0, 0, 562, 563, 1, 0, 0, 0, 563, 79, 1, 0, 0, 0, 564, 562, 1, 0, 0, 0, 565, 567, 7, 2, 0, 0, 566, 565, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 568, 1, 0, 0, 0, 568, 575, 5, 44, 0, 0, 569, 571, 5, 44, 0, 0, 570, 572, 7, 2, 0, 0, 571, 570, 1, 0, 0, 0, 571, 572, 1, 0, 0, 0, 572, 575, 1, 0, 0, 0, 573, 575, 7, 2, 0, 0, 574, 566, 1, 0, 0, 0, 574, 569, 1, 0, 0, 0, 574, 573, 1, 0, 0, 0, 575, 609, 1, 0, 0, 0, 576, 578, 7, 3, 0, 0, 577, 576, 1, 0, 0, 0, 577, 578, 1, 0, 0, 0, 578, 579, 1, 0, 0, 0, 579, 581, 7, 4, 0, 0, 580, 582, 5, 65, 0, 0, 581, 580, 1, 0, 0, 0, 581, 582, 1, 0, 0, 0, 582, 591, 1, 0, 0, 0, 583, 585, 7, 4, 0, 0, 584, 586, 5, 65, 0, 0, 585, 584, 1, 0, 0, 0, 585, 586, 1, 0, 0, 0, 586, 588, 1, 0, 0, 0, 587, 589, 7, 3, 0, 0, 588, 587, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 591, 1, 0, 0, 0, 590, 577, 1, 0, 0, 0, 590, 583, 1, 0, 0, 0, 591, 609, 1, 0, 0, 0, 592, 594, 7, 5, 0, 0, 593, 592, 1, 0, 0, 0, 593, 594, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, 595, 597, 5, 35, 0, 0, 596, 598, 5, 65, 0, 0, 597, 596, 1, 0, 0, 0, 597, 598, 1, 0, 0, 0, 598, 607, 1, 0, 0, 0, 599, 601, 5, 35, 0, 0, 600, 602, 5, 65, 0, 0, 601, 600, 1, 0, 0, 0, 601, 602, 1, 0, 0, 0, 602, 604, 1, 0, 0, 0, 603, 605, 7, 5, 0, 0, 604, 603, 1, 0, 0, 0, 604, 605, 1, 0, 0, 0, 605, 607, 1, 0, 0, 0, 606, 593, 1, 0, 0, 0, 606, 599, 1, 0, 0, 0, 607, 609, 1, 0, 0, 0, 608, 574, 1, 0, 0, 0, 608, 590, 1, 0, 0, 0, 608, 606, 1, 0, 0, 0, 609, 81, 1, 0, 0, 0, 610, 611, 5, 17, 0, 0, 611, 614, 5, 47, 0, 0, 612, 614, 5, 116, 0, 0, 613, 610, 1, 0, 0, 0, 613, 612, 1, 0, 0, 0, 614, 83, 1, 0, 0, 0, 615, 616, 5, 62, 0, 0, 616, 625, 3, 114, 57, 0, 617, 618, 5, 96, 0, 0, 618, 619, 5, 130, 0, 0, 619, 620, 3, 114, 57, 0, 620, 621, 5, 149, 0, 0, 621, 625, 1, 0, 0, 0, 622, 623, 5, 96, 0, 0, 623, 625, 3, 114, 57, 0, 624, 615, 1, 0, 0, 0, 624, 617, 1, 0, 0, 0, 624, 622, 1, 0, 0, 0, 625, 85, 1, 0, 0, 0, 626, 627, 5, 77, 0, 0, 627, 630, 3, 92, 46, 0, 628, 629, 5, 61, 0, 0, 629, 631, 3, 92, 46, 0, 630, 628, 1, 0, 0, 0, 630, 631, 1, 0, 0, 0, 631, 87, 1, 0, 0, 0, 632, 637, 3, 90, 45, 0, 633, 634, 5, 116, 0, 0, 634, 636, 3, 90, 45, 0, 635, 633, 1, 0, 0, 0, 636, 639, 1, 0, 0, 0, 637, 635, 1, 0, 0, 0, 637, 638, 1, 0, 0, 0, 638, 89, 1, 0, 0, 0, 639, 637, 1, 0, 0, 0, 640, 642, 3, 116, 58, 0, 641, 643, 7, 6, 0, 0, 642, 641, 1, 0, 0, 0, 642, 643, 1, 0, 0, 0, 643, 646, 1, 0, 0, 0, 644, 645, 5, 60, 0, 0, 645, 647, 7, 7, 0, 0, 646, 644, 1, 0, 0, 0, 646, 647, 1, 0, 0, 0, 647, 650, 1, 0, 0, 0, 648, 649, 5, 16, 0, 0, 649, 651, 5, 110, 0, 0, 650, 648, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 91, 1, 0, 0, 0, 652, 659, 3, 164, 82, 0, 653, 656, 3, 148, 74, 0, 654, 655, 5, 151, 0, 0, 655, 657, 3, 148, 74, 0, 656, 654, 1, 0, 0, 0, 656, 657, 1, 0, 0, 0, 657, 659, 1, 0, 0, 0, 658, 652, 1, 0, 0, 0, 658, 653, 1, 0, 0, 0, 659, 93, 1, 0, 0, 0, 660, 665, 3, 96, 48, 0, 661, 662, 5, 116, 0, 0, 662, 664, 3, 96, 48, 0, 663, 661, 1, 0, 0, 0, 664, 667, 1, 0, 0, 0, 665, 663, 1, 0, 0, 0, 665, 666, 1, 0, 0, 0, 666, 95, 1, 0, 0, 0, 667, 665, 1, 0, 0, 0, 668, 669, 3, 160, 80, 0, 669, 670, 5, 122, 0, 0, 670, 671, 3, 150, 75, 0, 671, 97, 1, 0, 0, 0, 672, 674, 3, 100, 50, 0, 673, 672, 1, 0, 0, 0, 673, 674, 1, 0, 0, 0, 674, 676, 1, 0, 0, 0, 675, 677, 3, 102, 51, 0, 676, 675, 1, 0, 0, 0, 676, 677, 1, 0, 0, 0, 677, 679, 1, 0, 0, 0, 678, 680, 3, 104, 52, 0, 679, 678, 1, 0, 0, 0, 679, 680, 1, 0, 0, 0, 680, 99, 1, 0, 0, 0, 681, 682, 5, 67, 0, 0, 682, 683, 5, 11, 0, 0, 683, 684, 3, 114, 57, 0, 684, 101, 1, 0, 0, 0, 685, 686, 5, 64, 0, 0, 686, 687, 5, 11, 0, 0, 687, 688, 3, 88, 44, 0, 688, 103, 1, 0, 0, 0, 689, 690, 7, 8, 0, 0, 690, 691, 3, 106, 53, 0, 691, 105, 1, 0, 0, 0, 692, 699, 3, 108, 54, 0, 693, 694, 5, 9, 0, 0, 694, 695, 3, 108, 54, 0, 695, 696, 5, 2, 0, 0, 696, 697, 3, 108, 54, 0, 697, 699, 1, 0, 0, 0, 698, 692, 1, 0, 0, 0, 698, 693, 1, 0, 0, 0, 699, 107, 1, 0, 0, 0, 700, 701, 5, 19, 0, 0, 701, 713, 5, 75, 0, 0, 702, 703, 5, 94, 0, 0, 703, 713, 5, 68, 0, 0, 704, 705, 5, 94, 0, 0, 705, 713, 5, 32, 0, 0, 706, 707, 3, 148, 74, 0, 707, 708, 5, 68, 0, 0, 708, 713, 1, 0, 0, 0, 709, 710, 3, 148, 74, 0, 710, 711, 5, 32, 0, 0, 711, 713, 1, 0, 0, 0, 712, 700, 1, 0, 0, 0, 712, 702, 1, 0, 0, 0, 712, 704, 1, 0, 0, 0, 712, 706, 1, 0, 0, 0, 712, 709, 1, 0, 0, 0, 713, 109, 1, 0, 0, 0, 714, 715, 3, 116, 58, 0, 715, 716, 5, 0, 0, 1, 716, 111, 1, 0, 0, 0, 717, 774, 3, 160, 80, 0, 718, 719, 3, 160, 80, 0, 719, 720, 5, 130, 0, 0, 720, 721, 3, 160, 80, 0, 721, 728, 3, 112, 56, 0, 722, 723, 5, 116, 0, 0, 723, 724, 3, 160, 80, 0, 724, 725, 3, 112, 56, 0, 725, 727, 1, 0, 0, 0, 726, 722, 1, 0, 0, 0, 727, 730, 1, 0, 0, 0, 728, 726, 1, 0, 0, 0, 728, 729, 1, 0, 0, 0, 729, 732, 1, 0, 0, 0, 730, 728, 1, 0, 0, 0, 731, 733, 5, 116, 0, 0, 732, 731, 1, 0, 0, 0, 732, 733, 1, 0, 0, 0, 733, 734, 1, 0, 0, 0, 734, 735, 5, 149, 0, 0, 735, 774, 1, 0, 0, 0, 736, 737, 3, 160, 80, 0, 737, 738, 5, 130, 0, 0, 738, 743, 3, 162, 81, 0, 739, 740, 5, 116, 0, 0, 740, 742, 3, 162, 81, 0, 741, 739, 1, 0, 0, 0, 742, 745, 1, 0, 0, 0, 743, 741, 1, 0, 0, 0, 743, 744, 1, 0, 0, 0, 744, 747, 1, 0, 0, 0, 745, 743, 1, 0, 0, 0, 746, 748, 5, 116, 0, 0, 747, 746, 1, 0, 0, 0, 747, 748, 1, 0, 0, 0, 748, 749, 1, 0, 0, 0, 749, 750, 5, 149, 0, 0, 750, 774, 1, 0, 0, 0, 751, 752, 3, 160, 80, 0, 752, 753, 5, 130, 0, 0, 753, 758, 3, 112, 56, 0, 754, 755, 5, 116, 0, 0, 755, 757, 3, 112, 56, 0, 756, 754, 1, 0, 0, 0, 757, 760, 1, 0, 0, 0, 758, 756, 1, 0, 0, 0, 758, 759, 1, 0, 0, 0, 759, 762, 1, 0, 0, 0, 760, 758, 1, 0, 0, 0, 761, 763, 5, 116, 0, 0, 762, 761, 1, 0, 0, 0, 762, 763, 1, 0, 0, 0, 763, 764, 1, 0, 0, 0, 764, 765, 5, 149, 0, 0, 765, 774, 1, 0, 0, 0, 766, 767, 3, 160, 80, 0, 767, 769, 5, 130, 0, 0, 768, 770, 3, 114, 57, 0, 769, 768, 1, 0, 0, 0, 769, 770, 1, 0, 0, 0, 770, 771, 1, 0, 0, 0, 771, 772, 5, 149, 0, 0, 772, 774, 1, 0, 0, 0, 773, 717, 1, 0, 0, 0, 773, 718, 1, 0, 0, 0, 773, 736, 1, 0, 0, 0, 773, 751, 1, 0, 0, 0, 773, 766, 1, 0, 0, 0, 774, 113, 1, 0, 0, 0, 775, 780, 3, 116, 58, 0, 776, 777, 5, 116, 0, 0, 777, 779, 3, 116, 58, 0, 778, 776, 1, 0, 0, 0, 779, 782, 1, 0, 0, 0, 780, 778, 1, 0, 0, 0, 780, 781, 1, 0, 0, 0, 781, 784, 1, 0, 0, 0, 782, 780, 1, 0, 0, 0, 783, 785, 5, 116, 0, 0, 784, 783, 1, 0, 0, 0, 784, 785, 1, 0, 0, 0, 785, 115, 1, 0, 0, 0, 786, 787, 6, 58, -1, 0, 787, 789, 5, 12, 0, 0, 788, 790, 3, 116, 58, 0, 789, 788, 1, 0, 0, 0, 789, 790, 1, 0, 0, 0, 790, 796, 1, 0, 0, 0, 791, 792, 5, 98, 0, 0, 792, 793, 3, 116, 58, 0, 793, 794, 5, 83, 0, 0, 794, 795, 3, 116, 58, 0, 795, 797, 1, 0, 0, 0, 796, 791, 1, 0, 0, 0, 797, 798, 1, 0, 0, 0, 798, 796, 1, 0, 0, 0, 798, 799, 1, 0, 0, 0, 799, 802, 1, 0, 0, 0, 800, 801, 5, 25, 0, 0, 801, 803, 3, 116, 58, 0, 802, 800, 1, 0, 0, 0, 802, 803, 1, 0, 0, 0, 803, 804, 1, 0, 0, 0, 804, 805, 5, 26, 0, 0, 805, 936, 1, 0, 0, 0, 806, 807, 5, 13, 0, 0, 807, 808, 5, 130, 0, 0, 808, 809, 3, 116, 58, 0, 809, 810, 5, 6, 0, 0, 810, 811, 3, 112, 56, 0, 811, 812, 5, 149, 0, 0, 812, 936, 1, 0, 0, 0, 813, 814, 5, 20, 0, 0, 814, 936, 5, 110, 0, 0, 815, 816, 5, 45, 0, 0, 816, 817, 3, 116, 58, 0, 817, 818, 3, 152, 76, 0, 818, 936, 1, 0, 0, 0, 819, 820, 5, 82, 0, 0, 820, 821, 5, 130, 0, 0, 821, 822, 3, 116, 58, 0, 822, 823, 5, 34, 0, 0, 823, 826, 3, 116, 58, 0, 824, 825, 5, 33, 0, 0, 825, 827, 3, 116, 58, 0, 826, 824, 1, 0, 0, 0, 826, 827, 1, 0, 0, 0, 827, 828, 1, 0, 0, 0, 828, 829, 5, 149, 0, 0, 829, 936, 1, 0, 0, 0, 830, 831, 5, 86, 0, 0, 831, 936, 5, 110, 0, 0, 832, 833, 5, 91, 0, 0, 833, 834, 5, 130, 0, 0, 834, 835, 7, 9, 0, 0, 835, 836, 3, 166, 83, 0, 836, 837, 5, 34, 0, 0, 837, 838, 3, 116, 58, 0, 838, 839, 5, 149, 0, 0, 839, 936, 1, 0, 0, 0, 840, 841, 3, 160, 80, 0, 841, 843, 5, 130, 0, 0, 842, 844, 3, 114, 57, 0, 843, 842, 1, 0, 0, 0, 843, 844, 1, 0, 0, 0, 844, 845, 1, 0, 0, 0, 845, 846, 5, 149, 0, 0, 846, 855, 1, 0, 0, 0, 847, 849, 5, 130, 0, 0, 848, 850, 5, 24, 0, 0, 849, 848, 1, 0, 0, 0, 849, 850, 1, 0, 0, 0, 850, 852, 1, 0, 0, 0, 851, 853, 3, 118, 59, 0, 852, 851, 1, 0, 0, 0, 852, 853, 1, 0, 0, 0, 853, 854, 1, 0, 0, 0, 854, 856, 5, 149, 0, 0, 855, 847, 1, 0, 0, 0, 855, 856, 1, 0, 0, 0, 856, 857, 1, 0, 0, 0, 857, 858, 5, 66, 0, 0, 858, 859, 5, 130, 0, 0, 859, 860, 3, 98, 49, 0, 860, 861, 5, 149, 0, 0, 861, 936, 1, 0, 0, 0, 862, 863, 3, 160, 80, 0, 863, 865, 5, 130, 0, 0, 864, 866, 3, 114, 57, 0, 865, 864, 1, 0, 0, 0, 865, 866, 1, 0, 0, 0, 866, 867, 1, 0, 0, 0, 867, 868, 5, 149, 0, 0, 868, 877, 1, 0, 0, 0, 869, 871, 5, 130, 0, 0, 870, 872, 5, 24, 0, 0, 871, 870, 1, 0, 0, 0, 871, 872, 1, 0, 0, 0, 872, 874, 1, 0, 0, 0, 873, 875, 3, 118, 59, 0, 874, 873, 1, 0, 0, 0, 874, 875, 1, 0, 0, 0, 875, 876, 1, 0, 0, 0, 876, 878, 5, 149, 0, 0, 877, 869, 1, 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 879, 1, 0, 0, 0, 879, 880, 5, 66, 0, 0, 880, 881, 3, 160, 80, 0, 881, 936, 1, 0, 0, 0, 882, 888, 3, 160, 80, 0, 883, 885, 5, 130, 0, 0, 884, 886, 3, 114, 57, 0, 885, 884, 1, 0, 0, 0, 885, 886, 1, 0, 0, 0, 886, 887, 1, 0, 0, 0, 887, 889, 5, 149, 0, 0, 888, 883, 1, 0, 0, 0, 888, 889, 1, 0, 0, 0, 889, 890, 1, 0, 0, 0, 890, 892, 5, 130, 0, 0, 891, 893, 5, 24, 0, 0, 892, 891, 1, 0, 0, 0, 892, 893, 1, 0, 0, 0, 893, 895, 1, 0, 0, 0, 894, 896, 3, 118, 59, 0, 895, 894, 1, 0, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897, 1, 0, 0, 0, 897, 898, 5, 149, 0, 0, 898, 936, 1, 0, 0, 0, 899, 936, 3, 124, 62, 0, 900, 936, 3, 168, 84, 0, 901, 936, 3, 150, 75, 0, 902, 903, 5, 118, 0, 0, 903, 936, 3, 116, 58, 19, 904, 905, 5, 58, 0, 0, 905, 936, 3, 116, 58, 13, 906, 907, 3, 140, 70, 0, 907, 908, 5, 120, 0, 0, 908, 910, 1, 0, 0, 0, 909, 906, 1, 0, 0, 0, 909, 910, 1, 0, 0, 0, 910, 911, 1, 0, 0, 0, 911, 936, 5, 112, 0, 0, 912, 913, 5, 130, 0, 0, 913, 914, 3, 44, 22, 0, 914, 915, 5, 149, 0, 0, 915, 936, 1, 0, 0, 0, 916, 917, 5, 130, 0, 0, 917, 918, 3, 116, 58, 0, 918, 919, 5, 149, 0, 0, 919, 936, 1, 0, 0, 0, 920, 921, 5, 130, 0, 0, 921, 922, 3, 114, 57, 0, 922, 923, 5, 149, 0, 0, 923, 936, 1, 0, 0, 0, 924, 926, 5, 129, 0, 0, 925, 927, 3, 114, 57, 0, 926, 925, 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, 927, 928, 1, 0, 0, 0, 928, 936, 5, 148, 0, 0, 929, 931, 5, 128, 0, 0, 930, 932, 3, 40, 20, 0, 931, 930, 1, 0, 0, 0, 931, 932, 1, 0, 0, 0, 932, 933, 1, 0, 0, 0, 933, 936, 5, 147, 0, 0, 934, 936, 3, 132, 66, 0, 935, 786, 1, 0, 0, 0, 935, 806, 1, 0, 0, 0, 935, 813, 1, 0, 0, 0, 935, 815, 1, 0, 0, 0, 935, 819, 1, 0, 0, 0, 935, 830, 1, 0, 0, 0, 935, 832, 1, 0, 0, 0, 935, 840, 1, 0, 0, 0, 935, 862, 1, 0, 0, 0, 935, 882, 1, 0, 0, 0, 935, 899, 1, 0, 0, 0, 935, 900, 1, 0, 0, 0, 935, 901, 1, 0, 0, 0, 935, 902, 1, 0, 0, 0, 935, 904, 1, 0, 0, 0, 935, 909, 1, 0, 0, 0, 935, 912, 1, 0, 0, 0, 935, 916, 1, 0, 0, 0, 935, 920, 1, 0, 0, 0, 935, 924, 1, 0, 0, 0, 935, 929, 1, 0, 0, 0, 935, 934, 1, 0, 0, 0, 936, 1041, 1, 0, 0, 0, 937, 941, 10, 18, 0, 0, 938, 942, 5, 112, 0, 0, 939, 942, 5, 151, 0, 0, 940, 942, 5, 138, 0, 0, 941, 938, 1, 0, 0, 0, 941, 939, 1, 0, 0, 0, 941, 940, 1, 0, 0, 0, 942, 943, 1, 0, 0, 0, 943, 1040, 3, 116, 58, 19, 944, 948, 10, 17, 0, 0, 945, 949, 5, 139, 0, 0, 946, 949, 5, 118, 0, 0, 947, 949, 5, 117, 0, 0, 948, 945, 1, 0, 0, 0, 948, 946, 1, 0, 0, 0, 948, 947, 1, 0, 0, 0, 949, 950, 1, 0, 0, 0, 950, 1040, 3, 116, 58, 18, 951, 976, 10, 16, 0, 0, 952, 977, 5, 121, 0, 0, 953, 977, 5, 122, 0, 0, 954, 977, 5, 133, 0, 0, 955, 977, 5, 131, 0, 0, 956, 977, 5, 132, 0, 0, 957, 977, 5, 123, 0, 0, 958, 977, 5, 124, 0, 0, 959, 961, 5, 58, 0, 0, 960, 959, 1, 0, 0, 0, 960, 961, 1, 0, 0, 0, 961, 962, 1, 0, 0, 0, 962, 964, 5, 42, 0, 0, 963, 965, 5, 15, 0, 0, 964, 963, 1, 0, 0, 0, 964, 965, 1, 0, 0, 0, 965, 977, 1, 0, 0, 0, 966, 968, 5, 58, 0, 0, 967, 966, 1, 0, 0, 0, 967, 968, 1, 0, 0, 0, 968, 969, 1, 0, 0, 0, 969, 977, 7, 10, 0, 0, 970, 977, 5, 145, 0, 0, 971, 977, 5, 146, 0, 0, 972, 977, 5, 135, 0, 0, 973, 977, 5, 126, 0, 0, 974, 977, 5, 127, 0, 0, 975, 977, 5, 134, 0, 0, 976, 952, 1, 0, 0, 0, 976, 953, 1, 0, 0, 0, 976, 954, 1, 0, 0, 0, 976, 955, 1, 0, 0, 0, 976, 956, 1, 0, 0, 0, 976, 957, 1, 0, 0, 0, 976, 958, 1, 0, 0, 0, 976, 960, 1, 0, 0, 0, 976, 967, 1, 0, 0, 0, 976, 970, 1, 0, 0, 0, 976, 971, 1, 0, 0, 0, 976, 972, 1, 0, 0, 0, 976, 973, 1, 0, 0, 0, 976, 974, 1, 0, 0, 0, 976, 975, 1, 0, 0, 0, 977, 978, 1, 0, 0, 0, 978, 1040, 3, 116, 58, 17, 979, 980, 10, 14, 0, 0, 980, 981, 5, 137, 0, 0, 981, 1040, 3, 116, 58, 15, 982, 983, 10, 12, 0, 0, 983, 984, 5, 2, 0, 0, 984, 1040, 3, 116, 58, 13, 985, 986, 10, 11, 0, 0, 986, 987, 5, 63, 0, 0, 987, 1040, 3, 116, 58, 12, 988, 990, 10, 10, 0, 0, 989, 991, 5, 58, 0, 0, 990, 989, 1, 0, 0, 0, 990, 991, 1, 0, 0, 0, 991, 992, 1, 0, 0, 0, 992, 993, 5, 9, 0, 0, 993, 994, 3, 116, 58, 0, 994, 995, 5, 2, 0, 0, 995, 996, 3, 116, 58, 11, 996, 1040, 1, 0, 0, 0, 997, 998, 10, 9, 0, 0, 998, 999, 5, 140, 0, 0, 999, 1000, 3, 116, 58, 0, 1000, 1001, 5, 115, 0, 0, 1001, 1002, 3, 116, 58, 9, 1002, 1040, 1, 0, 0, 0, 1003, 1004, 10, 25, 0, 0, 1004, 1005, 5, 129, 0, 0, 1005, 1006, 3, 116, 58, 0, 1006, 1007, 5, 148, 0, 0, 1007, 1040, 1, 0, 0, 0, 1008, 1009, 10, 24, 0, 0, 1009, 1010, 5, 120, 0, 0, 1010, 1040, 5, 108, 0, 0, 1011, 1012, 10, 23, 0, 0, 1012, 1013, 5, 120, 0, 0, 1013, 1040, 3, 160, 80, 0, 1014, 1015, 10, 22, 0, 0, 1015, 1016, 5, 136, 0, 0, 1016, 1017, 5, 129, 0, 0, 1017, 1018, 3, 116, 58, 0, 1018, 1019, 5, 148, 0, 0, 1019, 1040, 1, 0, 0, 0, 1020, 1021, 10, 21, 0, 0, 1021, 1022, 5, 136, 0, 0, 1022, 1040, 5, 108, 0, 0, 1023, 1024, 10, 20, 0, 0, 1024, 1025, 5, 136, 0, 0, 1025, 1040, 3, 160, 80, 0, 1026, 1027, 10, 15, 0, 0, 1027, 1029, 5, 46, 0, 0, 1028, 1030, 5, 58, 0, 0, 1029, 1028, 1, 0, 0, 0, 1029, 1030, 1, 0, 0, 0, 1030, 1031, 1, 0, 0, 0, 1031, 1040, 5, 59, 0, 0, 1032, 1037, 10, 8, 0, 0, 1033, 1034, 5, 6, 0, 0, 1034, 1038, 3, 160, 80, 0, 1035, 1036, 5, 6, 0, 0, 1036, 1038, 5, 110, 0, 0, 1037, 1033, 1, 0, 0, 0, 1037, 1035, 1, 0, 0, 0, 1038, 1040, 1, 0, 0, 0, 1039, 937, 1, 0, 0, 0, 1039, 944, 1, 0, 0, 0, 1039, 951, 1, 0, 0, 0, 1039, 979, 1, 0, 0, 0, 1039, 982, 1, 0, 0, 0, 1039, 985, 1, 0, 0, 0, 1039, 988, 1, 0, 0, 0, 1039, 997, 1, 0, 0, 0, 1039, 1003, 1, 0, 0, 0, 1039, 1008, 1, 0, 0, 0, 1039, 1011, 1, 0, 0, 0, 1039, 1014, 1, 0, 0, 0, 1039, 1020, 1, 0, 0, 0, 1039, 1023, 1, 0, 0, 0, 1039, 1026, 1, 0, 0, 0, 1039, 1032, 1, 0, 0, 0, 1040, 1043, 1, 0, 0, 0, 1041, 1039, 1, 0, 0, 0, 1041, 1042, 1, 0, 0, 0, 1042, 117, 1, 0, 0, 0, 1043, 1041, 1, 0, 0, 0, 1044, 1049, 3, 120, 60, 0, 1045, 1046, 5, 116, 0, 0, 1046, 1048, 3, 120, 60, 0, 1047, 1045, 1, 0, 0, 0, 1048, 1051, 1, 0, 0, 0, 1049, 1047, 1, 0, 0, 0, 1049, 1050, 1, 0, 0, 0, 1050, 1053, 1, 0, 0, 0, 1051, 1049, 1, 0, 0, 0, 1052, 1054, 5, 116, 0, 0, 1053, 1052, 1, 0, 0, 0, 1053, 1054, 1, 0, 0, 0, 1054, 119, 1, 0, 0, 0, 1055, 1058, 3, 122, 61, 0, 1056, 1058, 3, 116, 58, 0, 1057, 1055, 1, 0, 0, 0, 1057, 1056, 1, 0, 0, 0, 1058, 121, 1, 0, 0, 0, 1059, 1060, 5, 130, 0, 0, 1060, 1065, 3, 160, 80, 0, 1061, 1062, 5, 116, 0, 0, 1062, 1064, 3, 160, 80, 0, 1063, 1061, 1, 0, 0, 0, 1064, 1067, 1, 0, 0, 0, 1065, 1063, 1, 0, 0, 0, 1065, 1066, 1, 0, 0, 0, 1066, 1069, 1, 0, 0, 0, 1067, 1065, 1, 0, 0, 0, 1068, 1070, 5, 116, 0, 0, 1069, 1068, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 1071, 1, 0, 0, 0, 1071, 1072, 5, 149, 0, 0, 1072, 1085, 1, 0, 0, 0, 1073, 1078, 3, 160, 80, 0, 1074, 1075, 5, 116, 0, 0, 1075, 1077, 3, 160, 80, 0, 1076, 1074, 1, 0, 0, 0, 1077, 1080, 1, 0, 0, 0, 1078, 1076, 1, 0, 0, 0, 1078, 1079, 1, 0, 0, 0, 1079, 1082, 1, 0, 0, 0, 1080, 1078, 1, 0, 0, 0, 1081, 1083, 5, 116, 0, 0, 1082, 1081, 1, 0, 0, 0, 1082, 1083, 1, 0, 0, 0, 1083, 1085, 1, 0, 0, 0, 1084, 1059, 1, 0, 0, 0, 1084, 1073, 1, 0, 0, 0, 1085, 1086, 1, 0, 0, 0, 1086, 1087, 5, 111, 0, 0, 1087, 1088, 3, 116, 58, 0, 1088, 123, 1, 0, 0, 0, 1089, 1090, 5, 132, 0, 0, 1090, 1094, 3, 160, 80, 0, 1091, 1093, 3, 126, 63, 0, 1092, 1091, 1, 0, 0, 0, 1093, 1096, 1, 0, 0, 0, 1094, 1092, 1, 0, 0, 0, 1094, 1095, 1, 0, 0, 0, 1095, 1097, 1, 0, 0, 0, 1096, 1094, 1, 0, 0, 0, 1097, 1098, 5, 151, 0, 0, 1098, 1099, 5, 124, 0, 0, 1099, 1122, 1, 0, 0, 0, 1100, 1101, 5, 132, 0, 0, 1101, 1105, 3, 160, 80, 0, 1102, 1104, 3, 126, 63, 0, 1103, 1102, 1, 0, 0, 0, 1104, 1107, 1, 0, 0, 0, 1105, 1103, 1, 0, 0, 0, 1105, 1106, 1, 0, 0, 0, 1106, 1108, 1, 0, 0, 0, 1107, 1105, 1, 0, 0, 0, 1108, 1114, 5, 124, 0, 0, 1109, 1115, 3, 124, 62, 0, 1110, 1111, 5, 128, 0, 0, 1111, 1112, 3, 116, 58, 0, 1112, 1113, 5, 147, 0, 0, 1113, 1115, 1, 0, 0, 0, 1114, 1109, 1, 0, 0, 0, 1114, 1110, 1, 0, 0, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1116, 1, 0, 0, 0, 1116, 1117, 5, 132, 0, 0, 1117, 1118, 5, 151, 0, 0, 1118, 1119, 3, 160, 80, 0, 1119, 1120, 5, 124, 0, 0, 1120, 1122, 1, 0, 0, 0, 1121, 1089, 1, 0, 0, 0, 1121, 1100, 1, 0, 0, 0, 1122, 125, 1, 0, 0, 0, 1123, 1124, 3, 160, 80, 0, 1124, 1125, 5, 122, 0, 0, 1125, 1126, 3, 166, 83, 0, 1126, 1135, 1, 0, 0, 0, 1127, 1128, 3, 160, 80, 0, 1128, 1129, 5, 122, 0, 0, 1129, 1130, 5, 128, 0, 0, 1130, 1131, 3, 116, 58, 0, 1131, 1132, 5, 147, 0, 0, 1132, 1135, 1, 0, 0, 0, 1133, 1135, 3, 160, 80, 0, 1134, 1123, 1, 0, 0, 0, 1134, 1127, 1, 0, 0, 0, 1134, 1133, 1, 0, 0, 0, 1135, 127, 1, 0, 0, 0, 1136, 1141, 3, 130, 65, 0, 1137, 1138, 5, 116, 0, 0, 1138, 1140, 3, 130, 65, 0, 1139, 1137, 1, 0, 0, 0, 1140, 1143, 1, 0, 0, 0, 1141, 1139, 1, 0, 0, 0, 1141, 1142, 1, 0, 0, 0, 1142, 1145, 1, 0, 0, 0, 1143, 1141, 1, 0, 0, 0, 1144, 1146, 5, 116, 0, 0, 1145, 1144, 1, 0, 0, 0, 1145, 1146, 1, 0, 0, 0, 1146, 129, 1, 0, 0, 0, 1147, 1148, 3, 160, 80, 0, 1148, 1149, 5, 6, 0, 0, 1149, 1150, 5, 130, 0, 0, 1150, 1151, 3, 44, 22, 0, 1151, 1152, 5, 149, 0, 0, 1152, 1158, 1, 0, 0, 0, 1153, 1154, 3, 116, 58, 0, 1154, 1155, 5, 6, 0, 0, 1155, 1156, 3, 160, 80, 0, 1156, 1158, 1, 0, 0, 0, 1157, 1147, 1, 0, 0, 0, 1157, 1153, 1, 0, 0, 0, 1158, 131, 1, 0, 0, 0, 1159, 1167, 3, 164, 82, 0, 1160, 1161, 3, 140, 70, 0, 1161, 1162, 5, 120, 0, 0, 1162, 1164, 1, 0, 0, 0, 1163, 1160, 1, 0, 0, 0, 1163, 1164, 1, 0, 0, 0, 1164, 1165, 1, 0, 0, 0, 1165, 1167, 3, 134, 67, 0, 1166, 1159, 1, 0, 0, 0, 1166, 1163, 1, 0, 0, 0, 1167, 133, 1, 0, 0, 0, 1168, 1173, 3, 160, 80, 0, 1169, 1170, 5, 120, 0, 0, 1170, 1172, 3, 160, 80, 0, 1171, 1169, 1, 0, 0, 0, 1172, 1175, 1, 0, 0, 0, 1173, 1171, 1, 0, 0, 0, 1173, 1174, 1, 0, 0, 0, 1174, 135, 1, 0, 0, 0, 1175, 1173, 1, 0, 0, 0, 1176, 1177, 6, 68, -1, 0, 1177, 1186, 3, 140, 70, 0, 1178, 1186, 3, 138, 69, 0, 1179, 1180, 5, 130, 0, 0, 1180, 1181, 3, 44, 22, 0, 1181, 1182, 5, 149, 0, 0, 1182, 1186, 1, 0, 0, 0, 1183, 1186, 3, 124, 62, 0, 1184, 1186, 3, 164, 82, 0, 1185, 1176, 1, 0, 0, 0, 1185, 1178, 1, 0, 0, 0, 1185, 1179, 1, 0, 0, 0, 1185, 1183, 1, 0, 0, 0, 1185, 1184, 1, 0, 0, 0, 1186, 1195, 1, 0, 0, 0, 1187, 1191, 10, 3, 0, 0, 1188, 1192, 3, 158, 79, 0, 1189, 1190, 5, 6, 0, 0, 1190, 1192, 3, 160, 80, 0, 1191, 1188, 1, 0, 0, 0, 1191, 1189, 1, 0, 0, 0, 1192, 1194, 1, 0, 0, 0, 1193, 1187, 1, 0, 0, 0, 1194, 1197, 1, 0, 0, 0, 1195, 1193, 1, 0, 0, 0, 1195, 1196, 1, 0, 0, 0, 1196, 137, 1, 0, 0, 0, 1197, 1195, 1, 0, 0, 0, 1198, 1199, 3, 160, 80, 0, 1199, 1201, 5, 130, 0, 0, 1200, 1202, 3, 142, 71, 0, 1201, 1200, 1, 0, 0, 0, 1201, 1202, 1, 0, 0, 0, 1202, 1203, 1, 0, 0, 0, 1203, 1204, 5, 149, 0, 0, 1204, 139, 1, 0, 0, 0, 1205, 1206, 3, 144, 72, 0, 1206, 1207, 5, 120, 0, 0, 1207, 1209, 1, 0, 0, 0, 1208, 1205, 1, 0, 0, 0, 1208, 1209, 1, 0, 0, 0, 1209, 1210, 1, 0, 0, 0, 1210, 1211, 3, 160, 80, 0, 1211, 141, 1, 0, 0, 0, 1212, 1217, 3, 116, 58, 0, 1213, 1214, 5, 116, 0, 0, 1214, 1216, 3, 116, 58, 0, 1215, 1213, 1, 0, 0, 0, 1216, 1219, 1, 0, 0, 0, 1217, 1215, 1, 0, 0, 0, 1217, 1218, 1, 0, 0, 0, 1218, 1221, 1, 0, 0, 0, 1219, 1217, 1, 0, 0, 0, 1220, 1222, 5, 116, 0, 0, 1221, 1220, 1, 0, 0, 0, 1221, 1222, 1, 0, 0, 0, 1222, 143, 1, 0, 0, 0, 1223, 1224, 3, 160, 80, 0, 1224, 145, 1, 0, 0, 0, 1225, 1234, 5, 106, 0, 0, 1226, 1227, 5, 120, 0, 0, 1227, 1234, 7, 11, 0, 0, 1228, 1229, 5, 108, 0, 0, 1229, 1231, 5, 120, 0, 0, 1230, 1232, 7, 11, 0, 0, 1231, 1230, 1, 0, 0, 0, 1231, 1232, 1, 0, 0, 0, 1232, 1234, 1, 0, 0, 0, 1233, 1225, 1, 0, 0, 0, 1233, 1226, 1, 0, 0, 0, 1233, 1228, 1, 0, 0, 0, 1234, 147, 1, 0, 0, 0, 1235, 1237, 7, 12, 0, 0, 1236, 1235, 1, 0, 0, 0, 1236, 1237, 1, 0, 0, 0, 1237, 1244, 1, 0, 0, 0, 1238, 1245, 3, 146, 73, 0, 1239, 1245, 5, 107, 0, 0, 1240, 1245, 5, 108, 0, 0, 1241, 1245, 5, 109, 0, 0, 1242, 1245, 5, 43, 0, 0, 1243, 1245, 5, 57, 0, 0, 1244, 1238, 1, 0, 0, 0, 1244, 1239, 1, 0, 0, 0, 1244, 1240, 1, 0, 0, 0, 1244, 1241, 1, 0, 0, 0, 1244, 1242, 1, 0, 0, 0, 1244, 1243, 1, 0, 0, 0, 1245, 149, 1, 0, 0, 0, 1246, 1250, 3, 148, 74, 0, 1247, 1250, 5, 110, 0, 0, 1248, 1250, 5, 59, 0, 0, 1249, 1246, 1, 0, 0, 0, 1249, 1247, 1, 0, 0, 0, 1249, 1248, 1, 0, 0, 0, 1250, 151, 1, 0, 0, 0, 1251, 1252, 7, 13, 0, 0, 1252, 153, 1, 0, 0, 0, 1253, 1254, 7, 14, 0, 0, 1254, 155, 1, 0, 0, 0, 1255, 1256, 7, 15, 0, 0, 1256, 157, 1, 0, 0, 0, 1257, 1260, 5, 105, 0, 0, 1258, 1260, 3, 156, 78, 0, 1259, 1257, 1, 0, 0, 0, 1259, 1258, 1, 0, 0, 0, 1260, 159, 1, 0, 0, 0, 1261, 1265, 5, 105, 0, 0, 1262, 1265, 3, 152, 76, 0, 1263, 1265, 3, 154, 77, 0, 1264, 1261, 1, 0, 0, 0, 1264, 1262, 1, 0, 0, 0, 1264, 1263, 1, 0, 0, 0, 1265, 161, 1, 0, 0, 0, 1266, 1267, 3, 166, 83, 0, 1267, 1268, 5, 122, 0, 0, 1268, 1269, 3, 148, 74, 0, 1269, 163, 1, 0, 0, 0, 1270, 1271, 5, 128, 0, 0, 1271, 1272, 3, 160, 80, 0, 1272, 1273, 5, 147, 0, 0, 1273, 165, 1, 0, 0, 0, 1274, 1277, 5, 110, 0, 0, 1275, 1277, 3, 168, 84, 0, 1276, 1274, 1, 0, 0, 0, 1276, 1275, 1, 0, 0, 0, 1277, 167, 1, 0, 0, 0, 1278, 1282, 5, 142, 0, 0, 1279, 1281, 3, 170, 85, 0, 1280, 1279, 1, 0, 0, 0, 1281, 1284, 1, 0, 0, 0, 1282, 1280, 1, 0, 0, 0, 1282, 1283, 1, 0, 0, 0, 1283, 1285, 1, 0, 0, 0, 1284, 1282, 1, 0, 0, 0, 1285, 1286, 5, 144, 0, 0, 1286, 169, 1, 0, 0, 0, 1287, 1288, 5, 157, 0, 0, 1288, 1289, 3, 116, 58, 0, 1289, 1290, 5, 147, 0, 0, 1290, 1293, 1, 0, 0, 0, 1291, 1293, 5, 156, 0, 0, 1292, 1287, 1, 0, 0, 0, 1292, 1291, 1, 0, 0, 0, 1293, 171, 1, 0, 0, 0, 1294, 1298, 5, 143, 0, 0, 1295, 1297, 3, 174, 87, 0, 1296, 1295, 1, 0, 0, 0, 1297, 1300, 1, 0, 0, 0, 1298, 1296, 1, 0, 0, 0, 1298, 1299, 1, 0, 0, 0, 1299, 1301, 1, 0, 0, 0, 1300, 1298, 1, 0, 0, 0, 1301, 1302, 5, 0, 0, 1, 1302, 173, 1, 0, 0, 0, 1303, 1304, 5, 159, 0, 0, 1304, 1305, 3, 116, 58, 0, 1305, 1306, 5, 147, 0, 0, 1306, 1309, 1, 0, 0, 0, 1307, 1309, 5, 158, 0, 0, 1308, 1303, 1, 0, 0, 0, 1308, 1307, 1, 0, 0, 0, 1309, 175, 1, 0, 0, 0, 168, 179, 186, 195, 202, 206, 220, 224, 227, 231, 234, 241, 245, 254, 259, 268, 276, 283, 287, 293, 298, 306, 313, 319, 331, 339, 353, 357, 362, 372, 381, 384, 388, 391, 395, 398, 401, 404, 407, 411, 415, 418, 421, 424, 428, 431, 440, 446, 467, 484, 501, 507, 513, 524, 526, 537, 540, 546, 554, 560, 562, 566, 571, 574, 577, 581, 585, 588, 590, 593, 597, 601, 604, 606, 608, 613, 624, 630, 637, 642, 646, 650, 656, 658, 665, 673, 676, 679, 698, 712, 728, 732, 743, 747, 758, 762, 769, 773, 780, 784, 789, 798, 802, 826, 843, 849, 852, 855, 865, 871, 874, 877, 885, 888, 892, 895, 909, 926, 931, 935, 941, 948, 960, 964, 967, 976, 990, 1029, 1037, 1039, 1041, 1049, 1053, 1057, 1065, 1069, 1078, 1082, 1084, 1094, 1105, 1114, 1121, 1134, 1141, 1145, 1157, 1163, 1166, 1173, 1185, 1191, 1195, 1201, 1208, 1217, 1221, 1231, 1233, 1236, 1244, 1249, 1259, 1264, 1276, 1282, 1292, 1298, 1308] \ No newline at end of file +[4, 1, 159, 1311, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 1, 0, 5, 0, 178, 8, 0, 10, 0, 12, 0, 181, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 3, 1, 187, 8, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 196, 8, 3, 1, 4, 1, 4, 1, 4, 5, 4, 201, 8, 4, 10, 4, 12, 4, 204, 9, 4, 1, 4, 3, 4, 207, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 221, 8, 5, 1, 6, 1, 6, 3, 6, 225, 8, 6, 1, 6, 3, 6, 228, 8, 6, 1, 7, 1, 7, 3, 7, 232, 8, 7, 1, 7, 3, 7, 235, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 242, 8, 8, 1, 8, 1, 8, 3, 8, 246, 8, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 5, 9, 253, 8, 9, 10, 9, 12, 9, 256, 9, 9, 1, 9, 1, 9, 3, 9, 260, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 269, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 277, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 284, 8, 12, 1, 12, 1, 12, 3, 12, 288, 8, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 294, 8, 12, 1, 12, 1, 12, 1, 12, 3, 12, 299, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 307, 8, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 314, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 320, 8, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 3, 16, 332, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 5, 18, 338, 8, 18, 10, 18, 12, 18, 341, 9, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 5, 20, 352, 8, 20, 10, 20, 12, 20, 355, 9, 20, 1, 20, 3, 20, 358, 8, 20, 1, 21, 1, 21, 1, 21, 3, 21, 363, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 371, 8, 22, 10, 22, 12, 22, 374, 9, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 382, 8, 23, 1, 24, 3, 24, 385, 8, 24, 1, 24, 1, 24, 3, 24, 389, 8, 24, 1, 24, 3, 24, 392, 8, 24, 1, 24, 1, 24, 3, 24, 396, 8, 24, 1, 24, 3, 24, 399, 8, 24, 1, 24, 3, 24, 402, 8, 24, 1, 24, 3, 24, 405, 8, 24, 1, 24, 3, 24, 408, 8, 24, 1, 24, 1, 24, 3, 24, 412, 8, 24, 1, 24, 1, 24, 3, 24, 416, 8, 24, 1, 24, 3, 24, 419, 8, 24, 1, 24, 3, 24, 422, 8, 24, 1, 24, 3, 24, 425, 8, 24, 1, 24, 1, 24, 3, 24, 429, 8, 24, 1, 24, 3, 24, 432, 8, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 441, 8, 26, 1, 27, 1, 27, 1, 27, 1, 28, 3, 28, 447, 8, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 466, 8, 29, 10, 29, 12, 29, 469, 9, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 3, 32, 485, 8, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 502, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 508, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 514, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 525, 8, 36, 3, 36, 527, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 3, 39, 538, 8, 39, 1, 39, 3, 39, 541, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 547, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 555, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 5, 39, 561, 8, 39, 10, 39, 12, 39, 564, 9, 39, 1, 40, 3, 40, 567, 8, 40, 1, 40, 1, 40, 1, 40, 3, 40, 572, 8, 40, 1, 40, 3, 40, 575, 8, 40, 1, 40, 3, 40, 578, 8, 40, 1, 40, 1, 40, 3, 40, 582, 8, 40, 1, 40, 1, 40, 3, 40, 586, 8, 40, 1, 40, 3, 40, 589, 8, 40, 3, 40, 591, 8, 40, 1, 40, 3, 40, 594, 8, 40, 1, 40, 1, 40, 3, 40, 598, 8, 40, 1, 40, 1, 40, 3, 40, 602, 8, 40, 1, 40, 3, 40, 605, 8, 40, 3, 40, 607, 8, 40, 3, 40, 609, 8, 40, 1, 41, 1, 41, 1, 41, 3, 41, 614, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 625, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 631, 8, 43, 1, 44, 1, 44, 1, 44, 5, 44, 636, 8, 44, 10, 44, 12, 44, 639, 9, 44, 1, 45, 1, 45, 3, 45, 643, 8, 45, 1, 45, 1, 45, 3, 45, 647, 8, 45, 1, 45, 1, 45, 3, 45, 651, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 657, 8, 46, 3, 46, 659, 8, 46, 1, 47, 1, 47, 1, 47, 5, 47, 664, 8, 47, 10, 47, 12, 47, 667, 9, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 3, 49, 674, 8, 49, 1, 49, 3, 49, 677, 8, 49, 1, 49, 3, 49, 680, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 699, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 713, 8, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 727, 8, 56, 10, 56, 12, 56, 730, 9, 56, 1, 56, 3, 56, 733, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 742, 8, 56, 10, 56, 12, 56, 745, 9, 56, 1, 56, 3, 56, 748, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 757, 8, 56, 10, 56, 12, 56, 760, 9, 56, 1, 56, 3, 56, 763, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 770, 8, 56, 1, 56, 1, 56, 3, 56, 774, 8, 56, 1, 57, 1, 57, 1, 57, 5, 57, 779, 8, 57, 10, 57, 12, 57, 782, 9, 57, 1, 57, 3, 57, 785, 8, 57, 1, 58, 1, 58, 1, 58, 3, 58, 790, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 4, 58, 797, 8, 58, 11, 58, 12, 58, 798, 1, 58, 1, 58, 3, 58, 803, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 827, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 844, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 850, 8, 58, 1, 58, 3, 58, 853, 8, 58, 1, 58, 3, 58, 856, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 866, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 872, 8, 58, 1, 58, 3, 58, 875, 8, 58, 1, 58, 3, 58, 878, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 886, 8, 58, 1, 58, 3, 58, 889, 8, 58, 1, 58, 1, 58, 3, 58, 893, 8, 58, 1, 58, 3, 58, 896, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 910, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 927, 8, 58, 1, 58, 1, 58, 1, 58, 3, 58, 932, 8, 58, 1, 58, 1, 58, 3, 58, 936, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 942, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 949, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 961, 8, 58, 1, 58, 1, 58, 3, 58, 965, 8, 58, 1, 58, 3, 58, 968, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 977, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 991, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 1030, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 1038, 8, 58, 5, 58, 1040, 8, 58, 10, 58, 12, 58, 1043, 9, 58, 1, 59, 1, 59, 1, 59, 5, 59, 1048, 8, 59, 10, 59, 12, 59, 1051, 9, 59, 1, 59, 3, 59, 1054, 8, 59, 1, 60, 1, 60, 3, 60, 1058, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 1064, 8, 61, 10, 61, 12, 61, 1067, 9, 61, 1, 61, 3, 61, 1070, 8, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 1077, 8, 61, 10, 61, 12, 61, 1080, 9, 61, 1, 61, 3, 61, 1083, 8, 61, 3, 61, 1085, 8, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 5, 62, 1093, 8, 62, 10, 62, 12, 62, 1096, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 5, 62, 1104, 8, 62, 10, 62, 12, 62, 1107, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 1115, 8, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 1122, 8, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 1135, 8, 63, 1, 64, 1, 64, 1, 64, 5, 64, 1140, 8, 64, 10, 64, 12, 64, 1143, 9, 64, 1, 64, 3, 64, 1146, 8, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 1158, 8, 65, 1, 66, 1, 66, 1, 66, 1, 66, 3, 66, 1164, 8, 66, 1, 66, 3, 66, 1167, 8, 66, 1, 67, 1, 67, 1, 67, 5, 67, 1172, 8, 67, 10, 67, 12, 67, 1175, 9, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1186, 8, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1192, 8, 68, 5, 68, 1194, 8, 68, 10, 68, 12, 68, 1197, 9, 68, 1, 69, 1, 69, 1, 69, 3, 69, 1202, 8, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 3, 70, 1209, 8, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 5, 71, 1216, 8, 71, 10, 71, 12, 71, 1219, 9, 71, 1, 71, 3, 71, 1222, 8, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 1232, 8, 73, 3, 73, 1234, 8, 73, 1, 74, 3, 74, 1237, 8, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 1245, 8, 74, 1, 75, 1, 75, 1, 75, 3, 75, 1250, 8, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 3, 79, 1260, 8, 79, 1, 80, 1, 80, 1, 80, 3, 80, 1265, 8, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 3, 83, 1277, 8, 83, 1, 84, 1, 84, 5, 84, 1281, 8, 84, 10, 84, 12, 84, 1284, 9, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 3, 85, 1293, 8, 85, 1, 86, 1, 86, 5, 86, 1297, 8, 86, 10, 86, 12, 86, 1300, 9, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 3, 87, 1309, 8, 87, 1, 87, 0, 3, 78, 116, 136, 88, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 0, 16, 2, 0, 18, 18, 74, 74, 2, 0, 44, 44, 51, 51, 3, 0, 1, 1, 4, 4, 8, 8, 4, 0, 1, 1, 3, 4, 8, 8, 80, 80, 2, 0, 51, 51, 73, 73, 2, 0, 1, 1, 4, 4, 2, 0, 7, 7, 22, 23, 2, 0, 30, 30, 49, 49, 2, 0, 71, 71, 76, 76, 3, 0, 10, 10, 50, 50, 90, 90, 2, 0, 41, 41, 53, 53, 1, 0, 107, 108, 2, 0, 118, 118, 139, 139, 7, 0, 21, 21, 38, 38, 55, 56, 70, 70, 78, 78, 97, 97, 103, 103, 16, 0, 1, 13, 15, 20, 22, 28, 30, 30, 32, 37, 39, 42, 44, 51, 53, 54, 58, 58, 60, 69, 71, 77, 79, 83, 85, 92, 94, 96, 98, 99, 101, 102, 4, 0, 20, 20, 30, 30, 39, 39, 48, 48, 1479, 0, 179, 1, 0, 0, 0, 2, 186, 1, 0, 0, 0, 4, 188, 1, 0, 0, 0, 6, 190, 1, 0, 0, 0, 8, 197, 1, 0, 0, 0, 10, 220, 1, 0, 0, 0, 12, 222, 1, 0, 0, 0, 14, 229, 1, 0, 0, 0, 16, 236, 1, 0, 0, 0, 18, 249, 1, 0, 0, 0, 20, 261, 1, 0, 0, 0, 22, 270, 1, 0, 0, 0, 24, 278, 1, 0, 0, 0, 26, 300, 1, 0, 0, 0, 28, 315, 1, 0, 0, 0, 30, 324, 1, 0, 0, 0, 32, 329, 1, 0, 0, 0, 34, 333, 1, 0, 0, 0, 36, 335, 1, 0, 0, 0, 38, 344, 1, 0, 0, 0, 40, 348, 1, 0, 0, 0, 42, 362, 1, 0, 0, 0, 44, 366, 1, 0, 0, 0, 46, 381, 1, 0, 0, 0, 48, 384, 1, 0, 0, 0, 50, 433, 1, 0, 0, 0, 52, 436, 1, 0, 0, 0, 54, 442, 1, 0, 0, 0, 56, 446, 1, 0, 0, 0, 58, 452, 1, 0, 0, 0, 60, 470, 1, 0, 0, 0, 62, 473, 1, 0, 0, 0, 64, 476, 1, 0, 0, 0, 66, 486, 1, 0, 0, 0, 68, 489, 1, 0, 0, 0, 70, 493, 1, 0, 0, 0, 72, 526, 1, 0, 0, 0, 74, 528, 1, 0, 0, 0, 76, 531, 1, 0, 0, 0, 78, 546, 1, 0, 0, 0, 80, 608, 1, 0, 0, 0, 82, 613, 1, 0, 0, 0, 84, 624, 1, 0, 0, 0, 86, 626, 1, 0, 0, 0, 88, 632, 1, 0, 0, 0, 90, 640, 1, 0, 0, 0, 92, 658, 1, 0, 0, 0, 94, 660, 1, 0, 0, 0, 96, 668, 1, 0, 0, 0, 98, 673, 1, 0, 0, 0, 100, 681, 1, 0, 0, 0, 102, 685, 1, 0, 0, 0, 104, 689, 1, 0, 0, 0, 106, 698, 1, 0, 0, 0, 108, 712, 1, 0, 0, 0, 110, 714, 1, 0, 0, 0, 112, 773, 1, 0, 0, 0, 114, 775, 1, 0, 0, 0, 116, 935, 1, 0, 0, 0, 118, 1044, 1, 0, 0, 0, 120, 1057, 1, 0, 0, 0, 122, 1084, 1, 0, 0, 0, 124, 1121, 1, 0, 0, 0, 126, 1134, 1, 0, 0, 0, 128, 1136, 1, 0, 0, 0, 130, 1157, 1, 0, 0, 0, 132, 1166, 1, 0, 0, 0, 134, 1168, 1, 0, 0, 0, 136, 1185, 1, 0, 0, 0, 138, 1198, 1, 0, 0, 0, 140, 1208, 1, 0, 0, 0, 142, 1212, 1, 0, 0, 0, 144, 1223, 1, 0, 0, 0, 146, 1233, 1, 0, 0, 0, 148, 1236, 1, 0, 0, 0, 150, 1249, 1, 0, 0, 0, 152, 1251, 1, 0, 0, 0, 154, 1253, 1, 0, 0, 0, 156, 1255, 1, 0, 0, 0, 158, 1259, 1, 0, 0, 0, 160, 1264, 1, 0, 0, 0, 162, 1266, 1, 0, 0, 0, 164, 1270, 1, 0, 0, 0, 166, 1276, 1, 0, 0, 0, 168, 1278, 1, 0, 0, 0, 170, 1292, 1, 0, 0, 0, 172, 1294, 1, 0, 0, 0, 174, 1308, 1, 0, 0, 0, 176, 178, 3, 2, 1, 0, 177, 176, 1, 0, 0, 0, 178, 181, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 182, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 182, 183, 5, 0, 0, 1, 183, 1, 1, 0, 0, 0, 184, 187, 3, 6, 3, 0, 185, 187, 3, 10, 5, 0, 186, 184, 1, 0, 0, 0, 186, 185, 1, 0, 0, 0, 187, 3, 1, 0, 0, 0, 188, 189, 3, 116, 58, 0, 189, 5, 1, 0, 0, 0, 190, 191, 5, 52, 0, 0, 191, 195, 3, 160, 80, 0, 192, 193, 5, 115, 0, 0, 193, 194, 5, 122, 0, 0, 194, 196, 3, 4, 2, 0, 195, 192, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 7, 1, 0, 0, 0, 197, 202, 3, 160, 80, 0, 198, 199, 5, 116, 0, 0, 199, 201, 3, 160, 80, 0, 200, 198, 1, 0, 0, 0, 201, 204, 1, 0, 0, 0, 202, 200, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 203, 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 205, 207, 5, 116, 0, 0, 206, 205, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 9, 1, 0, 0, 0, 208, 221, 3, 12, 6, 0, 209, 221, 3, 14, 7, 0, 210, 221, 3, 18, 9, 0, 211, 221, 3, 20, 10, 0, 212, 221, 3, 22, 11, 0, 213, 221, 3, 26, 13, 0, 214, 221, 3, 24, 12, 0, 215, 221, 3, 28, 14, 0, 216, 221, 3, 30, 15, 0, 217, 221, 3, 36, 18, 0, 218, 221, 3, 32, 16, 0, 219, 221, 3, 34, 17, 0, 220, 208, 1, 0, 0, 0, 220, 209, 1, 0, 0, 0, 220, 210, 1, 0, 0, 0, 220, 211, 1, 0, 0, 0, 220, 212, 1, 0, 0, 0, 220, 213, 1, 0, 0, 0, 220, 214, 1, 0, 0, 0, 220, 215, 1, 0, 0, 0, 220, 216, 1, 0, 0, 0, 220, 217, 1, 0, 0, 0, 220, 218, 1, 0, 0, 0, 220, 219, 1, 0, 0, 0, 221, 11, 1, 0, 0, 0, 222, 224, 5, 72, 0, 0, 223, 225, 3, 4, 2, 0, 224, 223, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 227, 1, 0, 0, 0, 226, 228, 5, 150, 0, 0, 227, 226, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 13, 1, 0, 0, 0, 229, 231, 5, 84, 0, 0, 230, 232, 3, 4, 2, 0, 231, 230, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 234, 1, 0, 0, 0, 233, 235, 5, 150, 0, 0, 234, 233, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 15, 1, 0, 0, 0, 236, 245, 5, 14, 0, 0, 237, 238, 5, 130, 0, 0, 238, 241, 3, 160, 80, 0, 239, 240, 5, 115, 0, 0, 240, 242, 3, 160, 80, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 243, 1, 0, 0, 0, 243, 244, 5, 149, 0, 0, 244, 246, 1, 0, 0, 0, 245, 237, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 248, 3, 36, 18, 0, 248, 17, 1, 0, 0, 0, 249, 250, 5, 93, 0, 0, 250, 254, 3, 36, 18, 0, 251, 253, 3, 16, 8, 0, 252, 251, 1, 0, 0, 0, 253, 256, 1, 0, 0, 0, 254, 252, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 255, 259, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 257, 258, 5, 29, 0, 0, 258, 260, 3, 36, 18, 0, 259, 257, 1, 0, 0, 0, 259, 260, 1, 0, 0, 0, 260, 19, 1, 0, 0, 0, 261, 262, 5, 40, 0, 0, 262, 263, 5, 130, 0, 0, 263, 264, 3, 4, 2, 0, 264, 265, 5, 149, 0, 0, 265, 268, 3, 10, 5, 0, 266, 267, 5, 25, 0, 0, 267, 269, 3, 10, 5, 0, 268, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 21, 1, 0, 0, 0, 270, 271, 5, 100, 0, 0, 271, 272, 5, 130, 0, 0, 272, 273, 3, 4, 2, 0, 273, 274, 5, 149, 0, 0, 274, 276, 3, 10, 5, 0, 275, 277, 5, 150, 0, 0, 276, 275, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 23, 1, 0, 0, 0, 278, 279, 5, 33, 0, 0, 279, 283, 5, 130, 0, 0, 280, 284, 3, 6, 3, 0, 281, 284, 3, 30, 15, 0, 282, 284, 3, 4, 2, 0, 283, 280, 1, 0, 0, 0, 283, 281, 1, 0, 0, 0, 283, 282, 1, 0, 0, 0, 283, 284, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287, 5, 150, 0, 0, 286, 288, 3, 4, 2, 0, 287, 286, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 293, 5, 150, 0, 0, 290, 294, 3, 6, 3, 0, 291, 294, 3, 30, 15, 0, 292, 294, 3, 4, 2, 0, 293, 290, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 293, 292, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 296, 5, 149, 0, 0, 296, 298, 3, 10, 5, 0, 297, 299, 5, 150, 0, 0, 298, 297, 1, 0, 0, 0, 298, 299, 1, 0, 0, 0, 299, 25, 1, 0, 0, 0, 300, 301, 5, 33, 0, 0, 301, 302, 5, 130, 0, 0, 302, 303, 5, 52, 0, 0, 303, 306, 3, 160, 80, 0, 304, 305, 5, 116, 0, 0, 305, 307, 3, 160, 80, 0, 306, 304, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 309, 5, 42, 0, 0, 309, 310, 3, 4, 2, 0, 310, 311, 5, 149, 0, 0, 311, 313, 3, 10, 5, 0, 312, 314, 5, 150, 0, 0, 313, 312, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 27, 1, 0, 0, 0, 315, 316, 5, 31, 0, 0, 316, 317, 3, 160, 80, 0, 317, 319, 5, 130, 0, 0, 318, 320, 3, 8, 4, 0, 319, 318, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 322, 5, 149, 0, 0, 322, 323, 3, 36, 18, 0, 323, 29, 1, 0, 0, 0, 324, 325, 3, 4, 2, 0, 325, 326, 5, 115, 0, 0, 326, 327, 5, 122, 0, 0, 327, 328, 3, 4, 2, 0, 328, 31, 1, 0, 0, 0, 329, 331, 3, 4, 2, 0, 330, 332, 5, 150, 0, 0, 331, 330, 1, 0, 0, 0, 331, 332, 1, 0, 0, 0, 332, 33, 1, 0, 0, 0, 333, 334, 5, 150, 0, 0, 334, 35, 1, 0, 0, 0, 335, 339, 5, 128, 0, 0, 336, 338, 3, 2, 1, 0, 337, 336, 1, 0, 0, 0, 338, 341, 1, 0, 0, 0, 339, 337, 1, 0, 0, 0, 339, 340, 1, 0, 0, 0, 340, 342, 1, 0, 0, 0, 341, 339, 1, 0, 0, 0, 342, 343, 5, 147, 0, 0, 343, 37, 1, 0, 0, 0, 344, 345, 3, 4, 2, 0, 345, 346, 5, 115, 0, 0, 346, 347, 3, 4, 2, 0, 347, 39, 1, 0, 0, 0, 348, 353, 3, 38, 19, 0, 349, 350, 5, 116, 0, 0, 350, 352, 3, 38, 19, 0, 351, 349, 1, 0, 0, 0, 352, 355, 1, 0, 0, 0, 353, 351, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 357, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, 358, 5, 116, 0, 0, 357, 356, 1, 0, 0, 0, 357, 358, 1, 0, 0, 0, 358, 41, 1, 0, 0, 0, 359, 363, 3, 44, 22, 0, 360, 363, 3, 48, 24, 0, 361, 363, 3, 124, 62, 0, 362, 359, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 361, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 365, 5, 0, 0, 1, 365, 43, 1, 0, 0, 0, 366, 372, 3, 46, 23, 0, 367, 368, 5, 95, 0, 0, 368, 369, 5, 1, 0, 0, 369, 371, 3, 46, 23, 0, 370, 367, 1, 0, 0, 0, 371, 374, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 372, 373, 1, 0, 0, 0, 373, 45, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 375, 382, 3, 48, 24, 0, 376, 377, 5, 130, 0, 0, 377, 378, 3, 44, 22, 0, 378, 379, 5, 149, 0, 0, 379, 382, 1, 0, 0, 0, 380, 382, 3, 164, 82, 0, 381, 375, 1, 0, 0, 0, 381, 376, 1, 0, 0, 0, 381, 380, 1, 0, 0, 0, 382, 47, 1, 0, 0, 0, 383, 385, 3, 50, 25, 0, 384, 383, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 386, 1, 0, 0, 0, 386, 388, 5, 79, 0, 0, 387, 389, 5, 24, 0, 0, 388, 387, 1, 0, 0, 0, 388, 389, 1, 0, 0, 0, 389, 391, 1, 0, 0, 0, 390, 392, 3, 52, 26, 0, 391, 390, 1, 0, 0, 0, 391, 392, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 395, 3, 114, 57, 0, 394, 396, 3, 54, 27, 0, 395, 394, 1, 0, 0, 0, 395, 396, 1, 0, 0, 0, 396, 398, 1, 0, 0, 0, 397, 399, 3, 56, 28, 0, 398, 397, 1, 0, 0, 0, 398, 399, 1, 0, 0, 0, 399, 401, 1, 0, 0, 0, 400, 402, 3, 60, 30, 0, 401, 400, 1, 0, 0, 0, 401, 402, 1, 0, 0, 0, 402, 404, 1, 0, 0, 0, 403, 405, 3, 62, 31, 0, 404, 403, 1, 0, 0, 0, 404, 405, 1, 0, 0, 0, 405, 407, 1, 0, 0, 0, 406, 408, 3, 64, 32, 0, 407, 406, 1, 0, 0, 0, 407, 408, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 410, 5, 102, 0, 0, 410, 412, 7, 0, 0, 0, 411, 409, 1, 0, 0, 0, 411, 412, 1, 0, 0, 0, 412, 415, 1, 0, 0, 0, 413, 414, 5, 102, 0, 0, 414, 416, 5, 89, 0, 0, 415, 413, 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 418, 1, 0, 0, 0, 417, 419, 3, 66, 33, 0, 418, 417, 1, 0, 0, 0, 418, 419, 1, 0, 0, 0, 419, 421, 1, 0, 0, 0, 420, 422, 3, 58, 29, 0, 421, 420, 1, 0, 0, 0, 421, 422, 1, 0, 0, 0, 422, 424, 1, 0, 0, 0, 423, 425, 3, 68, 34, 0, 424, 423, 1, 0, 0, 0, 424, 425, 1, 0, 0, 0, 425, 428, 1, 0, 0, 0, 426, 429, 3, 72, 36, 0, 427, 429, 3, 74, 37, 0, 428, 426, 1, 0, 0, 0, 428, 427, 1, 0, 0, 0, 428, 429, 1, 0, 0, 0, 429, 431, 1, 0, 0, 0, 430, 432, 3, 76, 38, 0, 431, 430, 1, 0, 0, 0, 431, 432, 1, 0, 0, 0, 432, 49, 1, 0, 0, 0, 433, 434, 5, 102, 0, 0, 434, 435, 3, 128, 64, 0, 435, 51, 1, 0, 0, 0, 436, 437, 5, 88, 0, 0, 437, 440, 5, 108, 0, 0, 438, 439, 5, 102, 0, 0, 439, 441, 5, 85, 0, 0, 440, 438, 1, 0, 0, 0, 440, 441, 1, 0, 0, 0, 441, 53, 1, 0, 0, 0, 442, 443, 5, 34, 0, 0, 443, 444, 3, 78, 39, 0, 444, 55, 1, 0, 0, 0, 445, 447, 7, 1, 0, 0, 446, 445, 1, 0, 0, 0, 446, 447, 1, 0, 0, 0, 447, 448, 1, 0, 0, 0, 448, 449, 5, 5, 0, 0, 449, 450, 5, 47, 0, 0, 450, 451, 3, 114, 57, 0, 451, 57, 1, 0, 0, 0, 452, 453, 5, 101, 0, 0, 453, 454, 3, 160, 80, 0, 454, 455, 5, 6, 0, 0, 455, 456, 5, 130, 0, 0, 456, 457, 3, 98, 49, 0, 457, 467, 5, 149, 0, 0, 458, 459, 5, 116, 0, 0, 459, 460, 3, 160, 80, 0, 460, 461, 5, 6, 0, 0, 461, 462, 5, 130, 0, 0, 462, 463, 3, 98, 49, 0, 463, 464, 5, 149, 0, 0, 464, 466, 1, 0, 0, 0, 465, 458, 1, 0, 0, 0, 466, 469, 1, 0, 0, 0, 467, 465, 1, 0, 0, 0, 467, 468, 1, 0, 0, 0, 468, 59, 1, 0, 0, 0, 469, 467, 1, 0, 0, 0, 470, 471, 5, 69, 0, 0, 471, 472, 3, 116, 58, 0, 472, 61, 1, 0, 0, 0, 473, 474, 5, 99, 0, 0, 474, 475, 3, 116, 58, 0, 475, 63, 1, 0, 0, 0, 476, 477, 5, 36, 0, 0, 477, 484, 5, 11, 0, 0, 478, 479, 7, 0, 0, 0, 479, 480, 5, 130, 0, 0, 480, 481, 3, 114, 57, 0, 481, 482, 5, 149, 0, 0, 482, 485, 1, 0, 0, 0, 483, 485, 3, 114, 57, 0, 484, 478, 1, 0, 0, 0, 484, 483, 1, 0, 0, 0, 485, 65, 1, 0, 0, 0, 486, 487, 5, 37, 0, 0, 487, 488, 3, 116, 58, 0, 488, 67, 1, 0, 0, 0, 489, 490, 5, 64, 0, 0, 490, 491, 5, 11, 0, 0, 491, 492, 3, 88, 44, 0, 492, 69, 1, 0, 0, 0, 493, 494, 5, 64, 0, 0, 494, 495, 5, 11, 0, 0, 495, 496, 3, 114, 57, 0, 496, 71, 1, 0, 0, 0, 497, 498, 5, 54, 0, 0, 498, 501, 3, 116, 58, 0, 499, 500, 5, 116, 0, 0, 500, 502, 3, 116, 58, 0, 501, 499, 1, 0, 0, 0, 501, 502, 1, 0, 0, 0, 502, 507, 1, 0, 0, 0, 503, 504, 5, 102, 0, 0, 504, 508, 5, 85, 0, 0, 505, 506, 5, 11, 0, 0, 506, 508, 3, 114, 57, 0, 507, 503, 1, 0, 0, 0, 507, 505, 1, 0, 0, 0, 507, 508, 1, 0, 0, 0, 508, 527, 1, 0, 0, 0, 509, 510, 5, 54, 0, 0, 510, 513, 3, 116, 58, 0, 511, 512, 5, 102, 0, 0, 512, 514, 5, 85, 0, 0, 513, 511, 1, 0, 0, 0, 513, 514, 1, 0, 0, 0, 514, 515, 1, 0, 0, 0, 515, 516, 5, 61, 0, 0, 516, 517, 3, 116, 58, 0, 517, 527, 1, 0, 0, 0, 518, 519, 5, 54, 0, 0, 519, 520, 3, 116, 58, 0, 520, 521, 5, 61, 0, 0, 521, 524, 3, 116, 58, 0, 522, 523, 5, 11, 0, 0, 523, 525, 3, 114, 57, 0, 524, 522, 1, 0, 0, 0, 524, 525, 1, 0, 0, 0, 525, 527, 1, 0, 0, 0, 526, 497, 1, 0, 0, 0, 526, 509, 1, 0, 0, 0, 526, 518, 1, 0, 0, 0, 527, 73, 1, 0, 0, 0, 528, 529, 5, 61, 0, 0, 529, 530, 3, 116, 58, 0, 530, 75, 1, 0, 0, 0, 531, 532, 5, 81, 0, 0, 532, 533, 3, 94, 47, 0, 533, 77, 1, 0, 0, 0, 534, 535, 6, 39, -1, 0, 535, 537, 3, 136, 68, 0, 536, 538, 5, 28, 0, 0, 537, 536, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 540, 1, 0, 0, 0, 539, 541, 3, 86, 43, 0, 540, 539, 1, 0, 0, 0, 540, 541, 1, 0, 0, 0, 541, 547, 1, 0, 0, 0, 542, 543, 5, 130, 0, 0, 543, 544, 3, 78, 39, 0, 544, 545, 5, 149, 0, 0, 545, 547, 1, 0, 0, 0, 546, 534, 1, 0, 0, 0, 546, 542, 1, 0, 0, 0, 547, 562, 1, 0, 0, 0, 548, 549, 10, 3, 0, 0, 549, 550, 3, 82, 41, 0, 550, 551, 3, 78, 39, 4, 551, 561, 1, 0, 0, 0, 552, 554, 10, 4, 0, 0, 553, 555, 3, 80, 40, 0, 554, 553, 1, 0, 0, 0, 554, 555, 1, 0, 0, 0, 555, 556, 1, 0, 0, 0, 556, 557, 5, 47, 0, 0, 557, 558, 3, 78, 39, 0, 558, 559, 3, 84, 42, 0, 559, 561, 1, 0, 0, 0, 560, 548, 1, 0, 0, 0, 560, 552, 1, 0, 0, 0, 561, 564, 1, 0, 0, 0, 562, 560, 1, 0, 0, 0, 562, 563, 1, 0, 0, 0, 563, 79, 1, 0, 0, 0, 564, 562, 1, 0, 0, 0, 565, 567, 7, 2, 0, 0, 566, 565, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 568, 1, 0, 0, 0, 568, 575, 5, 44, 0, 0, 569, 571, 5, 44, 0, 0, 570, 572, 7, 2, 0, 0, 571, 570, 1, 0, 0, 0, 571, 572, 1, 0, 0, 0, 572, 575, 1, 0, 0, 0, 573, 575, 7, 2, 0, 0, 574, 566, 1, 0, 0, 0, 574, 569, 1, 0, 0, 0, 574, 573, 1, 0, 0, 0, 575, 609, 1, 0, 0, 0, 576, 578, 7, 3, 0, 0, 577, 576, 1, 0, 0, 0, 577, 578, 1, 0, 0, 0, 578, 579, 1, 0, 0, 0, 579, 581, 7, 4, 0, 0, 580, 582, 5, 65, 0, 0, 581, 580, 1, 0, 0, 0, 581, 582, 1, 0, 0, 0, 582, 591, 1, 0, 0, 0, 583, 585, 7, 4, 0, 0, 584, 586, 5, 65, 0, 0, 585, 584, 1, 0, 0, 0, 585, 586, 1, 0, 0, 0, 586, 588, 1, 0, 0, 0, 587, 589, 7, 3, 0, 0, 588, 587, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 591, 1, 0, 0, 0, 590, 577, 1, 0, 0, 0, 590, 583, 1, 0, 0, 0, 591, 609, 1, 0, 0, 0, 592, 594, 7, 5, 0, 0, 593, 592, 1, 0, 0, 0, 593, 594, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, 595, 597, 5, 35, 0, 0, 596, 598, 5, 65, 0, 0, 597, 596, 1, 0, 0, 0, 597, 598, 1, 0, 0, 0, 598, 607, 1, 0, 0, 0, 599, 601, 5, 35, 0, 0, 600, 602, 5, 65, 0, 0, 601, 600, 1, 0, 0, 0, 601, 602, 1, 0, 0, 0, 602, 604, 1, 0, 0, 0, 603, 605, 7, 5, 0, 0, 604, 603, 1, 0, 0, 0, 604, 605, 1, 0, 0, 0, 605, 607, 1, 0, 0, 0, 606, 593, 1, 0, 0, 0, 606, 599, 1, 0, 0, 0, 607, 609, 1, 0, 0, 0, 608, 574, 1, 0, 0, 0, 608, 590, 1, 0, 0, 0, 608, 606, 1, 0, 0, 0, 609, 81, 1, 0, 0, 0, 610, 611, 5, 17, 0, 0, 611, 614, 5, 47, 0, 0, 612, 614, 5, 116, 0, 0, 613, 610, 1, 0, 0, 0, 613, 612, 1, 0, 0, 0, 614, 83, 1, 0, 0, 0, 615, 616, 5, 62, 0, 0, 616, 625, 3, 114, 57, 0, 617, 618, 5, 96, 0, 0, 618, 619, 5, 130, 0, 0, 619, 620, 3, 114, 57, 0, 620, 621, 5, 149, 0, 0, 621, 625, 1, 0, 0, 0, 622, 623, 5, 96, 0, 0, 623, 625, 3, 114, 57, 0, 624, 615, 1, 0, 0, 0, 624, 617, 1, 0, 0, 0, 624, 622, 1, 0, 0, 0, 625, 85, 1, 0, 0, 0, 626, 627, 5, 77, 0, 0, 627, 630, 3, 92, 46, 0, 628, 629, 5, 61, 0, 0, 629, 631, 3, 92, 46, 0, 630, 628, 1, 0, 0, 0, 630, 631, 1, 0, 0, 0, 631, 87, 1, 0, 0, 0, 632, 637, 3, 90, 45, 0, 633, 634, 5, 116, 0, 0, 634, 636, 3, 90, 45, 0, 635, 633, 1, 0, 0, 0, 636, 639, 1, 0, 0, 0, 637, 635, 1, 0, 0, 0, 637, 638, 1, 0, 0, 0, 638, 89, 1, 0, 0, 0, 639, 637, 1, 0, 0, 0, 640, 642, 3, 116, 58, 0, 641, 643, 7, 6, 0, 0, 642, 641, 1, 0, 0, 0, 642, 643, 1, 0, 0, 0, 643, 646, 1, 0, 0, 0, 644, 645, 5, 60, 0, 0, 645, 647, 7, 7, 0, 0, 646, 644, 1, 0, 0, 0, 646, 647, 1, 0, 0, 0, 647, 650, 1, 0, 0, 0, 648, 649, 5, 16, 0, 0, 649, 651, 5, 110, 0, 0, 650, 648, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 91, 1, 0, 0, 0, 652, 659, 3, 164, 82, 0, 653, 656, 3, 148, 74, 0, 654, 655, 5, 151, 0, 0, 655, 657, 3, 148, 74, 0, 656, 654, 1, 0, 0, 0, 656, 657, 1, 0, 0, 0, 657, 659, 1, 0, 0, 0, 658, 652, 1, 0, 0, 0, 658, 653, 1, 0, 0, 0, 659, 93, 1, 0, 0, 0, 660, 665, 3, 96, 48, 0, 661, 662, 5, 116, 0, 0, 662, 664, 3, 96, 48, 0, 663, 661, 1, 0, 0, 0, 664, 667, 1, 0, 0, 0, 665, 663, 1, 0, 0, 0, 665, 666, 1, 0, 0, 0, 666, 95, 1, 0, 0, 0, 667, 665, 1, 0, 0, 0, 668, 669, 3, 160, 80, 0, 669, 670, 5, 122, 0, 0, 670, 671, 3, 150, 75, 0, 671, 97, 1, 0, 0, 0, 672, 674, 3, 100, 50, 0, 673, 672, 1, 0, 0, 0, 673, 674, 1, 0, 0, 0, 674, 676, 1, 0, 0, 0, 675, 677, 3, 102, 51, 0, 676, 675, 1, 0, 0, 0, 676, 677, 1, 0, 0, 0, 677, 679, 1, 0, 0, 0, 678, 680, 3, 104, 52, 0, 679, 678, 1, 0, 0, 0, 679, 680, 1, 0, 0, 0, 680, 99, 1, 0, 0, 0, 681, 682, 5, 67, 0, 0, 682, 683, 5, 11, 0, 0, 683, 684, 3, 114, 57, 0, 684, 101, 1, 0, 0, 0, 685, 686, 5, 64, 0, 0, 686, 687, 5, 11, 0, 0, 687, 688, 3, 88, 44, 0, 688, 103, 1, 0, 0, 0, 689, 690, 7, 8, 0, 0, 690, 691, 3, 106, 53, 0, 691, 105, 1, 0, 0, 0, 692, 699, 3, 108, 54, 0, 693, 694, 5, 9, 0, 0, 694, 695, 3, 108, 54, 0, 695, 696, 5, 2, 0, 0, 696, 697, 3, 108, 54, 0, 697, 699, 1, 0, 0, 0, 698, 692, 1, 0, 0, 0, 698, 693, 1, 0, 0, 0, 699, 107, 1, 0, 0, 0, 700, 701, 5, 19, 0, 0, 701, 713, 5, 75, 0, 0, 702, 703, 5, 94, 0, 0, 703, 713, 5, 68, 0, 0, 704, 705, 5, 94, 0, 0, 705, 713, 5, 32, 0, 0, 706, 707, 3, 148, 74, 0, 707, 708, 5, 68, 0, 0, 708, 713, 1, 0, 0, 0, 709, 710, 3, 148, 74, 0, 710, 711, 5, 32, 0, 0, 711, 713, 1, 0, 0, 0, 712, 700, 1, 0, 0, 0, 712, 702, 1, 0, 0, 0, 712, 704, 1, 0, 0, 0, 712, 706, 1, 0, 0, 0, 712, 709, 1, 0, 0, 0, 713, 109, 1, 0, 0, 0, 714, 715, 3, 116, 58, 0, 715, 716, 5, 0, 0, 1, 716, 111, 1, 0, 0, 0, 717, 774, 3, 160, 80, 0, 718, 719, 3, 160, 80, 0, 719, 720, 5, 130, 0, 0, 720, 721, 3, 160, 80, 0, 721, 728, 3, 112, 56, 0, 722, 723, 5, 116, 0, 0, 723, 724, 3, 160, 80, 0, 724, 725, 3, 112, 56, 0, 725, 727, 1, 0, 0, 0, 726, 722, 1, 0, 0, 0, 727, 730, 1, 0, 0, 0, 728, 726, 1, 0, 0, 0, 728, 729, 1, 0, 0, 0, 729, 732, 1, 0, 0, 0, 730, 728, 1, 0, 0, 0, 731, 733, 5, 116, 0, 0, 732, 731, 1, 0, 0, 0, 732, 733, 1, 0, 0, 0, 733, 734, 1, 0, 0, 0, 734, 735, 5, 149, 0, 0, 735, 774, 1, 0, 0, 0, 736, 737, 3, 160, 80, 0, 737, 738, 5, 130, 0, 0, 738, 743, 3, 162, 81, 0, 739, 740, 5, 116, 0, 0, 740, 742, 3, 162, 81, 0, 741, 739, 1, 0, 0, 0, 742, 745, 1, 0, 0, 0, 743, 741, 1, 0, 0, 0, 743, 744, 1, 0, 0, 0, 744, 747, 1, 0, 0, 0, 745, 743, 1, 0, 0, 0, 746, 748, 5, 116, 0, 0, 747, 746, 1, 0, 0, 0, 747, 748, 1, 0, 0, 0, 748, 749, 1, 0, 0, 0, 749, 750, 5, 149, 0, 0, 750, 774, 1, 0, 0, 0, 751, 752, 3, 160, 80, 0, 752, 753, 5, 130, 0, 0, 753, 758, 3, 112, 56, 0, 754, 755, 5, 116, 0, 0, 755, 757, 3, 112, 56, 0, 756, 754, 1, 0, 0, 0, 757, 760, 1, 0, 0, 0, 758, 756, 1, 0, 0, 0, 758, 759, 1, 0, 0, 0, 759, 762, 1, 0, 0, 0, 760, 758, 1, 0, 0, 0, 761, 763, 5, 116, 0, 0, 762, 761, 1, 0, 0, 0, 762, 763, 1, 0, 0, 0, 763, 764, 1, 0, 0, 0, 764, 765, 5, 149, 0, 0, 765, 774, 1, 0, 0, 0, 766, 767, 3, 160, 80, 0, 767, 769, 5, 130, 0, 0, 768, 770, 3, 114, 57, 0, 769, 768, 1, 0, 0, 0, 769, 770, 1, 0, 0, 0, 770, 771, 1, 0, 0, 0, 771, 772, 5, 149, 0, 0, 772, 774, 1, 0, 0, 0, 773, 717, 1, 0, 0, 0, 773, 718, 1, 0, 0, 0, 773, 736, 1, 0, 0, 0, 773, 751, 1, 0, 0, 0, 773, 766, 1, 0, 0, 0, 774, 113, 1, 0, 0, 0, 775, 780, 3, 116, 58, 0, 776, 777, 5, 116, 0, 0, 777, 779, 3, 116, 58, 0, 778, 776, 1, 0, 0, 0, 779, 782, 1, 0, 0, 0, 780, 778, 1, 0, 0, 0, 780, 781, 1, 0, 0, 0, 781, 784, 1, 0, 0, 0, 782, 780, 1, 0, 0, 0, 783, 785, 5, 116, 0, 0, 784, 783, 1, 0, 0, 0, 784, 785, 1, 0, 0, 0, 785, 115, 1, 0, 0, 0, 786, 787, 6, 58, -1, 0, 787, 789, 5, 12, 0, 0, 788, 790, 3, 116, 58, 0, 789, 788, 1, 0, 0, 0, 789, 790, 1, 0, 0, 0, 790, 796, 1, 0, 0, 0, 791, 792, 5, 98, 0, 0, 792, 793, 3, 116, 58, 0, 793, 794, 5, 83, 0, 0, 794, 795, 3, 116, 58, 0, 795, 797, 1, 0, 0, 0, 796, 791, 1, 0, 0, 0, 797, 798, 1, 0, 0, 0, 798, 796, 1, 0, 0, 0, 798, 799, 1, 0, 0, 0, 799, 802, 1, 0, 0, 0, 800, 801, 5, 25, 0, 0, 801, 803, 3, 116, 58, 0, 802, 800, 1, 0, 0, 0, 802, 803, 1, 0, 0, 0, 803, 804, 1, 0, 0, 0, 804, 805, 5, 26, 0, 0, 805, 936, 1, 0, 0, 0, 806, 807, 5, 13, 0, 0, 807, 808, 5, 130, 0, 0, 808, 809, 3, 116, 58, 0, 809, 810, 5, 6, 0, 0, 810, 811, 3, 112, 56, 0, 811, 812, 5, 149, 0, 0, 812, 936, 1, 0, 0, 0, 813, 814, 5, 20, 0, 0, 814, 936, 5, 110, 0, 0, 815, 816, 5, 45, 0, 0, 816, 817, 3, 116, 58, 0, 817, 818, 3, 152, 76, 0, 818, 936, 1, 0, 0, 0, 819, 820, 5, 82, 0, 0, 820, 821, 5, 130, 0, 0, 821, 822, 3, 116, 58, 0, 822, 823, 5, 34, 0, 0, 823, 826, 3, 116, 58, 0, 824, 825, 5, 33, 0, 0, 825, 827, 3, 116, 58, 0, 826, 824, 1, 0, 0, 0, 826, 827, 1, 0, 0, 0, 827, 828, 1, 0, 0, 0, 828, 829, 5, 149, 0, 0, 829, 936, 1, 0, 0, 0, 830, 831, 5, 86, 0, 0, 831, 936, 5, 110, 0, 0, 832, 833, 5, 91, 0, 0, 833, 834, 5, 130, 0, 0, 834, 835, 7, 9, 0, 0, 835, 836, 3, 166, 83, 0, 836, 837, 5, 34, 0, 0, 837, 838, 3, 116, 58, 0, 838, 839, 5, 149, 0, 0, 839, 936, 1, 0, 0, 0, 840, 841, 3, 160, 80, 0, 841, 843, 5, 130, 0, 0, 842, 844, 3, 114, 57, 0, 843, 842, 1, 0, 0, 0, 843, 844, 1, 0, 0, 0, 844, 845, 1, 0, 0, 0, 845, 846, 5, 149, 0, 0, 846, 855, 1, 0, 0, 0, 847, 849, 5, 130, 0, 0, 848, 850, 5, 24, 0, 0, 849, 848, 1, 0, 0, 0, 849, 850, 1, 0, 0, 0, 850, 852, 1, 0, 0, 0, 851, 853, 3, 118, 59, 0, 852, 851, 1, 0, 0, 0, 852, 853, 1, 0, 0, 0, 853, 854, 1, 0, 0, 0, 854, 856, 5, 149, 0, 0, 855, 847, 1, 0, 0, 0, 855, 856, 1, 0, 0, 0, 856, 857, 1, 0, 0, 0, 857, 858, 5, 66, 0, 0, 858, 859, 5, 130, 0, 0, 859, 860, 3, 98, 49, 0, 860, 861, 5, 149, 0, 0, 861, 936, 1, 0, 0, 0, 862, 863, 3, 160, 80, 0, 863, 865, 5, 130, 0, 0, 864, 866, 3, 114, 57, 0, 865, 864, 1, 0, 0, 0, 865, 866, 1, 0, 0, 0, 866, 867, 1, 0, 0, 0, 867, 868, 5, 149, 0, 0, 868, 877, 1, 0, 0, 0, 869, 871, 5, 130, 0, 0, 870, 872, 5, 24, 0, 0, 871, 870, 1, 0, 0, 0, 871, 872, 1, 0, 0, 0, 872, 874, 1, 0, 0, 0, 873, 875, 3, 118, 59, 0, 874, 873, 1, 0, 0, 0, 874, 875, 1, 0, 0, 0, 875, 876, 1, 0, 0, 0, 876, 878, 5, 149, 0, 0, 877, 869, 1, 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 879, 1, 0, 0, 0, 879, 880, 5, 66, 0, 0, 880, 881, 3, 160, 80, 0, 881, 936, 1, 0, 0, 0, 882, 888, 3, 160, 80, 0, 883, 885, 5, 130, 0, 0, 884, 886, 3, 114, 57, 0, 885, 884, 1, 0, 0, 0, 885, 886, 1, 0, 0, 0, 886, 887, 1, 0, 0, 0, 887, 889, 5, 149, 0, 0, 888, 883, 1, 0, 0, 0, 888, 889, 1, 0, 0, 0, 889, 890, 1, 0, 0, 0, 890, 892, 5, 130, 0, 0, 891, 893, 5, 24, 0, 0, 892, 891, 1, 0, 0, 0, 892, 893, 1, 0, 0, 0, 893, 895, 1, 0, 0, 0, 894, 896, 3, 118, 59, 0, 895, 894, 1, 0, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897, 1, 0, 0, 0, 897, 898, 5, 149, 0, 0, 898, 936, 1, 0, 0, 0, 899, 936, 3, 124, 62, 0, 900, 936, 3, 168, 84, 0, 901, 936, 3, 150, 75, 0, 902, 903, 5, 118, 0, 0, 903, 936, 3, 116, 58, 19, 904, 905, 5, 58, 0, 0, 905, 936, 3, 116, 58, 13, 906, 907, 3, 140, 70, 0, 907, 908, 5, 120, 0, 0, 908, 910, 1, 0, 0, 0, 909, 906, 1, 0, 0, 0, 909, 910, 1, 0, 0, 0, 910, 911, 1, 0, 0, 0, 911, 936, 5, 112, 0, 0, 912, 913, 5, 130, 0, 0, 913, 914, 3, 44, 22, 0, 914, 915, 5, 149, 0, 0, 915, 936, 1, 0, 0, 0, 916, 917, 5, 130, 0, 0, 917, 918, 3, 116, 58, 0, 918, 919, 5, 149, 0, 0, 919, 936, 1, 0, 0, 0, 920, 921, 5, 130, 0, 0, 921, 922, 3, 114, 57, 0, 922, 923, 5, 149, 0, 0, 923, 936, 1, 0, 0, 0, 924, 926, 5, 129, 0, 0, 925, 927, 3, 114, 57, 0, 926, 925, 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, 927, 928, 1, 0, 0, 0, 928, 936, 5, 148, 0, 0, 929, 931, 5, 128, 0, 0, 930, 932, 3, 40, 20, 0, 931, 930, 1, 0, 0, 0, 931, 932, 1, 0, 0, 0, 932, 933, 1, 0, 0, 0, 933, 936, 5, 147, 0, 0, 934, 936, 3, 132, 66, 0, 935, 786, 1, 0, 0, 0, 935, 806, 1, 0, 0, 0, 935, 813, 1, 0, 0, 0, 935, 815, 1, 0, 0, 0, 935, 819, 1, 0, 0, 0, 935, 830, 1, 0, 0, 0, 935, 832, 1, 0, 0, 0, 935, 840, 1, 0, 0, 0, 935, 862, 1, 0, 0, 0, 935, 882, 1, 0, 0, 0, 935, 899, 1, 0, 0, 0, 935, 900, 1, 0, 0, 0, 935, 901, 1, 0, 0, 0, 935, 902, 1, 0, 0, 0, 935, 904, 1, 0, 0, 0, 935, 909, 1, 0, 0, 0, 935, 912, 1, 0, 0, 0, 935, 916, 1, 0, 0, 0, 935, 920, 1, 0, 0, 0, 935, 924, 1, 0, 0, 0, 935, 929, 1, 0, 0, 0, 935, 934, 1, 0, 0, 0, 936, 1041, 1, 0, 0, 0, 937, 941, 10, 18, 0, 0, 938, 942, 5, 112, 0, 0, 939, 942, 5, 151, 0, 0, 940, 942, 5, 138, 0, 0, 941, 938, 1, 0, 0, 0, 941, 939, 1, 0, 0, 0, 941, 940, 1, 0, 0, 0, 942, 943, 1, 0, 0, 0, 943, 1040, 3, 116, 58, 19, 944, 948, 10, 17, 0, 0, 945, 949, 5, 139, 0, 0, 946, 949, 5, 118, 0, 0, 947, 949, 5, 117, 0, 0, 948, 945, 1, 0, 0, 0, 948, 946, 1, 0, 0, 0, 948, 947, 1, 0, 0, 0, 949, 950, 1, 0, 0, 0, 950, 1040, 3, 116, 58, 18, 951, 976, 10, 16, 0, 0, 952, 977, 5, 121, 0, 0, 953, 977, 5, 122, 0, 0, 954, 977, 5, 133, 0, 0, 955, 977, 5, 131, 0, 0, 956, 977, 5, 132, 0, 0, 957, 977, 5, 123, 0, 0, 958, 977, 5, 124, 0, 0, 959, 961, 5, 58, 0, 0, 960, 959, 1, 0, 0, 0, 960, 961, 1, 0, 0, 0, 961, 962, 1, 0, 0, 0, 962, 964, 5, 42, 0, 0, 963, 965, 5, 15, 0, 0, 964, 963, 1, 0, 0, 0, 964, 965, 1, 0, 0, 0, 965, 977, 1, 0, 0, 0, 966, 968, 5, 58, 0, 0, 967, 966, 1, 0, 0, 0, 967, 968, 1, 0, 0, 0, 968, 969, 1, 0, 0, 0, 969, 977, 7, 10, 0, 0, 970, 977, 5, 145, 0, 0, 971, 977, 5, 146, 0, 0, 972, 977, 5, 135, 0, 0, 973, 977, 5, 126, 0, 0, 974, 977, 5, 127, 0, 0, 975, 977, 5, 134, 0, 0, 976, 952, 1, 0, 0, 0, 976, 953, 1, 0, 0, 0, 976, 954, 1, 0, 0, 0, 976, 955, 1, 0, 0, 0, 976, 956, 1, 0, 0, 0, 976, 957, 1, 0, 0, 0, 976, 958, 1, 0, 0, 0, 976, 960, 1, 0, 0, 0, 976, 967, 1, 0, 0, 0, 976, 970, 1, 0, 0, 0, 976, 971, 1, 0, 0, 0, 976, 972, 1, 0, 0, 0, 976, 973, 1, 0, 0, 0, 976, 974, 1, 0, 0, 0, 976, 975, 1, 0, 0, 0, 977, 978, 1, 0, 0, 0, 978, 1040, 3, 116, 58, 17, 979, 980, 10, 14, 0, 0, 980, 981, 5, 137, 0, 0, 981, 1040, 3, 116, 58, 15, 982, 983, 10, 12, 0, 0, 983, 984, 5, 2, 0, 0, 984, 1040, 3, 116, 58, 13, 985, 986, 10, 11, 0, 0, 986, 987, 5, 63, 0, 0, 987, 1040, 3, 116, 58, 12, 988, 990, 10, 10, 0, 0, 989, 991, 5, 58, 0, 0, 990, 989, 1, 0, 0, 0, 990, 991, 1, 0, 0, 0, 991, 992, 1, 0, 0, 0, 992, 993, 5, 9, 0, 0, 993, 994, 3, 116, 58, 0, 994, 995, 5, 2, 0, 0, 995, 996, 3, 116, 58, 11, 996, 1040, 1, 0, 0, 0, 997, 998, 10, 9, 0, 0, 998, 999, 5, 140, 0, 0, 999, 1000, 3, 116, 58, 0, 1000, 1001, 5, 115, 0, 0, 1001, 1002, 3, 116, 58, 9, 1002, 1040, 1, 0, 0, 0, 1003, 1004, 10, 25, 0, 0, 1004, 1005, 5, 129, 0, 0, 1005, 1006, 3, 116, 58, 0, 1006, 1007, 5, 148, 0, 0, 1007, 1040, 1, 0, 0, 0, 1008, 1009, 10, 24, 0, 0, 1009, 1010, 5, 120, 0, 0, 1010, 1040, 5, 108, 0, 0, 1011, 1012, 10, 23, 0, 0, 1012, 1013, 5, 120, 0, 0, 1013, 1040, 3, 160, 80, 0, 1014, 1015, 10, 22, 0, 0, 1015, 1016, 5, 136, 0, 0, 1016, 1017, 5, 129, 0, 0, 1017, 1018, 3, 116, 58, 0, 1018, 1019, 5, 148, 0, 0, 1019, 1040, 1, 0, 0, 0, 1020, 1021, 10, 21, 0, 0, 1021, 1022, 5, 136, 0, 0, 1022, 1040, 5, 108, 0, 0, 1023, 1024, 10, 20, 0, 0, 1024, 1025, 5, 136, 0, 0, 1025, 1040, 3, 160, 80, 0, 1026, 1027, 10, 15, 0, 0, 1027, 1029, 5, 46, 0, 0, 1028, 1030, 5, 58, 0, 0, 1029, 1028, 1, 0, 0, 0, 1029, 1030, 1, 0, 0, 0, 1030, 1031, 1, 0, 0, 0, 1031, 1040, 5, 59, 0, 0, 1032, 1037, 10, 8, 0, 0, 1033, 1034, 5, 6, 0, 0, 1034, 1038, 3, 160, 80, 0, 1035, 1036, 5, 6, 0, 0, 1036, 1038, 5, 110, 0, 0, 1037, 1033, 1, 0, 0, 0, 1037, 1035, 1, 0, 0, 0, 1038, 1040, 1, 0, 0, 0, 1039, 937, 1, 0, 0, 0, 1039, 944, 1, 0, 0, 0, 1039, 951, 1, 0, 0, 0, 1039, 979, 1, 0, 0, 0, 1039, 982, 1, 0, 0, 0, 1039, 985, 1, 0, 0, 0, 1039, 988, 1, 0, 0, 0, 1039, 997, 1, 0, 0, 0, 1039, 1003, 1, 0, 0, 0, 1039, 1008, 1, 0, 0, 0, 1039, 1011, 1, 0, 0, 0, 1039, 1014, 1, 0, 0, 0, 1039, 1020, 1, 0, 0, 0, 1039, 1023, 1, 0, 0, 0, 1039, 1026, 1, 0, 0, 0, 1039, 1032, 1, 0, 0, 0, 1040, 1043, 1, 0, 0, 0, 1041, 1039, 1, 0, 0, 0, 1041, 1042, 1, 0, 0, 0, 1042, 117, 1, 0, 0, 0, 1043, 1041, 1, 0, 0, 0, 1044, 1049, 3, 120, 60, 0, 1045, 1046, 5, 116, 0, 0, 1046, 1048, 3, 120, 60, 0, 1047, 1045, 1, 0, 0, 0, 1048, 1051, 1, 0, 0, 0, 1049, 1047, 1, 0, 0, 0, 1049, 1050, 1, 0, 0, 0, 1050, 1053, 1, 0, 0, 0, 1051, 1049, 1, 0, 0, 0, 1052, 1054, 5, 116, 0, 0, 1053, 1052, 1, 0, 0, 0, 1053, 1054, 1, 0, 0, 0, 1054, 119, 1, 0, 0, 0, 1055, 1058, 3, 122, 61, 0, 1056, 1058, 3, 116, 58, 0, 1057, 1055, 1, 0, 0, 0, 1057, 1056, 1, 0, 0, 0, 1058, 121, 1, 0, 0, 0, 1059, 1060, 5, 130, 0, 0, 1060, 1065, 3, 160, 80, 0, 1061, 1062, 5, 116, 0, 0, 1062, 1064, 3, 160, 80, 0, 1063, 1061, 1, 0, 0, 0, 1064, 1067, 1, 0, 0, 0, 1065, 1063, 1, 0, 0, 0, 1065, 1066, 1, 0, 0, 0, 1066, 1069, 1, 0, 0, 0, 1067, 1065, 1, 0, 0, 0, 1068, 1070, 5, 116, 0, 0, 1069, 1068, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 1071, 1, 0, 0, 0, 1071, 1072, 5, 149, 0, 0, 1072, 1085, 1, 0, 0, 0, 1073, 1078, 3, 160, 80, 0, 1074, 1075, 5, 116, 0, 0, 1075, 1077, 3, 160, 80, 0, 1076, 1074, 1, 0, 0, 0, 1077, 1080, 1, 0, 0, 0, 1078, 1076, 1, 0, 0, 0, 1078, 1079, 1, 0, 0, 0, 1079, 1082, 1, 0, 0, 0, 1080, 1078, 1, 0, 0, 0, 1081, 1083, 5, 116, 0, 0, 1082, 1081, 1, 0, 0, 0, 1082, 1083, 1, 0, 0, 0, 1083, 1085, 1, 0, 0, 0, 1084, 1059, 1, 0, 0, 0, 1084, 1073, 1, 0, 0, 0, 1085, 1086, 1, 0, 0, 0, 1086, 1087, 5, 111, 0, 0, 1087, 1088, 3, 116, 58, 0, 1088, 123, 1, 0, 0, 0, 1089, 1090, 5, 132, 0, 0, 1090, 1094, 3, 160, 80, 0, 1091, 1093, 3, 126, 63, 0, 1092, 1091, 1, 0, 0, 0, 1093, 1096, 1, 0, 0, 0, 1094, 1092, 1, 0, 0, 0, 1094, 1095, 1, 0, 0, 0, 1095, 1097, 1, 0, 0, 0, 1096, 1094, 1, 0, 0, 0, 1097, 1098, 5, 151, 0, 0, 1098, 1099, 5, 124, 0, 0, 1099, 1122, 1, 0, 0, 0, 1100, 1101, 5, 132, 0, 0, 1101, 1105, 3, 160, 80, 0, 1102, 1104, 3, 126, 63, 0, 1103, 1102, 1, 0, 0, 0, 1104, 1107, 1, 0, 0, 0, 1105, 1103, 1, 0, 0, 0, 1105, 1106, 1, 0, 0, 0, 1106, 1108, 1, 0, 0, 0, 1107, 1105, 1, 0, 0, 0, 1108, 1114, 5, 124, 0, 0, 1109, 1115, 3, 124, 62, 0, 1110, 1111, 5, 128, 0, 0, 1111, 1112, 3, 116, 58, 0, 1112, 1113, 5, 147, 0, 0, 1113, 1115, 1, 0, 0, 0, 1114, 1109, 1, 0, 0, 0, 1114, 1110, 1, 0, 0, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1116, 1, 0, 0, 0, 1116, 1117, 5, 132, 0, 0, 1117, 1118, 5, 151, 0, 0, 1118, 1119, 3, 160, 80, 0, 1119, 1120, 5, 124, 0, 0, 1120, 1122, 1, 0, 0, 0, 1121, 1089, 1, 0, 0, 0, 1121, 1100, 1, 0, 0, 0, 1122, 125, 1, 0, 0, 0, 1123, 1124, 3, 160, 80, 0, 1124, 1125, 5, 122, 0, 0, 1125, 1126, 3, 166, 83, 0, 1126, 1135, 1, 0, 0, 0, 1127, 1128, 3, 160, 80, 0, 1128, 1129, 5, 122, 0, 0, 1129, 1130, 5, 128, 0, 0, 1130, 1131, 3, 116, 58, 0, 1131, 1132, 5, 147, 0, 0, 1132, 1135, 1, 0, 0, 0, 1133, 1135, 3, 160, 80, 0, 1134, 1123, 1, 0, 0, 0, 1134, 1127, 1, 0, 0, 0, 1134, 1133, 1, 0, 0, 0, 1135, 127, 1, 0, 0, 0, 1136, 1141, 3, 130, 65, 0, 1137, 1138, 5, 116, 0, 0, 1138, 1140, 3, 130, 65, 0, 1139, 1137, 1, 0, 0, 0, 1140, 1143, 1, 0, 0, 0, 1141, 1139, 1, 0, 0, 0, 1141, 1142, 1, 0, 0, 0, 1142, 1145, 1, 0, 0, 0, 1143, 1141, 1, 0, 0, 0, 1144, 1146, 5, 116, 0, 0, 1145, 1144, 1, 0, 0, 0, 1145, 1146, 1, 0, 0, 0, 1146, 129, 1, 0, 0, 0, 1147, 1148, 3, 160, 80, 0, 1148, 1149, 5, 6, 0, 0, 1149, 1150, 5, 130, 0, 0, 1150, 1151, 3, 44, 22, 0, 1151, 1152, 5, 149, 0, 0, 1152, 1158, 1, 0, 0, 0, 1153, 1154, 3, 116, 58, 0, 1154, 1155, 5, 6, 0, 0, 1155, 1156, 3, 160, 80, 0, 1156, 1158, 1, 0, 0, 0, 1157, 1147, 1, 0, 0, 0, 1157, 1153, 1, 0, 0, 0, 1158, 131, 1, 0, 0, 0, 1159, 1167, 3, 164, 82, 0, 1160, 1161, 3, 140, 70, 0, 1161, 1162, 5, 120, 0, 0, 1162, 1164, 1, 0, 0, 0, 1163, 1160, 1, 0, 0, 0, 1163, 1164, 1, 0, 0, 0, 1164, 1165, 1, 0, 0, 0, 1165, 1167, 3, 134, 67, 0, 1166, 1159, 1, 0, 0, 0, 1166, 1163, 1, 0, 0, 0, 1167, 133, 1, 0, 0, 0, 1168, 1173, 3, 160, 80, 0, 1169, 1170, 5, 120, 0, 0, 1170, 1172, 3, 160, 80, 0, 1171, 1169, 1, 0, 0, 0, 1172, 1175, 1, 0, 0, 0, 1173, 1171, 1, 0, 0, 0, 1173, 1174, 1, 0, 0, 0, 1174, 135, 1, 0, 0, 0, 1175, 1173, 1, 0, 0, 0, 1176, 1177, 6, 68, -1, 0, 1177, 1186, 3, 140, 70, 0, 1178, 1186, 3, 138, 69, 0, 1179, 1180, 5, 130, 0, 0, 1180, 1181, 3, 44, 22, 0, 1181, 1182, 5, 149, 0, 0, 1182, 1186, 1, 0, 0, 0, 1183, 1186, 3, 124, 62, 0, 1184, 1186, 3, 164, 82, 0, 1185, 1176, 1, 0, 0, 0, 1185, 1178, 1, 0, 0, 0, 1185, 1179, 1, 0, 0, 0, 1185, 1183, 1, 0, 0, 0, 1185, 1184, 1, 0, 0, 0, 1186, 1195, 1, 0, 0, 0, 1187, 1191, 10, 3, 0, 0, 1188, 1192, 3, 158, 79, 0, 1189, 1190, 5, 6, 0, 0, 1190, 1192, 3, 160, 80, 0, 1191, 1188, 1, 0, 0, 0, 1191, 1189, 1, 0, 0, 0, 1192, 1194, 1, 0, 0, 0, 1193, 1187, 1, 0, 0, 0, 1194, 1197, 1, 0, 0, 0, 1195, 1193, 1, 0, 0, 0, 1195, 1196, 1, 0, 0, 0, 1196, 137, 1, 0, 0, 0, 1197, 1195, 1, 0, 0, 0, 1198, 1199, 3, 160, 80, 0, 1199, 1201, 5, 130, 0, 0, 1200, 1202, 3, 142, 71, 0, 1201, 1200, 1, 0, 0, 0, 1201, 1202, 1, 0, 0, 0, 1202, 1203, 1, 0, 0, 0, 1203, 1204, 5, 149, 0, 0, 1204, 139, 1, 0, 0, 0, 1205, 1206, 3, 144, 72, 0, 1206, 1207, 5, 120, 0, 0, 1207, 1209, 1, 0, 0, 0, 1208, 1205, 1, 0, 0, 0, 1208, 1209, 1, 0, 0, 0, 1209, 1210, 1, 0, 0, 0, 1210, 1211, 3, 160, 80, 0, 1211, 141, 1, 0, 0, 0, 1212, 1217, 3, 116, 58, 0, 1213, 1214, 5, 116, 0, 0, 1214, 1216, 3, 116, 58, 0, 1215, 1213, 1, 0, 0, 0, 1216, 1219, 1, 0, 0, 0, 1217, 1215, 1, 0, 0, 0, 1217, 1218, 1, 0, 0, 0, 1218, 1221, 1, 0, 0, 0, 1219, 1217, 1, 0, 0, 0, 1220, 1222, 5, 116, 0, 0, 1221, 1220, 1, 0, 0, 0, 1221, 1222, 1, 0, 0, 0, 1222, 143, 1, 0, 0, 0, 1223, 1224, 3, 160, 80, 0, 1224, 145, 1, 0, 0, 0, 1225, 1234, 5, 106, 0, 0, 1226, 1227, 5, 120, 0, 0, 1227, 1234, 7, 11, 0, 0, 1228, 1229, 5, 108, 0, 0, 1229, 1231, 5, 120, 0, 0, 1230, 1232, 7, 11, 0, 0, 1231, 1230, 1, 0, 0, 0, 1231, 1232, 1, 0, 0, 0, 1232, 1234, 1, 0, 0, 0, 1233, 1225, 1, 0, 0, 0, 1233, 1226, 1, 0, 0, 0, 1233, 1228, 1, 0, 0, 0, 1234, 147, 1, 0, 0, 0, 1235, 1237, 7, 12, 0, 0, 1236, 1235, 1, 0, 0, 0, 1236, 1237, 1, 0, 0, 0, 1237, 1244, 1, 0, 0, 0, 1238, 1245, 3, 146, 73, 0, 1239, 1245, 5, 107, 0, 0, 1240, 1245, 5, 108, 0, 0, 1241, 1245, 5, 109, 0, 0, 1242, 1245, 5, 43, 0, 0, 1243, 1245, 5, 57, 0, 0, 1244, 1238, 1, 0, 0, 0, 1244, 1239, 1, 0, 0, 0, 1244, 1240, 1, 0, 0, 0, 1244, 1241, 1, 0, 0, 0, 1244, 1242, 1, 0, 0, 0, 1244, 1243, 1, 0, 0, 0, 1245, 149, 1, 0, 0, 0, 1246, 1250, 3, 148, 74, 0, 1247, 1250, 5, 110, 0, 0, 1248, 1250, 5, 59, 0, 0, 1249, 1246, 1, 0, 0, 0, 1249, 1247, 1, 0, 0, 0, 1249, 1248, 1, 0, 0, 0, 1250, 151, 1, 0, 0, 0, 1251, 1252, 7, 13, 0, 0, 1252, 153, 1, 0, 0, 0, 1253, 1254, 7, 14, 0, 0, 1254, 155, 1, 0, 0, 0, 1255, 1256, 7, 15, 0, 0, 1256, 157, 1, 0, 0, 0, 1257, 1260, 5, 105, 0, 0, 1258, 1260, 3, 156, 78, 0, 1259, 1257, 1, 0, 0, 0, 1259, 1258, 1, 0, 0, 0, 1260, 159, 1, 0, 0, 0, 1261, 1265, 5, 105, 0, 0, 1262, 1265, 3, 152, 76, 0, 1263, 1265, 3, 154, 77, 0, 1264, 1261, 1, 0, 0, 0, 1264, 1262, 1, 0, 0, 0, 1264, 1263, 1, 0, 0, 0, 1265, 161, 1, 0, 0, 0, 1266, 1267, 3, 166, 83, 0, 1267, 1268, 5, 122, 0, 0, 1268, 1269, 3, 148, 74, 0, 1269, 163, 1, 0, 0, 0, 1270, 1271, 5, 128, 0, 0, 1271, 1272, 3, 134, 67, 0, 1272, 1273, 5, 147, 0, 0, 1273, 165, 1, 0, 0, 0, 1274, 1277, 5, 110, 0, 0, 1275, 1277, 3, 168, 84, 0, 1276, 1274, 1, 0, 0, 0, 1276, 1275, 1, 0, 0, 0, 1277, 167, 1, 0, 0, 0, 1278, 1282, 5, 142, 0, 0, 1279, 1281, 3, 170, 85, 0, 1280, 1279, 1, 0, 0, 0, 1281, 1284, 1, 0, 0, 0, 1282, 1280, 1, 0, 0, 0, 1282, 1283, 1, 0, 0, 0, 1283, 1285, 1, 0, 0, 0, 1284, 1282, 1, 0, 0, 0, 1285, 1286, 5, 144, 0, 0, 1286, 169, 1, 0, 0, 0, 1287, 1288, 5, 157, 0, 0, 1288, 1289, 3, 116, 58, 0, 1289, 1290, 5, 147, 0, 0, 1290, 1293, 1, 0, 0, 0, 1291, 1293, 5, 156, 0, 0, 1292, 1287, 1, 0, 0, 0, 1292, 1291, 1, 0, 0, 0, 1293, 171, 1, 0, 0, 0, 1294, 1298, 5, 143, 0, 0, 1295, 1297, 3, 174, 87, 0, 1296, 1295, 1, 0, 0, 0, 1297, 1300, 1, 0, 0, 0, 1298, 1296, 1, 0, 0, 0, 1298, 1299, 1, 0, 0, 0, 1299, 1301, 1, 0, 0, 0, 1300, 1298, 1, 0, 0, 0, 1301, 1302, 5, 0, 0, 1, 1302, 173, 1, 0, 0, 0, 1303, 1304, 5, 159, 0, 0, 1304, 1305, 3, 116, 58, 0, 1305, 1306, 5, 147, 0, 0, 1306, 1309, 1, 0, 0, 0, 1307, 1309, 5, 158, 0, 0, 1308, 1303, 1, 0, 0, 0, 1308, 1307, 1, 0, 0, 0, 1309, 175, 1, 0, 0, 0, 168, 179, 186, 195, 202, 206, 220, 224, 227, 231, 234, 241, 245, 254, 259, 268, 276, 283, 287, 293, 298, 306, 313, 319, 331, 339, 353, 357, 362, 372, 381, 384, 388, 391, 395, 398, 401, 404, 407, 411, 415, 418, 421, 424, 428, 431, 440, 446, 467, 484, 501, 507, 513, 524, 526, 537, 540, 546, 554, 560, 562, 566, 571, 574, 577, 581, 585, 588, 590, 593, 597, 601, 604, 606, 608, 613, 624, 630, 637, 642, 646, 650, 656, 658, 665, 673, 676, 679, 698, 712, 728, 732, 743, 747, 758, 762, 769, 773, 780, 784, 789, 798, 802, 826, 843, 849, 852, 855, 865, 871, 874, 877, 885, 888, 892, 895, 909, 926, 931, 935, 941, 948, 960, 964, 967, 976, 990, 1029, 1037, 1039, 1041, 1049, 1053, 1057, 1065, 1069, 1078, 1082, 1084, 1094, 1105, 1114, 1121, 1134, 1141, 1145, 1157, 1163, 1166, 1173, 1185, 1191, 1195, 1201, 1208, 1217, 1221, 1231, 1233, 1236, 1244, 1249, 1259, 1264, 1276, 1282, 1292, 1298, 1308] \ No newline at end of file diff --git a/hogql_parser/parser.cpp b/hogql_parser/parser.cpp index f82dcd2bf476c..54a1eeedd8e29 100644 --- a/hogql_parser/parser.cpp +++ b/hogql_parser/parser.cpp @@ -2554,8 +2554,11 @@ class HogQLParseTreeConverter : public HogQLParserBaseVisitor { } VISIT(Placeholder) { - string name = visitAsString(ctx->identifier()); - RETURN_NEW_AST_NODE("Placeholder", "{s:s#}", "field", name.data(), name.size()); + auto nested_identifier_ctx = ctx->nestedIdentifier(); + vector nested = + nested_identifier_ctx ? any_cast>(visit(nested_identifier_ctx)) : vector(); + + RETURN_NEW_AST_NODE("Placeholder", "{s:N}", "chain", X_PyList_FromStrings(nested)); } VISIT_UNSUPPORTED(EnumValue) diff --git a/hogql_parser/setup.py b/hogql_parser/setup.py index 3c7bc51026aa6..cbbb680b12102 100644 --- a/hogql_parser/setup.py +++ b/hogql_parser/setup.py @@ -32,7 +32,7 @@ setup( name="hogql_parser", - version="1.0.32", + version="1.0.35", url="https://github.com/PostHog/posthog/tree/master/hogql_parser", author="PostHog Inc.", author_email="hey@posthog.com", diff --git a/package.json b/package.json index 2ec48a1059f71..f94e610e1c095 100644 --- a/package.json +++ b/package.json @@ -139,6 +139,7 @@ "kea-test-utils": "^0.2.4", "kea-waitfor": "^0.2.1", "kea-window-values": "^3.0.0", + "lodash.merge": "^4.6.2", "maplibre-gl": "^3.5.1", "md5": "^2.3.0", "monaco-editor": "^0.49.0", @@ -147,7 +148,7 @@ "pmtiles": "^2.11.0", "postcss": "^8.4.31", "postcss-preset-env": "^9.3.0", - "posthog-js": "1.151.0", + "posthog-js": "1.153.0", "posthog-js-lite": "3.0.0", "prettier": "^2.8.8", "prop-types": "^15.7.2", @@ -223,6 +224,7 @@ "@types/image-blob-reduce": "^4.1.1", "@types/jest": "^29.5.12", "@types/jest-image-snapshot": "^6.1.0", + "@types/lodash.merge": "^4.6.9", "@types/md5": "^2.3.0", "@types/node": "^18.11.9", "@types/papaparse": "^5.3.8", diff --git a/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts b/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts index feed88b570d5f..741f6a13978f4 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts @@ -119,6 +119,11 @@ export const sessionInfoSummary = new Summary({ percentiles: [0.1, 0.25, 0.5, 0.9, 0.99], }) +const gaugeBatchUtilization = new Gauge({ + name: 'recording_blob_ingestion_batch_utilization', + help: 'Indicates how big batches are we are processing compared to the max batch size. Useful as a scaling metric', +}) + type PartitionMetrics = { lastMessageTimestamp?: number lastMessageOffset?: number @@ -343,6 +348,8 @@ export class SessionRecordingIngester { }) } + gaugeBatchUtilization.set(messages.length / this.config.SESSION_RECORDING_KAFKA_BATCH_SIZE) + await runInstrumentedFunction({ statsKey: `recordingingester.handleEachBatch`, sendTimeoutGuardToSentry: false, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5432acec6a69c..7b0ca91c4d22b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -238,6 +238,9 @@ dependencies: kea-window-values: specifier: ^3.0.0 version: 3.0.0(kea@3.1.5) + lodash.merge: + specifier: ^4.6.2 + version: 4.6.2 maplibre-gl: specifier: ^3.5.1 version: 3.5.1 @@ -263,8 +266,8 @@ dependencies: specifier: ^9.3.0 version: 9.3.0(postcss@8.4.31) posthog-js: - specifier: 1.151.0 - version: 1.151.0 + specifier: 1.153.0 + version: 1.153.0 posthog-js-lite: specifier: 3.0.0 version: 3.0.0 @@ -488,6 +491,9 @@ devDependencies: '@types/jest-image-snapshot': specifier: ^6.1.0 version: 6.1.0 + '@types/lodash.merge': + specifier: ^4.6.9 + version: 4.6.9 '@types/node': specifier: ^18.11.9 version: 18.11.9 @@ -8355,6 +8361,12 @@ packages: resolution: {integrity: sha512-PecSzorDGdabF57OBeQO/xFbAkYWo88g4Xvnsx7LRwqLC17I7OoKtA3bQB9uXkY6UkMWCOsA8HSVpaoitscdXw==} dev: false + /@types/lodash.merge@4.6.9: + resolution: {integrity: sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==} + dependencies: + '@types/lodash': 4.14.188 + dev: true + /@types/lodash@4.14.188: resolution: {integrity: sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w==} dev: true @@ -15659,7 +15671,6 @@ packages: /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true /lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} @@ -17728,8 +17739,8 @@ packages: resolution: {integrity: sha512-dyajjnfzZD1tht4N7p7iwf7nBnR1MjVaVu+MKr+7gBgA39bn28wizCIJZztZPtHy4PY0YwtSGgwfBCuG/hnHgA==} dev: false - /posthog-js@1.151.0: - resolution: {integrity: sha512-KcafRksGNYNar230VpGWicUc4FhezSDVd7zw8uX0ohtUgPiq6OSek48YUC4uF+0i1s/zbpFeD3zky1o0zqFacw==} + /posthog-js@1.153.0: + resolution: {integrity: sha512-eAXPXiBeN84P9QgnthjgrqECZUGHbQl9B/v6RJ3E1EQvj66vpSgrjfsb3SBcvOoH70kAryAbC0BLyoPs9fi+2w==} dependencies: fflate: 0.4.8 preact: 10.23.1 diff --git a/posthog/api/plugin.py b/posthog/api/plugin.py index 04578f5e64eba..a98b9260f66fe 100644 --- a/posthog/api/plugin.py +++ b/posthog/api/plugin.py @@ -30,6 +30,7 @@ Detail, Trigger, dict_changes_between, + load_activity, load_all_activity, log_activity, ) @@ -893,6 +894,17 @@ def frontend(self, request: request.Request, **kwargs): content = f"export function getFrontendApp () {'{'} return {json.dumps(obj)} {'}'}" return HttpResponse(content, content_type="application/javascript; charset=UTF-8") + @action(methods=["GET"], url_path="activity", detail=True) + def activity(self, request: request.Request, **kwargs): + limit = int(request.query_params.get("limit", "10")) + page = int(request.query_params.get("page", "1")) + + activity_page = load_activity( + "PluginConfig", team_id=self.team_id, item_ids=[self.get_object().id], limit=limit, page=page + ) + + return activity_page_response(activity_page, limit, page, request) + def _get_secret_fields_for_plugin(plugin: Plugin) -> set[str]: # A set of keys for config fields that have secret = true diff --git a/posthog/api/test/__snapshots__/test_cohort.ambr b/posthog/api/test/__snapshots__/test_cohort.ambr index 2297680c16077..319f16cbd550b 100644 --- a/posthog/api/test/__snapshots__/test_cohort.ambr +++ b/posthog/api/test/__snapshots__/test_cohort.ambr @@ -51,7 +51,8 @@ HAVING max(is_deleted) = 0 SETTINGS optimize_aggregation_in_order = 1)) person ON person.person_id = behavior_query.person_id WHERE 1 = 1 AND ((((has(['something'], replaceRegexpAll(JSONExtractRaw(person_props, '$some_prop'), '^"|"$', '')))) - OR ((performed_event_condition_X_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order=1 ) as person + OR ((performed_event_condition_X_level_level_0_level_1_level_0_0)))) SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ) as person UNION ALL SELECT person_id, cohort_id, @@ -62,7 +63,8 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 1 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohort.test_async_deletion_of_cohort.10 @@ -144,7 +146,8 @@ WHERE team_id = 2 AND cohort_id = 2 AND version < 2 - AND sign = 1 SETTINGS optimize_aggregation_in_order = 1 + AND sign = 1 SETTINGS optimize_aggregation_in_order = 1, + join_algorithm = 'auto' ''' # --- # name: TestCohort.test_async_deletion_of_cohort.6 diff --git a/posthog/cdp/templates/__init__.py b/posthog/cdp/templates/__init__.py index 0e39e71109190..8e556b89bbfd4 100644 --- a/posthog/cdp/templates/__init__.py +++ b/posthog/cdp/templates/__init__.py @@ -8,6 +8,10 @@ from .posthog.template_posthog import template as posthog from .aws_kinesis.template_aws_kinesis import template as aws_kinesis from .salesforce.template_salesforce import template_create as salesforce_create, template_update as salesforce_update +from .mailjet.template_mailjet import ( + template_create_contact as mailjet_create_contact, + template_update_contact_list as mailjet_update_contact_list, +) HOG_FUNCTION_TEMPLATES = [ @@ -22,8 +26,11 @@ clearbit, salesforce_create, salesforce_update, + mailjet_create_contact, + mailjet_update_contact_list, ] + HOG_FUNCTION_TEMPLATES_BY_ID = {template.id: template for template in HOG_FUNCTION_TEMPLATES} __all__ = ["HOG_FUNCTION_TEMPLATES", "HOG_FUNCTION_TEMPLATES_BY_ID"] diff --git a/posthog/cdp/templates/customerio/template_customerio.py b/posthog/cdp/templates/customerio/template_customerio.py index e82b234b313af..420ee678cca26 100644 --- a/posthog/cdp/templates/customerio/template_customerio.py +++ b/posthog/cdp/templates/customerio/template_customerio.py @@ -3,7 +3,7 @@ # Based off of https://customer.io/docs/api/track/#operation/entity template: HogFunctionTemplate = HogFunctionTemplate( - status="beta", + status="alpha", id="template-customerio", name="Update persons in Customer.io", description="Updates persons in Customer.io", diff --git a/posthog/cdp/templates/mailjet/template_mailjet.py b/posthog/cdp/templates/mailjet/template_mailjet.py new file mode 100644 index 0000000000000..f8be459bf69ab --- /dev/null +++ b/posthog/cdp/templates/mailjet/template_mailjet.py @@ -0,0 +1,146 @@ +from posthog.cdp.templates.hog_function_template import HogFunctionTemplate + + +# See https://dev.mailjet.com/email/reference/contacts/contact-list/ + +common_inputs_schemas = [ + { + "key": "api_key", + "type": "string", + "label": "Mailjet API Key", + "secret": True, + "required": True, + }, + { + "key": "email", + "type": "string", + "label": "Email of the user", + "description": "Where to find the email for the user to be checked with Mailjet", + "default": "{person.properties.email}", + "secret": False, + "required": True, + }, +] + +common_filters = { + "events": [{"id": "$identify", "name": "$identify", "type": "events", "order": 0}], + "actions": [], + "filter_test_accounts": True, +} + + +template_create_contact: HogFunctionTemplate = HogFunctionTemplate( + status="beta", + id="template-mailjet-create-contact", + name="Add contacts to Mailjet", + description="Updates a contact in Mailjet", + icon_url="/static/services/mailjet.png", + hog=""" +if (empty(inputs.email)) { + return false +} + +fetch(f'https://api.mailjet.com/v3/REST/contact/', { + 'method': 'POST', + 'headers': { + 'Authorization': f'Bearer {inputs.api_key}', + 'Content-Type': 'application/json' + }, + 'body': { + 'Email': inputs.email, + 'Name': inputs.name, + 'IsExcludedFromCampaigns': inputs.is_excluded_from_campaigns + } +}) +""".strip(), + inputs_schema=[ + *common_inputs_schemas, + { + "key": "name", + "type": "string", + "label": "Name", + "description": "Name of the contact", + "default": "{person.properties.first_name} {person.properties.last_name}", + "secret": False, + "required": False, + }, + { + "key": "is_excluded_from_campaigns", + "type": "boolean", + "label": "Is excluded from campaigns", + "description": "Whether the contact should be excluded from campaigns", + "default": False, + "secret": False, + "required": False, + }, + ], + filters=common_filters, +) + + +template_update_contact_list: HogFunctionTemplate = HogFunctionTemplate( + status="beta", + id="template-mailjet-update-contact-list", + name="Update a Mailjet contact list", + description="Updates a contact in Mailjet", + icon_url="/static/services/mailjet.png", + hog=""" +if (empty(inputs.email)) { + return false +} + +fetch(f'https://api.mailjet.com/v3/REST/contact/{inputs.email}/managecontactlists', { + 'method': 'POST', + 'headers': { + 'Authorization': f'Bearer {inputs.api_key}', + 'Content-Type': 'application/json' + }, + 'body': { + 'ContactsLists':[ + { + 'Action': inputs.action, + 'ListID': inputs.contact_list_id + }, + ] + } +}) +""".strip(), + inputs_schema=[ + *common_inputs_schemas, + { + "key": "contact_list_id", + "type": "string", + "label": "Contact list ID", + "description": "ID of the contact list", + "secret": False, + "required": True, + }, + { + "key": "action", + "type": "choice", + "label": "Action", + "secret": False, + "default": "addnoforce", + "required": True, + "choices": [ + { + "label": "Add", + "value": "addnoforce", + }, + { + "label": "Add (force)", + "value": "addforce", + }, + { + "label": "Remove", + "value": "remove", + }, + { + "label": "Unsubscribe", + "value": "unsub", + }, + ], + }, + ], + filters=common_filters, +) diff --git a/posthog/cdp/templates/mailjet/test_template_mailjet.py b/posthog/cdp/templates/mailjet/test_template_mailjet.py new file mode 100644 index 0000000000000..0163975411651 --- /dev/null +++ b/posthog/cdp/templates/mailjet/test_template_mailjet.py @@ -0,0 +1,55 @@ +from inline_snapshot import snapshot +from posthog.cdp.templates.helpers import BaseHogFunctionTemplateTest +from posthog.cdp.templates.mailjet.template_mailjet import template_create_contact, template_update_contact_list + + +def create_inputs(**kwargs): + inputs = {"api_key": "API_KEY", "email": "example@posthog.com"} + inputs.update(kwargs) + return inputs + + +class TestTemplateMailjetCreateContact(BaseHogFunctionTemplateTest): + template = template_create_contact + + def test_function_works(self): + self.run_function(inputs=create_inputs(name="Example", is_excluded_from_campaigns=False)) + + assert self.get_mock_fetch_calls()[0] == snapshot( + ( + "https://api.mailjet.com/v3/REST/contact/", + { + "method": "POST", + "headers": {"Authorization": "Bearer API_KEY", "Content-Type": "application/json"}, + "body": {"Email": "example@posthog.com", "Name": "Example", "IsExcludedFromCampaigns": False}, + }, + ) + ) + + def test_function_ignores_no_email(self): + self.run_function(inputs=create_inputs(email="")) + + assert self.get_mock_fetch_calls() == [] + + +class TestTemplateMailjetUpdateContactList(BaseHogFunctionTemplateTest): + template = template_update_contact_list + + def test_function_works(self): + self.run_function(inputs=create_inputs(contact_list_id=123, action="addnoforce")) + + assert self.get_mock_fetch_calls()[0] == snapshot( + ( + "https://api.mailjet.com/v3/REST/contact/example@posthog.com/managecontactlists", + { + "method": "POST", + "headers": {"Authorization": "Bearer API_KEY", "Content-Type": "application/json"}, + "body": {"ContactsLists": [{"Action": "addnoforce", "ListID": 123}]}, + }, + ) + ) + + def test_function_ignores_no_email(self): + self.run_function(inputs=create_inputs(email="")) + + assert self.get_mock_fetch_calls() == [] diff --git a/posthog/hogql/ast.py b/posthog/hogql/ast.py index 21686dd7b1b47..575085ca1ed45 100644 --- a/posthog/hogql/ast.py +++ b/posthog/hogql/ast.py @@ -698,7 +698,11 @@ class Field(Expr): @dataclass(kw_only=True) class Placeholder(Expr): - field: str + chain: list[str | int] + + @property + def field(self): + return ".".join(str(chain) for chain in self.chain) @dataclass(kw_only=True) diff --git a/posthog/hogql/filters.py b/posthog/hogql/filters.py index becb80eda9239..9011dc1de4b6f 100644 --- a/posthog/hogql/filters.py +++ b/posthog/hogql/filters.py @@ -1,5 +1,6 @@ from typing import Optional, TypeVar +import dataclasses from dateutil.parser import isoparse from posthog.hogql import ast @@ -14,6 +15,12 @@ T = TypeVar("T", bound=ast.Expr) +@dataclasses.dataclass +class CompareOperationWrapper: + compare_operation: ast.CompareOperation + skip: bool = False + + def replace_filters(node: T, filters: Optional[HogQLFilters], team: Team) -> T: return ReplaceFilters(filters, team).visit(node) @@ -24,6 +31,7 @@ def __init__(self, filters: Optional[HogQLFilters], team: Team = None): self.filters = filters self.team = team self.selects: list[ast.SelectQuery] = [] + self.compare_operations: list[CompareOperationWrapper] = [] def visit_select_query(self, node): self.selects.append(node) @@ -31,8 +39,20 @@ def visit_select_query(self, node): self.selects.pop() return node + def visit_compare_operation(self, node): + self.compare_operations.append(CompareOperationWrapper(compare_operation=node, skip=False)) + node = super().visit_compare_operation(node) + compare_wrapper = self.compare_operations.pop() + if compare_wrapper.skip: + return ast.CompareOperation( + left=ast.Constant(value=True), + op=ast.CompareOperationOp.Eq, + right=ast.Constant(value=True), + ) + return node + def visit_placeholder(self, node): - if node.field == "filters": + if node.chain == ["filters"]: if self.filters is None: return ast.Constant(value=True) @@ -111,4 +131,40 @@ def visit_placeholder(self, node): if len(exprs) == 1: return exprs[0] return ast.And(exprs=exprs) + if node.chain == ["filters", "dateRange", "from"]: + compare_op_wrapper = self.compare_operations[-1] + + if self.filters is None: + compare_op_wrapper.skip = True + return ast.Constant(value=True) + + dateFrom = self.filters.dateRange.date_from if self.filters.dateRange else None + if dateFrom is not None and dateFrom != "all": + try: + parsed_date = isoparse(dateFrom).replace(tzinfo=self.team.timezone_info) + except ValueError: + parsed_date = relative_date_parse(dateFrom, self.team.timezone_info) + + return ast.Constant(value=parsed_date) + else: + compare_op_wrapper.skip = True + return ast.Constant(value=True) + if node.chain == ["filters", "dateRange", "to"]: + compare_op_wrapper = self.compare_operations[-1] + + if self.filters is None: + compare_op_wrapper.skip = True + return ast.Constant(value=True) + + dateTo = self.filters.dateRange.date_to if self.filters.dateRange else None + if dateTo is not None: + try: + parsed_date = isoparse(dateTo).replace(tzinfo=self.team.timezone_info) + except ValueError: + parsed_date = relative_date_parse(dateTo, self.team.timezone_info) + return ast.Constant(value=parsed_date) + else: + compare_op_wrapper.skip = True + return ast.Constant(value=True) + return super().visit_placeholder(node) diff --git a/posthog/hogql/grammar/HogQLParser.g4 b/posthog/hogql/grammar/HogQLParser.g4 index 871f549f41f02..4a6e187643877 100644 --- a/posthog/hogql/grammar/HogQLParser.g4 +++ b/posthog/hogql/grammar/HogQLParser.g4 @@ -293,7 +293,7 @@ keywordForAlias alias: IDENTIFIER | keywordForAlias; // |interval| can't be an alias, otherwise 'INTERVAL 1 SOMETHING' becomes ambiguous. identifier: IDENTIFIER | interval | keyword; enumValue: string EQ_SINGLE numberLiteral; -placeholder: LBRACE identifier RBRACE; +placeholder: LBRACE nestedIdentifier RBRACE; string: STRING_LITERAL | templateString; templateString : QUOTE_SINGLE_TEMPLATE stringContents* QUOTE_SINGLE ; diff --git a/posthog/hogql/grammar/HogQLParser.interp b/posthog/hogql/grammar/HogQLParser.interp index e31bf92fee7e9..183059ec0fd79 100644 --- a/posthog/hogql/grammar/HogQLParser.interp +++ b/posthog/hogql/grammar/HogQLParser.interp @@ -414,4 +414,4 @@ stringContentsFull atn: -[4, 1, 159, 1311, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 1, 0, 5, 0, 178, 8, 0, 10, 0, 12, 0, 181, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 3, 1, 187, 8, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 196, 8, 3, 1, 4, 1, 4, 1, 4, 5, 4, 201, 8, 4, 10, 4, 12, 4, 204, 9, 4, 1, 4, 3, 4, 207, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 221, 8, 5, 1, 6, 1, 6, 3, 6, 225, 8, 6, 1, 6, 3, 6, 228, 8, 6, 1, 7, 1, 7, 3, 7, 232, 8, 7, 1, 7, 3, 7, 235, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 242, 8, 8, 1, 8, 1, 8, 3, 8, 246, 8, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 5, 9, 253, 8, 9, 10, 9, 12, 9, 256, 9, 9, 1, 9, 1, 9, 3, 9, 260, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 269, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 277, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 284, 8, 12, 1, 12, 1, 12, 3, 12, 288, 8, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 294, 8, 12, 1, 12, 1, 12, 1, 12, 3, 12, 299, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 307, 8, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 314, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 320, 8, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 3, 16, 332, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 5, 18, 338, 8, 18, 10, 18, 12, 18, 341, 9, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 5, 20, 352, 8, 20, 10, 20, 12, 20, 355, 9, 20, 1, 20, 3, 20, 358, 8, 20, 1, 21, 1, 21, 1, 21, 3, 21, 363, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 371, 8, 22, 10, 22, 12, 22, 374, 9, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 382, 8, 23, 1, 24, 3, 24, 385, 8, 24, 1, 24, 1, 24, 3, 24, 389, 8, 24, 1, 24, 3, 24, 392, 8, 24, 1, 24, 1, 24, 3, 24, 396, 8, 24, 1, 24, 3, 24, 399, 8, 24, 1, 24, 3, 24, 402, 8, 24, 1, 24, 3, 24, 405, 8, 24, 1, 24, 3, 24, 408, 8, 24, 1, 24, 1, 24, 3, 24, 412, 8, 24, 1, 24, 1, 24, 3, 24, 416, 8, 24, 1, 24, 3, 24, 419, 8, 24, 1, 24, 3, 24, 422, 8, 24, 1, 24, 3, 24, 425, 8, 24, 1, 24, 1, 24, 3, 24, 429, 8, 24, 1, 24, 3, 24, 432, 8, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 441, 8, 26, 1, 27, 1, 27, 1, 27, 1, 28, 3, 28, 447, 8, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 466, 8, 29, 10, 29, 12, 29, 469, 9, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 3, 32, 485, 8, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 502, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 508, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 514, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 525, 8, 36, 3, 36, 527, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 3, 39, 538, 8, 39, 1, 39, 3, 39, 541, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 547, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 555, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 5, 39, 561, 8, 39, 10, 39, 12, 39, 564, 9, 39, 1, 40, 3, 40, 567, 8, 40, 1, 40, 1, 40, 1, 40, 3, 40, 572, 8, 40, 1, 40, 3, 40, 575, 8, 40, 1, 40, 3, 40, 578, 8, 40, 1, 40, 1, 40, 3, 40, 582, 8, 40, 1, 40, 1, 40, 3, 40, 586, 8, 40, 1, 40, 3, 40, 589, 8, 40, 3, 40, 591, 8, 40, 1, 40, 3, 40, 594, 8, 40, 1, 40, 1, 40, 3, 40, 598, 8, 40, 1, 40, 1, 40, 3, 40, 602, 8, 40, 1, 40, 3, 40, 605, 8, 40, 3, 40, 607, 8, 40, 3, 40, 609, 8, 40, 1, 41, 1, 41, 1, 41, 3, 41, 614, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 625, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 631, 8, 43, 1, 44, 1, 44, 1, 44, 5, 44, 636, 8, 44, 10, 44, 12, 44, 639, 9, 44, 1, 45, 1, 45, 3, 45, 643, 8, 45, 1, 45, 1, 45, 3, 45, 647, 8, 45, 1, 45, 1, 45, 3, 45, 651, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 657, 8, 46, 3, 46, 659, 8, 46, 1, 47, 1, 47, 1, 47, 5, 47, 664, 8, 47, 10, 47, 12, 47, 667, 9, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 3, 49, 674, 8, 49, 1, 49, 3, 49, 677, 8, 49, 1, 49, 3, 49, 680, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 699, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 713, 8, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 727, 8, 56, 10, 56, 12, 56, 730, 9, 56, 1, 56, 3, 56, 733, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 742, 8, 56, 10, 56, 12, 56, 745, 9, 56, 1, 56, 3, 56, 748, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 757, 8, 56, 10, 56, 12, 56, 760, 9, 56, 1, 56, 3, 56, 763, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 770, 8, 56, 1, 56, 1, 56, 3, 56, 774, 8, 56, 1, 57, 1, 57, 1, 57, 5, 57, 779, 8, 57, 10, 57, 12, 57, 782, 9, 57, 1, 57, 3, 57, 785, 8, 57, 1, 58, 1, 58, 1, 58, 3, 58, 790, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 4, 58, 797, 8, 58, 11, 58, 12, 58, 798, 1, 58, 1, 58, 3, 58, 803, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 827, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 844, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 850, 8, 58, 1, 58, 3, 58, 853, 8, 58, 1, 58, 3, 58, 856, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 866, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 872, 8, 58, 1, 58, 3, 58, 875, 8, 58, 1, 58, 3, 58, 878, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 886, 8, 58, 1, 58, 3, 58, 889, 8, 58, 1, 58, 1, 58, 3, 58, 893, 8, 58, 1, 58, 3, 58, 896, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 910, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 927, 8, 58, 1, 58, 1, 58, 1, 58, 3, 58, 932, 8, 58, 1, 58, 1, 58, 3, 58, 936, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 942, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 949, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 961, 8, 58, 1, 58, 1, 58, 3, 58, 965, 8, 58, 1, 58, 3, 58, 968, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 977, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 991, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 1030, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 1038, 8, 58, 5, 58, 1040, 8, 58, 10, 58, 12, 58, 1043, 9, 58, 1, 59, 1, 59, 1, 59, 5, 59, 1048, 8, 59, 10, 59, 12, 59, 1051, 9, 59, 1, 59, 3, 59, 1054, 8, 59, 1, 60, 1, 60, 3, 60, 1058, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 1064, 8, 61, 10, 61, 12, 61, 1067, 9, 61, 1, 61, 3, 61, 1070, 8, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 1077, 8, 61, 10, 61, 12, 61, 1080, 9, 61, 1, 61, 3, 61, 1083, 8, 61, 3, 61, 1085, 8, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 5, 62, 1093, 8, 62, 10, 62, 12, 62, 1096, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 5, 62, 1104, 8, 62, 10, 62, 12, 62, 1107, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 1115, 8, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 1122, 8, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 1135, 8, 63, 1, 64, 1, 64, 1, 64, 5, 64, 1140, 8, 64, 10, 64, 12, 64, 1143, 9, 64, 1, 64, 3, 64, 1146, 8, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 1158, 8, 65, 1, 66, 1, 66, 1, 66, 1, 66, 3, 66, 1164, 8, 66, 1, 66, 3, 66, 1167, 8, 66, 1, 67, 1, 67, 1, 67, 5, 67, 1172, 8, 67, 10, 67, 12, 67, 1175, 9, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1186, 8, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1192, 8, 68, 5, 68, 1194, 8, 68, 10, 68, 12, 68, 1197, 9, 68, 1, 69, 1, 69, 1, 69, 3, 69, 1202, 8, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 3, 70, 1209, 8, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 5, 71, 1216, 8, 71, 10, 71, 12, 71, 1219, 9, 71, 1, 71, 3, 71, 1222, 8, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 1232, 8, 73, 3, 73, 1234, 8, 73, 1, 74, 3, 74, 1237, 8, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 1245, 8, 74, 1, 75, 1, 75, 1, 75, 3, 75, 1250, 8, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 3, 79, 1260, 8, 79, 1, 80, 1, 80, 1, 80, 3, 80, 1265, 8, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 3, 83, 1277, 8, 83, 1, 84, 1, 84, 5, 84, 1281, 8, 84, 10, 84, 12, 84, 1284, 9, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 3, 85, 1293, 8, 85, 1, 86, 1, 86, 5, 86, 1297, 8, 86, 10, 86, 12, 86, 1300, 9, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 3, 87, 1309, 8, 87, 1, 87, 0, 3, 78, 116, 136, 88, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 0, 16, 2, 0, 18, 18, 74, 74, 2, 0, 44, 44, 51, 51, 3, 0, 1, 1, 4, 4, 8, 8, 4, 0, 1, 1, 3, 4, 8, 8, 80, 80, 2, 0, 51, 51, 73, 73, 2, 0, 1, 1, 4, 4, 2, 0, 7, 7, 22, 23, 2, 0, 30, 30, 49, 49, 2, 0, 71, 71, 76, 76, 3, 0, 10, 10, 50, 50, 90, 90, 2, 0, 41, 41, 53, 53, 1, 0, 107, 108, 2, 0, 118, 118, 139, 139, 7, 0, 21, 21, 38, 38, 55, 56, 70, 70, 78, 78, 97, 97, 103, 103, 16, 0, 1, 13, 15, 20, 22, 28, 30, 30, 32, 37, 39, 42, 44, 51, 53, 54, 58, 58, 60, 69, 71, 77, 79, 83, 85, 92, 94, 96, 98, 99, 101, 102, 4, 0, 20, 20, 30, 30, 39, 39, 48, 48, 1479, 0, 179, 1, 0, 0, 0, 2, 186, 1, 0, 0, 0, 4, 188, 1, 0, 0, 0, 6, 190, 1, 0, 0, 0, 8, 197, 1, 0, 0, 0, 10, 220, 1, 0, 0, 0, 12, 222, 1, 0, 0, 0, 14, 229, 1, 0, 0, 0, 16, 236, 1, 0, 0, 0, 18, 249, 1, 0, 0, 0, 20, 261, 1, 0, 0, 0, 22, 270, 1, 0, 0, 0, 24, 278, 1, 0, 0, 0, 26, 300, 1, 0, 0, 0, 28, 315, 1, 0, 0, 0, 30, 324, 1, 0, 0, 0, 32, 329, 1, 0, 0, 0, 34, 333, 1, 0, 0, 0, 36, 335, 1, 0, 0, 0, 38, 344, 1, 0, 0, 0, 40, 348, 1, 0, 0, 0, 42, 362, 1, 0, 0, 0, 44, 366, 1, 0, 0, 0, 46, 381, 1, 0, 0, 0, 48, 384, 1, 0, 0, 0, 50, 433, 1, 0, 0, 0, 52, 436, 1, 0, 0, 0, 54, 442, 1, 0, 0, 0, 56, 446, 1, 0, 0, 0, 58, 452, 1, 0, 0, 0, 60, 470, 1, 0, 0, 0, 62, 473, 1, 0, 0, 0, 64, 476, 1, 0, 0, 0, 66, 486, 1, 0, 0, 0, 68, 489, 1, 0, 0, 0, 70, 493, 1, 0, 0, 0, 72, 526, 1, 0, 0, 0, 74, 528, 1, 0, 0, 0, 76, 531, 1, 0, 0, 0, 78, 546, 1, 0, 0, 0, 80, 608, 1, 0, 0, 0, 82, 613, 1, 0, 0, 0, 84, 624, 1, 0, 0, 0, 86, 626, 1, 0, 0, 0, 88, 632, 1, 0, 0, 0, 90, 640, 1, 0, 0, 0, 92, 658, 1, 0, 0, 0, 94, 660, 1, 0, 0, 0, 96, 668, 1, 0, 0, 0, 98, 673, 1, 0, 0, 0, 100, 681, 1, 0, 0, 0, 102, 685, 1, 0, 0, 0, 104, 689, 1, 0, 0, 0, 106, 698, 1, 0, 0, 0, 108, 712, 1, 0, 0, 0, 110, 714, 1, 0, 0, 0, 112, 773, 1, 0, 0, 0, 114, 775, 1, 0, 0, 0, 116, 935, 1, 0, 0, 0, 118, 1044, 1, 0, 0, 0, 120, 1057, 1, 0, 0, 0, 122, 1084, 1, 0, 0, 0, 124, 1121, 1, 0, 0, 0, 126, 1134, 1, 0, 0, 0, 128, 1136, 1, 0, 0, 0, 130, 1157, 1, 0, 0, 0, 132, 1166, 1, 0, 0, 0, 134, 1168, 1, 0, 0, 0, 136, 1185, 1, 0, 0, 0, 138, 1198, 1, 0, 0, 0, 140, 1208, 1, 0, 0, 0, 142, 1212, 1, 0, 0, 0, 144, 1223, 1, 0, 0, 0, 146, 1233, 1, 0, 0, 0, 148, 1236, 1, 0, 0, 0, 150, 1249, 1, 0, 0, 0, 152, 1251, 1, 0, 0, 0, 154, 1253, 1, 0, 0, 0, 156, 1255, 1, 0, 0, 0, 158, 1259, 1, 0, 0, 0, 160, 1264, 1, 0, 0, 0, 162, 1266, 1, 0, 0, 0, 164, 1270, 1, 0, 0, 0, 166, 1276, 1, 0, 0, 0, 168, 1278, 1, 0, 0, 0, 170, 1292, 1, 0, 0, 0, 172, 1294, 1, 0, 0, 0, 174, 1308, 1, 0, 0, 0, 176, 178, 3, 2, 1, 0, 177, 176, 1, 0, 0, 0, 178, 181, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 182, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 182, 183, 5, 0, 0, 1, 183, 1, 1, 0, 0, 0, 184, 187, 3, 6, 3, 0, 185, 187, 3, 10, 5, 0, 186, 184, 1, 0, 0, 0, 186, 185, 1, 0, 0, 0, 187, 3, 1, 0, 0, 0, 188, 189, 3, 116, 58, 0, 189, 5, 1, 0, 0, 0, 190, 191, 5, 52, 0, 0, 191, 195, 3, 160, 80, 0, 192, 193, 5, 115, 0, 0, 193, 194, 5, 122, 0, 0, 194, 196, 3, 4, 2, 0, 195, 192, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 7, 1, 0, 0, 0, 197, 202, 3, 160, 80, 0, 198, 199, 5, 116, 0, 0, 199, 201, 3, 160, 80, 0, 200, 198, 1, 0, 0, 0, 201, 204, 1, 0, 0, 0, 202, 200, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 203, 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 205, 207, 5, 116, 0, 0, 206, 205, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 9, 1, 0, 0, 0, 208, 221, 3, 12, 6, 0, 209, 221, 3, 14, 7, 0, 210, 221, 3, 18, 9, 0, 211, 221, 3, 20, 10, 0, 212, 221, 3, 22, 11, 0, 213, 221, 3, 26, 13, 0, 214, 221, 3, 24, 12, 0, 215, 221, 3, 28, 14, 0, 216, 221, 3, 30, 15, 0, 217, 221, 3, 36, 18, 0, 218, 221, 3, 32, 16, 0, 219, 221, 3, 34, 17, 0, 220, 208, 1, 0, 0, 0, 220, 209, 1, 0, 0, 0, 220, 210, 1, 0, 0, 0, 220, 211, 1, 0, 0, 0, 220, 212, 1, 0, 0, 0, 220, 213, 1, 0, 0, 0, 220, 214, 1, 0, 0, 0, 220, 215, 1, 0, 0, 0, 220, 216, 1, 0, 0, 0, 220, 217, 1, 0, 0, 0, 220, 218, 1, 0, 0, 0, 220, 219, 1, 0, 0, 0, 221, 11, 1, 0, 0, 0, 222, 224, 5, 72, 0, 0, 223, 225, 3, 4, 2, 0, 224, 223, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 227, 1, 0, 0, 0, 226, 228, 5, 150, 0, 0, 227, 226, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 13, 1, 0, 0, 0, 229, 231, 5, 84, 0, 0, 230, 232, 3, 4, 2, 0, 231, 230, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 234, 1, 0, 0, 0, 233, 235, 5, 150, 0, 0, 234, 233, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 15, 1, 0, 0, 0, 236, 245, 5, 14, 0, 0, 237, 238, 5, 130, 0, 0, 238, 241, 3, 160, 80, 0, 239, 240, 5, 115, 0, 0, 240, 242, 3, 160, 80, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 243, 1, 0, 0, 0, 243, 244, 5, 149, 0, 0, 244, 246, 1, 0, 0, 0, 245, 237, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 248, 3, 36, 18, 0, 248, 17, 1, 0, 0, 0, 249, 250, 5, 93, 0, 0, 250, 254, 3, 36, 18, 0, 251, 253, 3, 16, 8, 0, 252, 251, 1, 0, 0, 0, 253, 256, 1, 0, 0, 0, 254, 252, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 255, 259, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 257, 258, 5, 29, 0, 0, 258, 260, 3, 36, 18, 0, 259, 257, 1, 0, 0, 0, 259, 260, 1, 0, 0, 0, 260, 19, 1, 0, 0, 0, 261, 262, 5, 40, 0, 0, 262, 263, 5, 130, 0, 0, 263, 264, 3, 4, 2, 0, 264, 265, 5, 149, 0, 0, 265, 268, 3, 10, 5, 0, 266, 267, 5, 25, 0, 0, 267, 269, 3, 10, 5, 0, 268, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 21, 1, 0, 0, 0, 270, 271, 5, 100, 0, 0, 271, 272, 5, 130, 0, 0, 272, 273, 3, 4, 2, 0, 273, 274, 5, 149, 0, 0, 274, 276, 3, 10, 5, 0, 275, 277, 5, 150, 0, 0, 276, 275, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 23, 1, 0, 0, 0, 278, 279, 5, 33, 0, 0, 279, 283, 5, 130, 0, 0, 280, 284, 3, 6, 3, 0, 281, 284, 3, 30, 15, 0, 282, 284, 3, 4, 2, 0, 283, 280, 1, 0, 0, 0, 283, 281, 1, 0, 0, 0, 283, 282, 1, 0, 0, 0, 283, 284, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287, 5, 150, 0, 0, 286, 288, 3, 4, 2, 0, 287, 286, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 293, 5, 150, 0, 0, 290, 294, 3, 6, 3, 0, 291, 294, 3, 30, 15, 0, 292, 294, 3, 4, 2, 0, 293, 290, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 293, 292, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 296, 5, 149, 0, 0, 296, 298, 3, 10, 5, 0, 297, 299, 5, 150, 0, 0, 298, 297, 1, 0, 0, 0, 298, 299, 1, 0, 0, 0, 299, 25, 1, 0, 0, 0, 300, 301, 5, 33, 0, 0, 301, 302, 5, 130, 0, 0, 302, 303, 5, 52, 0, 0, 303, 306, 3, 160, 80, 0, 304, 305, 5, 116, 0, 0, 305, 307, 3, 160, 80, 0, 306, 304, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 309, 5, 42, 0, 0, 309, 310, 3, 4, 2, 0, 310, 311, 5, 149, 0, 0, 311, 313, 3, 10, 5, 0, 312, 314, 5, 150, 0, 0, 313, 312, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 27, 1, 0, 0, 0, 315, 316, 5, 31, 0, 0, 316, 317, 3, 160, 80, 0, 317, 319, 5, 130, 0, 0, 318, 320, 3, 8, 4, 0, 319, 318, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 322, 5, 149, 0, 0, 322, 323, 3, 36, 18, 0, 323, 29, 1, 0, 0, 0, 324, 325, 3, 4, 2, 0, 325, 326, 5, 115, 0, 0, 326, 327, 5, 122, 0, 0, 327, 328, 3, 4, 2, 0, 328, 31, 1, 0, 0, 0, 329, 331, 3, 4, 2, 0, 330, 332, 5, 150, 0, 0, 331, 330, 1, 0, 0, 0, 331, 332, 1, 0, 0, 0, 332, 33, 1, 0, 0, 0, 333, 334, 5, 150, 0, 0, 334, 35, 1, 0, 0, 0, 335, 339, 5, 128, 0, 0, 336, 338, 3, 2, 1, 0, 337, 336, 1, 0, 0, 0, 338, 341, 1, 0, 0, 0, 339, 337, 1, 0, 0, 0, 339, 340, 1, 0, 0, 0, 340, 342, 1, 0, 0, 0, 341, 339, 1, 0, 0, 0, 342, 343, 5, 147, 0, 0, 343, 37, 1, 0, 0, 0, 344, 345, 3, 4, 2, 0, 345, 346, 5, 115, 0, 0, 346, 347, 3, 4, 2, 0, 347, 39, 1, 0, 0, 0, 348, 353, 3, 38, 19, 0, 349, 350, 5, 116, 0, 0, 350, 352, 3, 38, 19, 0, 351, 349, 1, 0, 0, 0, 352, 355, 1, 0, 0, 0, 353, 351, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 357, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, 358, 5, 116, 0, 0, 357, 356, 1, 0, 0, 0, 357, 358, 1, 0, 0, 0, 358, 41, 1, 0, 0, 0, 359, 363, 3, 44, 22, 0, 360, 363, 3, 48, 24, 0, 361, 363, 3, 124, 62, 0, 362, 359, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 361, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 365, 5, 0, 0, 1, 365, 43, 1, 0, 0, 0, 366, 372, 3, 46, 23, 0, 367, 368, 5, 95, 0, 0, 368, 369, 5, 1, 0, 0, 369, 371, 3, 46, 23, 0, 370, 367, 1, 0, 0, 0, 371, 374, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 372, 373, 1, 0, 0, 0, 373, 45, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 375, 382, 3, 48, 24, 0, 376, 377, 5, 130, 0, 0, 377, 378, 3, 44, 22, 0, 378, 379, 5, 149, 0, 0, 379, 382, 1, 0, 0, 0, 380, 382, 3, 164, 82, 0, 381, 375, 1, 0, 0, 0, 381, 376, 1, 0, 0, 0, 381, 380, 1, 0, 0, 0, 382, 47, 1, 0, 0, 0, 383, 385, 3, 50, 25, 0, 384, 383, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 386, 1, 0, 0, 0, 386, 388, 5, 79, 0, 0, 387, 389, 5, 24, 0, 0, 388, 387, 1, 0, 0, 0, 388, 389, 1, 0, 0, 0, 389, 391, 1, 0, 0, 0, 390, 392, 3, 52, 26, 0, 391, 390, 1, 0, 0, 0, 391, 392, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 395, 3, 114, 57, 0, 394, 396, 3, 54, 27, 0, 395, 394, 1, 0, 0, 0, 395, 396, 1, 0, 0, 0, 396, 398, 1, 0, 0, 0, 397, 399, 3, 56, 28, 0, 398, 397, 1, 0, 0, 0, 398, 399, 1, 0, 0, 0, 399, 401, 1, 0, 0, 0, 400, 402, 3, 60, 30, 0, 401, 400, 1, 0, 0, 0, 401, 402, 1, 0, 0, 0, 402, 404, 1, 0, 0, 0, 403, 405, 3, 62, 31, 0, 404, 403, 1, 0, 0, 0, 404, 405, 1, 0, 0, 0, 405, 407, 1, 0, 0, 0, 406, 408, 3, 64, 32, 0, 407, 406, 1, 0, 0, 0, 407, 408, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 410, 5, 102, 0, 0, 410, 412, 7, 0, 0, 0, 411, 409, 1, 0, 0, 0, 411, 412, 1, 0, 0, 0, 412, 415, 1, 0, 0, 0, 413, 414, 5, 102, 0, 0, 414, 416, 5, 89, 0, 0, 415, 413, 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 418, 1, 0, 0, 0, 417, 419, 3, 66, 33, 0, 418, 417, 1, 0, 0, 0, 418, 419, 1, 0, 0, 0, 419, 421, 1, 0, 0, 0, 420, 422, 3, 58, 29, 0, 421, 420, 1, 0, 0, 0, 421, 422, 1, 0, 0, 0, 422, 424, 1, 0, 0, 0, 423, 425, 3, 68, 34, 0, 424, 423, 1, 0, 0, 0, 424, 425, 1, 0, 0, 0, 425, 428, 1, 0, 0, 0, 426, 429, 3, 72, 36, 0, 427, 429, 3, 74, 37, 0, 428, 426, 1, 0, 0, 0, 428, 427, 1, 0, 0, 0, 428, 429, 1, 0, 0, 0, 429, 431, 1, 0, 0, 0, 430, 432, 3, 76, 38, 0, 431, 430, 1, 0, 0, 0, 431, 432, 1, 0, 0, 0, 432, 49, 1, 0, 0, 0, 433, 434, 5, 102, 0, 0, 434, 435, 3, 128, 64, 0, 435, 51, 1, 0, 0, 0, 436, 437, 5, 88, 0, 0, 437, 440, 5, 108, 0, 0, 438, 439, 5, 102, 0, 0, 439, 441, 5, 85, 0, 0, 440, 438, 1, 0, 0, 0, 440, 441, 1, 0, 0, 0, 441, 53, 1, 0, 0, 0, 442, 443, 5, 34, 0, 0, 443, 444, 3, 78, 39, 0, 444, 55, 1, 0, 0, 0, 445, 447, 7, 1, 0, 0, 446, 445, 1, 0, 0, 0, 446, 447, 1, 0, 0, 0, 447, 448, 1, 0, 0, 0, 448, 449, 5, 5, 0, 0, 449, 450, 5, 47, 0, 0, 450, 451, 3, 114, 57, 0, 451, 57, 1, 0, 0, 0, 452, 453, 5, 101, 0, 0, 453, 454, 3, 160, 80, 0, 454, 455, 5, 6, 0, 0, 455, 456, 5, 130, 0, 0, 456, 457, 3, 98, 49, 0, 457, 467, 5, 149, 0, 0, 458, 459, 5, 116, 0, 0, 459, 460, 3, 160, 80, 0, 460, 461, 5, 6, 0, 0, 461, 462, 5, 130, 0, 0, 462, 463, 3, 98, 49, 0, 463, 464, 5, 149, 0, 0, 464, 466, 1, 0, 0, 0, 465, 458, 1, 0, 0, 0, 466, 469, 1, 0, 0, 0, 467, 465, 1, 0, 0, 0, 467, 468, 1, 0, 0, 0, 468, 59, 1, 0, 0, 0, 469, 467, 1, 0, 0, 0, 470, 471, 5, 69, 0, 0, 471, 472, 3, 116, 58, 0, 472, 61, 1, 0, 0, 0, 473, 474, 5, 99, 0, 0, 474, 475, 3, 116, 58, 0, 475, 63, 1, 0, 0, 0, 476, 477, 5, 36, 0, 0, 477, 484, 5, 11, 0, 0, 478, 479, 7, 0, 0, 0, 479, 480, 5, 130, 0, 0, 480, 481, 3, 114, 57, 0, 481, 482, 5, 149, 0, 0, 482, 485, 1, 0, 0, 0, 483, 485, 3, 114, 57, 0, 484, 478, 1, 0, 0, 0, 484, 483, 1, 0, 0, 0, 485, 65, 1, 0, 0, 0, 486, 487, 5, 37, 0, 0, 487, 488, 3, 116, 58, 0, 488, 67, 1, 0, 0, 0, 489, 490, 5, 64, 0, 0, 490, 491, 5, 11, 0, 0, 491, 492, 3, 88, 44, 0, 492, 69, 1, 0, 0, 0, 493, 494, 5, 64, 0, 0, 494, 495, 5, 11, 0, 0, 495, 496, 3, 114, 57, 0, 496, 71, 1, 0, 0, 0, 497, 498, 5, 54, 0, 0, 498, 501, 3, 116, 58, 0, 499, 500, 5, 116, 0, 0, 500, 502, 3, 116, 58, 0, 501, 499, 1, 0, 0, 0, 501, 502, 1, 0, 0, 0, 502, 507, 1, 0, 0, 0, 503, 504, 5, 102, 0, 0, 504, 508, 5, 85, 0, 0, 505, 506, 5, 11, 0, 0, 506, 508, 3, 114, 57, 0, 507, 503, 1, 0, 0, 0, 507, 505, 1, 0, 0, 0, 507, 508, 1, 0, 0, 0, 508, 527, 1, 0, 0, 0, 509, 510, 5, 54, 0, 0, 510, 513, 3, 116, 58, 0, 511, 512, 5, 102, 0, 0, 512, 514, 5, 85, 0, 0, 513, 511, 1, 0, 0, 0, 513, 514, 1, 0, 0, 0, 514, 515, 1, 0, 0, 0, 515, 516, 5, 61, 0, 0, 516, 517, 3, 116, 58, 0, 517, 527, 1, 0, 0, 0, 518, 519, 5, 54, 0, 0, 519, 520, 3, 116, 58, 0, 520, 521, 5, 61, 0, 0, 521, 524, 3, 116, 58, 0, 522, 523, 5, 11, 0, 0, 523, 525, 3, 114, 57, 0, 524, 522, 1, 0, 0, 0, 524, 525, 1, 0, 0, 0, 525, 527, 1, 0, 0, 0, 526, 497, 1, 0, 0, 0, 526, 509, 1, 0, 0, 0, 526, 518, 1, 0, 0, 0, 527, 73, 1, 0, 0, 0, 528, 529, 5, 61, 0, 0, 529, 530, 3, 116, 58, 0, 530, 75, 1, 0, 0, 0, 531, 532, 5, 81, 0, 0, 532, 533, 3, 94, 47, 0, 533, 77, 1, 0, 0, 0, 534, 535, 6, 39, -1, 0, 535, 537, 3, 136, 68, 0, 536, 538, 5, 28, 0, 0, 537, 536, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 540, 1, 0, 0, 0, 539, 541, 3, 86, 43, 0, 540, 539, 1, 0, 0, 0, 540, 541, 1, 0, 0, 0, 541, 547, 1, 0, 0, 0, 542, 543, 5, 130, 0, 0, 543, 544, 3, 78, 39, 0, 544, 545, 5, 149, 0, 0, 545, 547, 1, 0, 0, 0, 546, 534, 1, 0, 0, 0, 546, 542, 1, 0, 0, 0, 547, 562, 1, 0, 0, 0, 548, 549, 10, 3, 0, 0, 549, 550, 3, 82, 41, 0, 550, 551, 3, 78, 39, 4, 551, 561, 1, 0, 0, 0, 552, 554, 10, 4, 0, 0, 553, 555, 3, 80, 40, 0, 554, 553, 1, 0, 0, 0, 554, 555, 1, 0, 0, 0, 555, 556, 1, 0, 0, 0, 556, 557, 5, 47, 0, 0, 557, 558, 3, 78, 39, 0, 558, 559, 3, 84, 42, 0, 559, 561, 1, 0, 0, 0, 560, 548, 1, 0, 0, 0, 560, 552, 1, 0, 0, 0, 561, 564, 1, 0, 0, 0, 562, 560, 1, 0, 0, 0, 562, 563, 1, 0, 0, 0, 563, 79, 1, 0, 0, 0, 564, 562, 1, 0, 0, 0, 565, 567, 7, 2, 0, 0, 566, 565, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 568, 1, 0, 0, 0, 568, 575, 5, 44, 0, 0, 569, 571, 5, 44, 0, 0, 570, 572, 7, 2, 0, 0, 571, 570, 1, 0, 0, 0, 571, 572, 1, 0, 0, 0, 572, 575, 1, 0, 0, 0, 573, 575, 7, 2, 0, 0, 574, 566, 1, 0, 0, 0, 574, 569, 1, 0, 0, 0, 574, 573, 1, 0, 0, 0, 575, 609, 1, 0, 0, 0, 576, 578, 7, 3, 0, 0, 577, 576, 1, 0, 0, 0, 577, 578, 1, 0, 0, 0, 578, 579, 1, 0, 0, 0, 579, 581, 7, 4, 0, 0, 580, 582, 5, 65, 0, 0, 581, 580, 1, 0, 0, 0, 581, 582, 1, 0, 0, 0, 582, 591, 1, 0, 0, 0, 583, 585, 7, 4, 0, 0, 584, 586, 5, 65, 0, 0, 585, 584, 1, 0, 0, 0, 585, 586, 1, 0, 0, 0, 586, 588, 1, 0, 0, 0, 587, 589, 7, 3, 0, 0, 588, 587, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 591, 1, 0, 0, 0, 590, 577, 1, 0, 0, 0, 590, 583, 1, 0, 0, 0, 591, 609, 1, 0, 0, 0, 592, 594, 7, 5, 0, 0, 593, 592, 1, 0, 0, 0, 593, 594, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, 595, 597, 5, 35, 0, 0, 596, 598, 5, 65, 0, 0, 597, 596, 1, 0, 0, 0, 597, 598, 1, 0, 0, 0, 598, 607, 1, 0, 0, 0, 599, 601, 5, 35, 0, 0, 600, 602, 5, 65, 0, 0, 601, 600, 1, 0, 0, 0, 601, 602, 1, 0, 0, 0, 602, 604, 1, 0, 0, 0, 603, 605, 7, 5, 0, 0, 604, 603, 1, 0, 0, 0, 604, 605, 1, 0, 0, 0, 605, 607, 1, 0, 0, 0, 606, 593, 1, 0, 0, 0, 606, 599, 1, 0, 0, 0, 607, 609, 1, 0, 0, 0, 608, 574, 1, 0, 0, 0, 608, 590, 1, 0, 0, 0, 608, 606, 1, 0, 0, 0, 609, 81, 1, 0, 0, 0, 610, 611, 5, 17, 0, 0, 611, 614, 5, 47, 0, 0, 612, 614, 5, 116, 0, 0, 613, 610, 1, 0, 0, 0, 613, 612, 1, 0, 0, 0, 614, 83, 1, 0, 0, 0, 615, 616, 5, 62, 0, 0, 616, 625, 3, 114, 57, 0, 617, 618, 5, 96, 0, 0, 618, 619, 5, 130, 0, 0, 619, 620, 3, 114, 57, 0, 620, 621, 5, 149, 0, 0, 621, 625, 1, 0, 0, 0, 622, 623, 5, 96, 0, 0, 623, 625, 3, 114, 57, 0, 624, 615, 1, 0, 0, 0, 624, 617, 1, 0, 0, 0, 624, 622, 1, 0, 0, 0, 625, 85, 1, 0, 0, 0, 626, 627, 5, 77, 0, 0, 627, 630, 3, 92, 46, 0, 628, 629, 5, 61, 0, 0, 629, 631, 3, 92, 46, 0, 630, 628, 1, 0, 0, 0, 630, 631, 1, 0, 0, 0, 631, 87, 1, 0, 0, 0, 632, 637, 3, 90, 45, 0, 633, 634, 5, 116, 0, 0, 634, 636, 3, 90, 45, 0, 635, 633, 1, 0, 0, 0, 636, 639, 1, 0, 0, 0, 637, 635, 1, 0, 0, 0, 637, 638, 1, 0, 0, 0, 638, 89, 1, 0, 0, 0, 639, 637, 1, 0, 0, 0, 640, 642, 3, 116, 58, 0, 641, 643, 7, 6, 0, 0, 642, 641, 1, 0, 0, 0, 642, 643, 1, 0, 0, 0, 643, 646, 1, 0, 0, 0, 644, 645, 5, 60, 0, 0, 645, 647, 7, 7, 0, 0, 646, 644, 1, 0, 0, 0, 646, 647, 1, 0, 0, 0, 647, 650, 1, 0, 0, 0, 648, 649, 5, 16, 0, 0, 649, 651, 5, 110, 0, 0, 650, 648, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 91, 1, 0, 0, 0, 652, 659, 3, 164, 82, 0, 653, 656, 3, 148, 74, 0, 654, 655, 5, 151, 0, 0, 655, 657, 3, 148, 74, 0, 656, 654, 1, 0, 0, 0, 656, 657, 1, 0, 0, 0, 657, 659, 1, 0, 0, 0, 658, 652, 1, 0, 0, 0, 658, 653, 1, 0, 0, 0, 659, 93, 1, 0, 0, 0, 660, 665, 3, 96, 48, 0, 661, 662, 5, 116, 0, 0, 662, 664, 3, 96, 48, 0, 663, 661, 1, 0, 0, 0, 664, 667, 1, 0, 0, 0, 665, 663, 1, 0, 0, 0, 665, 666, 1, 0, 0, 0, 666, 95, 1, 0, 0, 0, 667, 665, 1, 0, 0, 0, 668, 669, 3, 160, 80, 0, 669, 670, 5, 122, 0, 0, 670, 671, 3, 150, 75, 0, 671, 97, 1, 0, 0, 0, 672, 674, 3, 100, 50, 0, 673, 672, 1, 0, 0, 0, 673, 674, 1, 0, 0, 0, 674, 676, 1, 0, 0, 0, 675, 677, 3, 102, 51, 0, 676, 675, 1, 0, 0, 0, 676, 677, 1, 0, 0, 0, 677, 679, 1, 0, 0, 0, 678, 680, 3, 104, 52, 0, 679, 678, 1, 0, 0, 0, 679, 680, 1, 0, 0, 0, 680, 99, 1, 0, 0, 0, 681, 682, 5, 67, 0, 0, 682, 683, 5, 11, 0, 0, 683, 684, 3, 114, 57, 0, 684, 101, 1, 0, 0, 0, 685, 686, 5, 64, 0, 0, 686, 687, 5, 11, 0, 0, 687, 688, 3, 88, 44, 0, 688, 103, 1, 0, 0, 0, 689, 690, 7, 8, 0, 0, 690, 691, 3, 106, 53, 0, 691, 105, 1, 0, 0, 0, 692, 699, 3, 108, 54, 0, 693, 694, 5, 9, 0, 0, 694, 695, 3, 108, 54, 0, 695, 696, 5, 2, 0, 0, 696, 697, 3, 108, 54, 0, 697, 699, 1, 0, 0, 0, 698, 692, 1, 0, 0, 0, 698, 693, 1, 0, 0, 0, 699, 107, 1, 0, 0, 0, 700, 701, 5, 19, 0, 0, 701, 713, 5, 75, 0, 0, 702, 703, 5, 94, 0, 0, 703, 713, 5, 68, 0, 0, 704, 705, 5, 94, 0, 0, 705, 713, 5, 32, 0, 0, 706, 707, 3, 148, 74, 0, 707, 708, 5, 68, 0, 0, 708, 713, 1, 0, 0, 0, 709, 710, 3, 148, 74, 0, 710, 711, 5, 32, 0, 0, 711, 713, 1, 0, 0, 0, 712, 700, 1, 0, 0, 0, 712, 702, 1, 0, 0, 0, 712, 704, 1, 0, 0, 0, 712, 706, 1, 0, 0, 0, 712, 709, 1, 0, 0, 0, 713, 109, 1, 0, 0, 0, 714, 715, 3, 116, 58, 0, 715, 716, 5, 0, 0, 1, 716, 111, 1, 0, 0, 0, 717, 774, 3, 160, 80, 0, 718, 719, 3, 160, 80, 0, 719, 720, 5, 130, 0, 0, 720, 721, 3, 160, 80, 0, 721, 728, 3, 112, 56, 0, 722, 723, 5, 116, 0, 0, 723, 724, 3, 160, 80, 0, 724, 725, 3, 112, 56, 0, 725, 727, 1, 0, 0, 0, 726, 722, 1, 0, 0, 0, 727, 730, 1, 0, 0, 0, 728, 726, 1, 0, 0, 0, 728, 729, 1, 0, 0, 0, 729, 732, 1, 0, 0, 0, 730, 728, 1, 0, 0, 0, 731, 733, 5, 116, 0, 0, 732, 731, 1, 0, 0, 0, 732, 733, 1, 0, 0, 0, 733, 734, 1, 0, 0, 0, 734, 735, 5, 149, 0, 0, 735, 774, 1, 0, 0, 0, 736, 737, 3, 160, 80, 0, 737, 738, 5, 130, 0, 0, 738, 743, 3, 162, 81, 0, 739, 740, 5, 116, 0, 0, 740, 742, 3, 162, 81, 0, 741, 739, 1, 0, 0, 0, 742, 745, 1, 0, 0, 0, 743, 741, 1, 0, 0, 0, 743, 744, 1, 0, 0, 0, 744, 747, 1, 0, 0, 0, 745, 743, 1, 0, 0, 0, 746, 748, 5, 116, 0, 0, 747, 746, 1, 0, 0, 0, 747, 748, 1, 0, 0, 0, 748, 749, 1, 0, 0, 0, 749, 750, 5, 149, 0, 0, 750, 774, 1, 0, 0, 0, 751, 752, 3, 160, 80, 0, 752, 753, 5, 130, 0, 0, 753, 758, 3, 112, 56, 0, 754, 755, 5, 116, 0, 0, 755, 757, 3, 112, 56, 0, 756, 754, 1, 0, 0, 0, 757, 760, 1, 0, 0, 0, 758, 756, 1, 0, 0, 0, 758, 759, 1, 0, 0, 0, 759, 762, 1, 0, 0, 0, 760, 758, 1, 0, 0, 0, 761, 763, 5, 116, 0, 0, 762, 761, 1, 0, 0, 0, 762, 763, 1, 0, 0, 0, 763, 764, 1, 0, 0, 0, 764, 765, 5, 149, 0, 0, 765, 774, 1, 0, 0, 0, 766, 767, 3, 160, 80, 0, 767, 769, 5, 130, 0, 0, 768, 770, 3, 114, 57, 0, 769, 768, 1, 0, 0, 0, 769, 770, 1, 0, 0, 0, 770, 771, 1, 0, 0, 0, 771, 772, 5, 149, 0, 0, 772, 774, 1, 0, 0, 0, 773, 717, 1, 0, 0, 0, 773, 718, 1, 0, 0, 0, 773, 736, 1, 0, 0, 0, 773, 751, 1, 0, 0, 0, 773, 766, 1, 0, 0, 0, 774, 113, 1, 0, 0, 0, 775, 780, 3, 116, 58, 0, 776, 777, 5, 116, 0, 0, 777, 779, 3, 116, 58, 0, 778, 776, 1, 0, 0, 0, 779, 782, 1, 0, 0, 0, 780, 778, 1, 0, 0, 0, 780, 781, 1, 0, 0, 0, 781, 784, 1, 0, 0, 0, 782, 780, 1, 0, 0, 0, 783, 785, 5, 116, 0, 0, 784, 783, 1, 0, 0, 0, 784, 785, 1, 0, 0, 0, 785, 115, 1, 0, 0, 0, 786, 787, 6, 58, -1, 0, 787, 789, 5, 12, 0, 0, 788, 790, 3, 116, 58, 0, 789, 788, 1, 0, 0, 0, 789, 790, 1, 0, 0, 0, 790, 796, 1, 0, 0, 0, 791, 792, 5, 98, 0, 0, 792, 793, 3, 116, 58, 0, 793, 794, 5, 83, 0, 0, 794, 795, 3, 116, 58, 0, 795, 797, 1, 0, 0, 0, 796, 791, 1, 0, 0, 0, 797, 798, 1, 0, 0, 0, 798, 796, 1, 0, 0, 0, 798, 799, 1, 0, 0, 0, 799, 802, 1, 0, 0, 0, 800, 801, 5, 25, 0, 0, 801, 803, 3, 116, 58, 0, 802, 800, 1, 0, 0, 0, 802, 803, 1, 0, 0, 0, 803, 804, 1, 0, 0, 0, 804, 805, 5, 26, 0, 0, 805, 936, 1, 0, 0, 0, 806, 807, 5, 13, 0, 0, 807, 808, 5, 130, 0, 0, 808, 809, 3, 116, 58, 0, 809, 810, 5, 6, 0, 0, 810, 811, 3, 112, 56, 0, 811, 812, 5, 149, 0, 0, 812, 936, 1, 0, 0, 0, 813, 814, 5, 20, 0, 0, 814, 936, 5, 110, 0, 0, 815, 816, 5, 45, 0, 0, 816, 817, 3, 116, 58, 0, 817, 818, 3, 152, 76, 0, 818, 936, 1, 0, 0, 0, 819, 820, 5, 82, 0, 0, 820, 821, 5, 130, 0, 0, 821, 822, 3, 116, 58, 0, 822, 823, 5, 34, 0, 0, 823, 826, 3, 116, 58, 0, 824, 825, 5, 33, 0, 0, 825, 827, 3, 116, 58, 0, 826, 824, 1, 0, 0, 0, 826, 827, 1, 0, 0, 0, 827, 828, 1, 0, 0, 0, 828, 829, 5, 149, 0, 0, 829, 936, 1, 0, 0, 0, 830, 831, 5, 86, 0, 0, 831, 936, 5, 110, 0, 0, 832, 833, 5, 91, 0, 0, 833, 834, 5, 130, 0, 0, 834, 835, 7, 9, 0, 0, 835, 836, 3, 166, 83, 0, 836, 837, 5, 34, 0, 0, 837, 838, 3, 116, 58, 0, 838, 839, 5, 149, 0, 0, 839, 936, 1, 0, 0, 0, 840, 841, 3, 160, 80, 0, 841, 843, 5, 130, 0, 0, 842, 844, 3, 114, 57, 0, 843, 842, 1, 0, 0, 0, 843, 844, 1, 0, 0, 0, 844, 845, 1, 0, 0, 0, 845, 846, 5, 149, 0, 0, 846, 855, 1, 0, 0, 0, 847, 849, 5, 130, 0, 0, 848, 850, 5, 24, 0, 0, 849, 848, 1, 0, 0, 0, 849, 850, 1, 0, 0, 0, 850, 852, 1, 0, 0, 0, 851, 853, 3, 118, 59, 0, 852, 851, 1, 0, 0, 0, 852, 853, 1, 0, 0, 0, 853, 854, 1, 0, 0, 0, 854, 856, 5, 149, 0, 0, 855, 847, 1, 0, 0, 0, 855, 856, 1, 0, 0, 0, 856, 857, 1, 0, 0, 0, 857, 858, 5, 66, 0, 0, 858, 859, 5, 130, 0, 0, 859, 860, 3, 98, 49, 0, 860, 861, 5, 149, 0, 0, 861, 936, 1, 0, 0, 0, 862, 863, 3, 160, 80, 0, 863, 865, 5, 130, 0, 0, 864, 866, 3, 114, 57, 0, 865, 864, 1, 0, 0, 0, 865, 866, 1, 0, 0, 0, 866, 867, 1, 0, 0, 0, 867, 868, 5, 149, 0, 0, 868, 877, 1, 0, 0, 0, 869, 871, 5, 130, 0, 0, 870, 872, 5, 24, 0, 0, 871, 870, 1, 0, 0, 0, 871, 872, 1, 0, 0, 0, 872, 874, 1, 0, 0, 0, 873, 875, 3, 118, 59, 0, 874, 873, 1, 0, 0, 0, 874, 875, 1, 0, 0, 0, 875, 876, 1, 0, 0, 0, 876, 878, 5, 149, 0, 0, 877, 869, 1, 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 879, 1, 0, 0, 0, 879, 880, 5, 66, 0, 0, 880, 881, 3, 160, 80, 0, 881, 936, 1, 0, 0, 0, 882, 888, 3, 160, 80, 0, 883, 885, 5, 130, 0, 0, 884, 886, 3, 114, 57, 0, 885, 884, 1, 0, 0, 0, 885, 886, 1, 0, 0, 0, 886, 887, 1, 0, 0, 0, 887, 889, 5, 149, 0, 0, 888, 883, 1, 0, 0, 0, 888, 889, 1, 0, 0, 0, 889, 890, 1, 0, 0, 0, 890, 892, 5, 130, 0, 0, 891, 893, 5, 24, 0, 0, 892, 891, 1, 0, 0, 0, 892, 893, 1, 0, 0, 0, 893, 895, 1, 0, 0, 0, 894, 896, 3, 118, 59, 0, 895, 894, 1, 0, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897, 1, 0, 0, 0, 897, 898, 5, 149, 0, 0, 898, 936, 1, 0, 0, 0, 899, 936, 3, 124, 62, 0, 900, 936, 3, 168, 84, 0, 901, 936, 3, 150, 75, 0, 902, 903, 5, 118, 0, 0, 903, 936, 3, 116, 58, 19, 904, 905, 5, 58, 0, 0, 905, 936, 3, 116, 58, 13, 906, 907, 3, 140, 70, 0, 907, 908, 5, 120, 0, 0, 908, 910, 1, 0, 0, 0, 909, 906, 1, 0, 0, 0, 909, 910, 1, 0, 0, 0, 910, 911, 1, 0, 0, 0, 911, 936, 5, 112, 0, 0, 912, 913, 5, 130, 0, 0, 913, 914, 3, 44, 22, 0, 914, 915, 5, 149, 0, 0, 915, 936, 1, 0, 0, 0, 916, 917, 5, 130, 0, 0, 917, 918, 3, 116, 58, 0, 918, 919, 5, 149, 0, 0, 919, 936, 1, 0, 0, 0, 920, 921, 5, 130, 0, 0, 921, 922, 3, 114, 57, 0, 922, 923, 5, 149, 0, 0, 923, 936, 1, 0, 0, 0, 924, 926, 5, 129, 0, 0, 925, 927, 3, 114, 57, 0, 926, 925, 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, 927, 928, 1, 0, 0, 0, 928, 936, 5, 148, 0, 0, 929, 931, 5, 128, 0, 0, 930, 932, 3, 40, 20, 0, 931, 930, 1, 0, 0, 0, 931, 932, 1, 0, 0, 0, 932, 933, 1, 0, 0, 0, 933, 936, 5, 147, 0, 0, 934, 936, 3, 132, 66, 0, 935, 786, 1, 0, 0, 0, 935, 806, 1, 0, 0, 0, 935, 813, 1, 0, 0, 0, 935, 815, 1, 0, 0, 0, 935, 819, 1, 0, 0, 0, 935, 830, 1, 0, 0, 0, 935, 832, 1, 0, 0, 0, 935, 840, 1, 0, 0, 0, 935, 862, 1, 0, 0, 0, 935, 882, 1, 0, 0, 0, 935, 899, 1, 0, 0, 0, 935, 900, 1, 0, 0, 0, 935, 901, 1, 0, 0, 0, 935, 902, 1, 0, 0, 0, 935, 904, 1, 0, 0, 0, 935, 909, 1, 0, 0, 0, 935, 912, 1, 0, 0, 0, 935, 916, 1, 0, 0, 0, 935, 920, 1, 0, 0, 0, 935, 924, 1, 0, 0, 0, 935, 929, 1, 0, 0, 0, 935, 934, 1, 0, 0, 0, 936, 1041, 1, 0, 0, 0, 937, 941, 10, 18, 0, 0, 938, 942, 5, 112, 0, 0, 939, 942, 5, 151, 0, 0, 940, 942, 5, 138, 0, 0, 941, 938, 1, 0, 0, 0, 941, 939, 1, 0, 0, 0, 941, 940, 1, 0, 0, 0, 942, 943, 1, 0, 0, 0, 943, 1040, 3, 116, 58, 19, 944, 948, 10, 17, 0, 0, 945, 949, 5, 139, 0, 0, 946, 949, 5, 118, 0, 0, 947, 949, 5, 117, 0, 0, 948, 945, 1, 0, 0, 0, 948, 946, 1, 0, 0, 0, 948, 947, 1, 0, 0, 0, 949, 950, 1, 0, 0, 0, 950, 1040, 3, 116, 58, 18, 951, 976, 10, 16, 0, 0, 952, 977, 5, 121, 0, 0, 953, 977, 5, 122, 0, 0, 954, 977, 5, 133, 0, 0, 955, 977, 5, 131, 0, 0, 956, 977, 5, 132, 0, 0, 957, 977, 5, 123, 0, 0, 958, 977, 5, 124, 0, 0, 959, 961, 5, 58, 0, 0, 960, 959, 1, 0, 0, 0, 960, 961, 1, 0, 0, 0, 961, 962, 1, 0, 0, 0, 962, 964, 5, 42, 0, 0, 963, 965, 5, 15, 0, 0, 964, 963, 1, 0, 0, 0, 964, 965, 1, 0, 0, 0, 965, 977, 1, 0, 0, 0, 966, 968, 5, 58, 0, 0, 967, 966, 1, 0, 0, 0, 967, 968, 1, 0, 0, 0, 968, 969, 1, 0, 0, 0, 969, 977, 7, 10, 0, 0, 970, 977, 5, 145, 0, 0, 971, 977, 5, 146, 0, 0, 972, 977, 5, 135, 0, 0, 973, 977, 5, 126, 0, 0, 974, 977, 5, 127, 0, 0, 975, 977, 5, 134, 0, 0, 976, 952, 1, 0, 0, 0, 976, 953, 1, 0, 0, 0, 976, 954, 1, 0, 0, 0, 976, 955, 1, 0, 0, 0, 976, 956, 1, 0, 0, 0, 976, 957, 1, 0, 0, 0, 976, 958, 1, 0, 0, 0, 976, 960, 1, 0, 0, 0, 976, 967, 1, 0, 0, 0, 976, 970, 1, 0, 0, 0, 976, 971, 1, 0, 0, 0, 976, 972, 1, 0, 0, 0, 976, 973, 1, 0, 0, 0, 976, 974, 1, 0, 0, 0, 976, 975, 1, 0, 0, 0, 977, 978, 1, 0, 0, 0, 978, 1040, 3, 116, 58, 17, 979, 980, 10, 14, 0, 0, 980, 981, 5, 137, 0, 0, 981, 1040, 3, 116, 58, 15, 982, 983, 10, 12, 0, 0, 983, 984, 5, 2, 0, 0, 984, 1040, 3, 116, 58, 13, 985, 986, 10, 11, 0, 0, 986, 987, 5, 63, 0, 0, 987, 1040, 3, 116, 58, 12, 988, 990, 10, 10, 0, 0, 989, 991, 5, 58, 0, 0, 990, 989, 1, 0, 0, 0, 990, 991, 1, 0, 0, 0, 991, 992, 1, 0, 0, 0, 992, 993, 5, 9, 0, 0, 993, 994, 3, 116, 58, 0, 994, 995, 5, 2, 0, 0, 995, 996, 3, 116, 58, 11, 996, 1040, 1, 0, 0, 0, 997, 998, 10, 9, 0, 0, 998, 999, 5, 140, 0, 0, 999, 1000, 3, 116, 58, 0, 1000, 1001, 5, 115, 0, 0, 1001, 1002, 3, 116, 58, 9, 1002, 1040, 1, 0, 0, 0, 1003, 1004, 10, 25, 0, 0, 1004, 1005, 5, 129, 0, 0, 1005, 1006, 3, 116, 58, 0, 1006, 1007, 5, 148, 0, 0, 1007, 1040, 1, 0, 0, 0, 1008, 1009, 10, 24, 0, 0, 1009, 1010, 5, 120, 0, 0, 1010, 1040, 5, 108, 0, 0, 1011, 1012, 10, 23, 0, 0, 1012, 1013, 5, 120, 0, 0, 1013, 1040, 3, 160, 80, 0, 1014, 1015, 10, 22, 0, 0, 1015, 1016, 5, 136, 0, 0, 1016, 1017, 5, 129, 0, 0, 1017, 1018, 3, 116, 58, 0, 1018, 1019, 5, 148, 0, 0, 1019, 1040, 1, 0, 0, 0, 1020, 1021, 10, 21, 0, 0, 1021, 1022, 5, 136, 0, 0, 1022, 1040, 5, 108, 0, 0, 1023, 1024, 10, 20, 0, 0, 1024, 1025, 5, 136, 0, 0, 1025, 1040, 3, 160, 80, 0, 1026, 1027, 10, 15, 0, 0, 1027, 1029, 5, 46, 0, 0, 1028, 1030, 5, 58, 0, 0, 1029, 1028, 1, 0, 0, 0, 1029, 1030, 1, 0, 0, 0, 1030, 1031, 1, 0, 0, 0, 1031, 1040, 5, 59, 0, 0, 1032, 1037, 10, 8, 0, 0, 1033, 1034, 5, 6, 0, 0, 1034, 1038, 3, 160, 80, 0, 1035, 1036, 5, 6, 0, 0, 1036, 1038, 5, 110, 0, 0, 1037, 1033, 1, 0, 0, 0, 1037, 1035, 1, 0, 0, 0, 1038, 1040, 1, 0, 0, 0, 1039, 937, 1, 0, 0, 0, 1039, 944, 1, 0, 0, 0, 1039, 951, 1, 0, 0, 0, 1039, 979, 1, 0, 0, 0, 1039, 982, 1, 0, 0, 0, 1039, 985, 1, 0, 0, 0, 1039, 988, 1, 0, 0, 0, 1039, 997, 1, 0, 0, 0, 1039, 1003, 1, 0, 0, 0, 1039, 1008, 1, 0, 0, 0, 1039, 1011, 1, 0, 0, 0, 1039, 1014, 1, 0, 0, 0, 1039, 1020, 1, 0, 0, 0, 1039, 1023, 1, 0, 0, 0, 1039, 1026, 1, 0, 0, 0, 1039, 1032, 1, 0, 0, 0, 1040, 1043, 1, 0, 0, 0, 1041, 1039, 1, 0, 0, 0, 1041, 1042, 1, 0, 0, 0, 1042, 117, 1, 0, 0, 0, 1043, 1041, 1, 0, 0, 0, 1044, 1049, 3, 120, 60, 0, 1045, 1046, 5, 116, 0, 0, 1046, 1048, 3, 120, 60, 0, 1047, 1045, 1, 0, 0, 0, 1048, 1051, 1, 0, 0, 0, 1049, 1047, 1, 0, 0, 0, 1049, 1050, 1, 0, 0, 0, 1050, 1053, 1, 0, 0, 0, 1051, 1049, 1, 0, 0, 0, 1052, 1054, 5, 116, 0, 0, 1053, 1052, 1, 0, 0, 0, 1053, 1054, 1, 0, 0, 0, 1054, 119, 1, 0, 0, 0, 1055, 1058, 3, 122, 61, 0, 1056, 1058, 3, 116, 58, 0, 1057, 1055, 1, 0, 0, 0, 1057, 1056, 1, 0, 0, 0, 1058, 121, 1, 0, 0, 0, 1059, 1060, 5, 130, 0, 0, 1060, 1065, 3, 160, 80, 0, 1061, 1062, 5, 116, 0, 0, 1062, 1064, 3, 160, 80, 0, 1063, 1061, 1, 0, 0, 0, 1064, 1067, 1, 0, 0, 0, 1065, 1063, 1, 0, 0, 0, 1065, 1066, 1, 0, 0, 0, 1066, 1069, 1, 0, 0, 0, 1067, 1065, 1, 0, 0, 0, 1068, 1070, 5, 116, 0, 0, 1069, 1068, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 1071, 1, 0, 0, 0, 1071, 1072, 5, 149, 0, 0, 1072, 1085, 1, 0, 0, 0, 1073, 1078, 3, 160, 80, 0, 1074, 1075, 5, 116, 0, 0, 1075, 1077, 3, 160, 80, 0, 1076, 1074, 1, 0, 0, 0, 1077, 1080, 1, 0, 0, 0, 1078, 1076, 1, 0, 0, 0, 1078, 1079, 1, 0, 0, 0, 1079, 1082, 1, 0, 0, 0, 1080, 1078, 1, 0, 0, 0, 1081, 1083, 5, 116, 0, 0, 1082, 1081, 1, 0, 0, 0, 1082, 1083, 1, 0, 0, 0, 1083, 1085, 1, 0, 0, 0, 1084, 1059, 1, 0, 0, 0, 1084, 1073, 1, 0, 0, 0, 1085, 1086, 1, 0, 0, 0, 1086, 1087, 5, 111, 0, 0, 1087, 1088, 3, 116, 58, 0, 1088, 123, 1, 0, 0, 0, 1089, 1090, 5, 132, 0, 0, 1090, 1094, 3, 160, 80, 0, 1091, 1093, 3, 126, 63, 0, 1092, 1091, 1, 0, 0, 0, 1093, 1096, 1, 0, 0, 0, 1094, 1092, 1, 0, 0, 0, 1094, 1095, 1, 0, 0, 0, 1095, 1097, 1, 0, 0, 0, 1096, 1094, 1, 0, 0, 0, 1097, 1098, 5, 151, 0, 0, 1098, 1099, 5, 124, 0, 0, 1099, 1122, 1, 0, 0, 0, 1100, 1101, 5, 132, 0, 0, 1101, 1105, 3, 160, 80, 0, 1102, 1104, 3, 126, 63, 0, 1103, 1102, 1, 0, 0, 0, 1104, 1107, 1, 0, 0, 0, 1105, 1103, 1, 0, 0, 0, 1105, 1106, 1, 0, 0, 0, 1106, 1108, 1, 0, 0, 0, 1107, 1105, 1, 0, 0, 0, 1108, 1114, 5, 124, 0, 0, 1109, 1115, 3, 124, 62, 0, 1110, 1111, 5, 128, 0, 0, 1111, 1112, 3, 116, 58, 0, 1112, 1113, 5, 147, 0, 0, 1113, 1115, 1, 0, 0, 0, 1114, 1109, 1, 0, 0, 0, 1114, 1110, 1, 0, 0, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1116, 1, 0, 0, 0, 1116, 1117, 5, 132, 0, 0, 1117, 1118, 5, 151, 0, 0, 1118, 1119, 3, 160, 80, 0, 1119, 1120, 5, 124, 0, 0, 1120, 1122, 1, 0, 0, 0, 1121, 1089, 1, 0, 0, 0, 1121, 1100, 1, 0, 0, 0, 1122, 125, 1, 0, 0, 0, 1123, 1124, 3, 160, 80, 0, 1124, 1125, 5, 122, 0, 0, 1125, 1126, 3, 166, 83, 0, 1126, 1135, 1, 0, 0, 0, 1127, 1128, 3, 160, 80, 0, 1128, 1129, 5, 122, 0, 0, 1129, 1130, 5, 128, 0, 0, 1130, 1131, 3, 116, 58, 0, 1131, 1132, 5, 147, 0, 0, 1132, 1135, 1, 0, 0, 0, 1133, 1135, 3, 160, 80, 0, 1134, 1123, 1, 0, 0, 0, 1134, 1127, 1, 0, 0, 0, 1134, 1133, 1, 0, 0, 0, 1135, 127, 1, 0, 0, 0, 1136, 1141, 3, 130, 65, 0, 1137, 1138, 5, 116, 0, 0, 1138, 1140, 3, 130, 65, 0, 1139, 1137, 1, 0, 0, 0, 1140, 1143, 1, 0, 0, 0, 1141, 1139, 1, 0, 0, 0, 1141, 1142, 1, 0, 0, 0, 1142, 1145, 1, 0, 0, 0, 1143, 1141, 1, 0, 0, 0, 1144, 1146, 5, 116, 0, 0, 1145, 1144, 1, 0, 0, 0, 1145, 1146, 1, 0, 0, 0, 1146, 129, 1, 0, 0, 0, 1147, 1148, 3, 160, 80, 0, 1148, 1149, 5, 6, 0, 0, 1149, 1150, 5, 130, 0, 0, 1150, 1151, 3, 44, 22, 0, 1151, 1152, 5, 149, 0, 0, 1152, 1158, 1, 0, 0, 0, 1153, 1154, 3, 116, 58, 0, 1154, 1155, 5, 6, 0, 0, 1155, 1156, 3, 160, 80, 0, 1156, 1158, 1, 0, 0, 0, 1157, 1147, 1, 0, 0, 0, 1157, 1153, 1, 0, 0, 0, 1158, 131, 1, 0, 0, 0, 1159, 1167, 3, 164, 82, 0, 1160, 1161, 3, 140, 70, 0, 1161, 1162, 5, 120, 0, 0, 1162, 1164, 1, 0, 0, 0, 1163, 1160, 1, 0, 0, 0, 1163, 1164, 1, 0, 0, 0, 1164, 1165, 1, 0, 0, 0, 1165, 1167, 3, 134, 67, 0, 1166, 1159, 1, 0, 0, 0, 1166, 1163, 1, 0, 0, 0, 1167, 133, 1, 0, 0, 0, 1168, 1173, 3, 160, 80, 0, 1169, 1170, 5, 120, 0, 0, 1170, 1172, 3, 160, 80, 0, 1171, 1169, 1, 0, 0, 0, 1172, 1175, 1, 0, 0, 0, 1173, 1171, 1, 0, 0, 0, 1173, 1174, 1, 0, 0, 0, 1174, 135, 1, 0, 0, 0, 1175, 1173, 1, 0, 0, 0, 1176, 1177, 6, 68, -1, 0, 1177, 1186, 3, 140, 70, 0, 1178, 1186, 3, 138, 69, 0, 1179, 1180, 5, 130, 0, 0, 1180, 1181, 3, 44, 22, 0, 1181, 1182, 5, 149, 0, 0, 1182, 1186, 1, 0, 0, 0, 1183, 1186, 3, 124, 62, 0, 1184, 1186, 3, 164, 82, 0, 1185, 1176, 1, 0, 0, 0, 1185, 1178, 1, 0, 0, 0, 1185, 1179, 1, 0, 0, 0, 1185, 1183, 1, 0, 0, 0, 1185, 1184, 1, 0, 0, 0, 1186, 1195, 1, 0, 0, 0, 1187, 1191, 10, 3, 0, 0, 1188, 1192, 3, 158, 79, 0, 1189, 1190, 5, 6, 0, 0, 1190, 1192, 3, 160, 80, 0, 1191, 1188, 1, 0, 0, 0, 1191, 1189, 1, 0, 0, 0, 1192, 1194, 1, 0, 0, 0, 1193, 1187, 1, 0, 0, 0, 1194, 1197, 1, 0, 0, 0, 1195, 1193, 1, 0, 0, 0, 1195, 1196, 1, 0, 0, 0, 1196, 137, 1, 0, 0, 0, 1197, 1195, 1, 0, 0, 0, 1198, 1199, 3, 160, 80, 0, 1199, 1201, 5, 130, 0, 0, 1200, 1202, 3, 142, 71, 0, 1201, 1200, 1, 0, 0, 0, 1201, 1202, 1, 0, 0, 0, 1202, 1203, 1, 0, 0, 0, 1203, 1204, 5, 149, 0, 0, 1204, 139, 1, 0, 0, 0, 1205, 1206, 3, 144, 72, 0, 1206, 1207, 5, 120, 0, 0, 1207, 1209, 1, 0, 0, 0, 1208, 1205, 1, 0, 0, 0, 1208, 1209, 1, 0, 0, 0, 1209, 1210, 1, 0, 0, 0, 1210, 1211, 3, 160, 80, 0, 1211, 141, 1, 0, 0, 0, 1212, 1217, 3, 116, 58, 0, 1213, 1214, 5, 116, 0, 0, 1214, 1216, 3, 116, 58, 0, 1215, 1213, 1, 0, 0, 0, 1216, 1219, 1, 0, 0, 0, 1217, 1215, 1, 0, 0, 0, 1217, 1218, 1, 0, 0, 0, 1218, 1221, 1, 0, 0, 0, 1219, 1217, 1, 0, 0, 0, 1220, 1222, 5, 116, 0, 0, 1221, 1220, 1, 0, 0, 0, 1221, 1222, 1, 0, 0, 0, 1222, 143, 1, 0, 0, 0, 1223, 1224, 3, 160, 80, 0, 1224, 145, 1, 0, 0, 0, 1225, 1234, 5, 106, 0, 0, 1226, 1227, 5, 120, 0, 0, 1227, 1234, 7, 11, 0, 0, 1228, 1229, 5, 108, 0, 0, 1229, 1231, 5, 120, 0, 0, 1230, 1232, 7, 11, 0, 0, 1231, 1230, 1, 0, 0, 0, 1231, 1232, 1, 0, 0, 0, 1232, 1234, 1, 0, 0, 0, 1233, 1225, 1, 0, 0, 0, 1233, 1226, 1, 0, 0, 0, 1233, 1228, 1, 0, 0, 0, 1234, 147, 1, 0, 0, 0, 1235, 1237, 7, 12, 0, 0, 1236, 1235, 1, 0, 0, 0, 1236, 1237, 1, 0, 0, 0, 1237, 1244, 1, 0, 0, 0, 1238, 1245, 3, 146, 73, 0, 1239, 1245, 5, 107, 0, 0, 1240, 1245, 5, 108, 0, 0, 1241, 1245, 5, 109, 0, 0, 1242, 1245, 5, 43, 0, 0, 1243, 1245, 5, 57, 0, 0, 1244, 1238, 1, 0, 0, 0, 1244, 1239, 1, 0, 0, 0, 1244, 1240, 1, 0, 0, 0, 1244, 1241, 1, 0, 0, 0, 1244, 1242, 1, 0, 0, 0, 1244, 1243, 1, 0, 0, 0, 1245, 149, 1, 0, 0, 0, 1246, 1250, 3, 148, 74, 0, 1247, 1250, 5, 110, 0, 0, 1248, 1250, 5, 59, 0, 0, 1249, 1246, 1, 0, 0, 0, 1249, 1247, 1, 0, 0, 0, 1249, 1248, 1, 0, 0, 0, 1250, 151, 1, 0, 0, 0, 1251, 1252, 7, 13, 0, 0, 1252, 153, 1, 0, 0, 0, 1253, 1254, 7, 14, 0, 0, 1254, 155, 1, 0, 0, 0, 1255, 1256, 7, 15, 0, 0, 1256, 157, 1, 0, 0, 0, 1257, 1260, 5, 105, 0, 0, 1258, 1260, 3, 156, 78, 0, 1259, 1257, 1, 0, 0, 0, 1259, 1258, 1, 0, 0, 0, 1260, 159, 1, 0, 0, 0, 1261, 1265, 5, 105, 0, 0, 1262, 1265, 3, 152, 76, 0, 1263, 1265, 3, 154, 77, 0, 1264, 1261, 1, 0, 0, 0, 1264, 1262, 1, 0, 0, 0, 1264, 1263, 1, 0, 0, 0, 1265, 161, 1, 0, 0, 0, 1266, 1267, 3, 166, 83, 0, 1267, 1268, 5, 122, 0, 0, 1268, 1269, 3, 148, 74, 0, 1269, 163, 1, 0, 0, 0, 1270, 1271, 5, 128, 0, 0, 1271, 1272, 3, 160, 80, 0, 1272, 1273, 5, 147, 0, 0, 1273, 165, 1, 0, 0, 0, 1274, 1277, 5, 110, 0, 0, 1275, 1277, 3, 168, 84, 0, 1276, 1274, 1, 0, 0, 0, 1276, 1275, 1, 0, 0, 0, 1277, 167, 1, 0, 0, 0, 1278, 1282, 5, 142, 0, 0, 1279, 1281, 3, 170, 85, 0, 1280, 1279, 1, 0, 0, 0, 1281, 1284, 1, 0, 0, 0, 1282, 1280, 1, 0, 0, 0, 1282, 1283, 1, 0, 0, 0, 1283, 1285, 1, 0, 0, 0, 1284, 1282, 1, 0, 0, 0, 1285, 1286, 5, 144, 0, 0, 1286, 169, 1, 0, 0, 0, 1287, 1288, 5, 157, 0, 0, 1288, 1289, 3, 116, 58, 0, 1289, 1290, 5, 147, 0, 0, 1290, 1293, 1, 0, 0, 0, 1291, 1293, 5, 156, 0, 0, 1292, 1287, 1, 0, 0, 0, 1292, 1291, 1, 0, 0, 0, 1293, 171, 1, 0, 0, 0, 1294, 1298, 5, 143, 0, 0, 1295, 1297, 3, 174, 87, 0, 1296, 1295, 1, 0, 0, 0, 1297, 1300, 1, 0, 0, 0, 1298, 1296, 1, 0, 0, 0, 1298, 1299, 1, 0, 0, 0, 1299, 1301, 1, 0, 0, 0, 1300, 1298, 1, 0, 0, 0, 1301, 1302, 5, 0, 0, 1, 1302, 173, 1, 0, 0, 0, 1303, 1304, 5, 159, 0, 0, 1304, 1305, 3, 116, 58, 0, 1305, 1306, 5, 147, 0, 0, 1306, 1309, 1, 0, 0, 0, 1307, 1309, 5, 158, 0, 0, 1308, 1303, 1, 0, 0, 0, 1308, 1307, 1, 0, 0, 0, 1309, 175, 1, 0, 0, 0, 168, 179, 186, 195, 202, 206, 220, 224, 227, 231, 234, 241, 245, 254, 259, 268, 276, 283, 287, 293, 298, 306, 313, 319, 331, 339, 353, 357, 362, 372, 381, 384, 388, 391, 395, 398, 401, 404, 407, 411, 415, 418, 421, 424, 428, 431, 440, 446, 467, 484, 501, 507, 513, 524, 526, 537, 540, 546, 554, 560, 562, 566, 571, 574, 577, 581, 585, 588, 590, 593, 597, 601, 604, 606, 608, 613, 624, 630, 637, 642, 646, 650, 656, 658, 665, 673, 676, 679, 698, 712, 728, 732, 743, 747, 758, 762, 769, 773, 780, 784, 789, 798, 802, 826, 843, 849, 852, 855, 865, 871, 874, 877, 885, 888, 892, 895, 909, 926, 931, 935, 941, 948, 960, 964, 967, 976, 990, 1029, 1037, 1039, 1041, 1049, 1053, 1057, 1065, 1069, 1078, 1082, 1084, 1094, 1105, 1114, 1121, 1134, 1141, 1145, 1157, 1163, 1166, 1173, 1185, 1191, 1195, 1201, 1208, 1217, 1221, 1231, 1233, 1236, 1244, 1249, 1259, 1264, 1276, 1282, 1292, 1298, 1308] \ No newline at end of file +[4, 1, 159, 1311, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 1, 0, 5, 0, 178, 8, 0, 10, 0, 12, 0, 181, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 3, 1, 187, 8, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 196, 8, 3, 1, 4, 1, 4, 1, 4, 5, 4, 201, 8, 4, 10, 4, 12, 4, 204, 9, 4, 1, 4, 3, 4, 207, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 221, 8, 5, 1, 6, 1, 6, 3, 6, 225, 8, 6, 1, 6, 3, 6, 228, 8, 6, 1, 7, 1, 7, 3, 7, 232, 8, 7, 1, 7, 3, 7, 235, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 242, 8, 8, 1, 8, 1, 8, 3, 8, 246, 8, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 5, 9, 253, 8, 9, 10, 9, 12, 9, 256, 9, 9, 1, 9, 1, 9, 3, 9, 260, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 269, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 277, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 284, 8, 12, 1, 12, 1, 12, 3, 12, 288, 8, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 294, 8, 12, 1, 12, 1, 12, 1, 12, 3, 12, 299, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 307, 8, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 314, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 320, 8, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 3, 16, 332, 8, 16, 1, 17, 1, 17, 1, 18, 1, 18, 5, 18, 338, 8, 18, 10, 18, 12, 18, 341, 9, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 5, 20, 352, 8, 20, 10, 20, 12, 20, 355, 9, 20, 1, 20, 3, 20, 358, 8, 20, 1, 21, 1, 21, 1, 21, 3, 21, 363, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 371, 8, 22, 10, 22, 12, 22, 374, 9, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 382, 8, 23, 1, 24, 3, 24, 385, 8, 24, 1, 24, 1, 24, 3, 24, 389, 8, 24, 1, 24, 3, 24, 392, 8, 24, 1, 24, 1, 24, 3, 24, 396, 8, 24, 1, 24, 3, 24, 399, 8, 24, 1, 24, 3, 24, 402, 8, 24, 1, 24, 3, 24, 405, 8, 24, 1, 24, 3, 24, 408, 8, 24, 1, 24, 1, 24, 3, 24, 412, 8, 24, 1, 24, 1, 24, 3, 24, 416, 8, 24, 1, 24, 3, 24, 419, 8, 24, 1, 24, 3, 24, 422, 8, 24, 1, 24, 3, 24, 425, 8, 24, 1, 24, 1, 24, 3, 24, 429, 8, 24, 1, 24, 3, 24, 432, 8, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 441, 8, 26, 1, 27, 1, 27, 1, 27, 1, 28, 3, 28, 447, 8, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 466, 8, 29, 10, 29, 12, 29, 469, 9, 29, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 3, 32, 485, 8, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 502, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 508, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 514, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 525, 8, 36, 3, 36, 527, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 3, 39, 538, 8, 39, 1, 39, 3, 39, 541, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 547, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 3, 39, 555, 8, 39, 1, 39, 1, 39, 1, 39, 1, 39, 5, 39, 561, 8, 39, 10, 39, 12, 39, 564, 9, 39, 1, 40, 3, 40, 567, 8, 40, 1, 40, 1, 40, 1, 40, 3, 40, 572, 8, 40, 1, 40, 3, 40, 575, 8, 40, 1, 40, 3, 40, 578, 8, 40, 1, 40, 1, 40, 3, 40, 582, 8, 40, 1, 40, 1, 40, 3, 40, 586, 8, 40, 1, 40, 3, 40, 589, 8, 40, 3, 40, 591, 8, 40, 1, 40, 3, 40, 594, 8, 40, 1, 40, 1, 40, 3, 40, 598, 8, 40, 1, 40, 1, 40, 3, 40, 602, 8, 40, 1, 40, 3, 40, 605, 8, 40, 3, 40, 607, 8, 40, 3, 40, 609, 8, 40, 1, 41, 1, 41, 1, 41, 3, 41, 614, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 625, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 631, 8, 43, 1, 44, 1, 44, 1, 44, 5, 44, 636, 8, 44, 10, 44, 12, 44, 639, 9, 44, 1, 45, 1, 45, 3, 45, 643, 8, 45, 1, 45, 1, 45, 3, 45, 647, 8, 45, 1, 45, 1, 45, 3, 45, 651, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 657, 8, 46, 3, 46, 659, 8, 46, 1, 47, 1, 47, 1, 47, 5, 47, 664, 8, 47, 10, 47, 12, 47, 667, 9, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 3, 49, 674, 8, 49, 1, 49, 3, 49, 677, 8, 49, 1, 49, 3, 49, 680, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 3, 53, 699, 8, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 713, 8, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 727, 8, 56, 10, 56, 12, 56, 730, 9, 56, 1, 56, 3, 56, 733, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 742, 8, 56, 10, 56, 12, 56, 745, 9, 56, 1, 56, 3, 56, 748, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 757, 8, 56, 10, 56, 12, 56, 760, 9, 56, 1, 56, 3, 56, 763, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 770, 8, 56, 1, 56, 1, 56, 3, 56, 774, 8, 56, 1, 57, 1, 57, 1, 57, 5, 57, 779, 8, 57, 10, 57, 12, 57, 782, 9, 57, 1, 57, 3, 57, 785, 8, 57, 1, 58, 1, 58, 1, 58, 3, 58, 790, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 4, 58, 797, 8, 58, 11, 58, 12, 58, 798, 1, 58, 1, 58, 3, 58, 803, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 827, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 844, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 850, 8, 58, 1, 58, 3, 58, 853, 8, 58, 1, 58, 3, 58, 856, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 866, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 872, 8, 58, 1, 58, 3, 58, 875, 8, 58, 1, 58, 3, 58, 878, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 886, 8, 58, 1, 58, 3, 58, 889, 8, 58, 1, 58, 1, 58, 3, 58, 893, 8, 58, 1, 58, 3, 58, 896, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 910, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 927, 8, 58, 1, 58, 1, 58, 1, 58, 3, 58, 932, 8, 58, 1, 58, 1, 58, 3, 58, 936, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 942, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 949, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 961, 8, 58, 1, 58, 1, 58, 3, 58, 965, 8, 58, 1, 58, 3, 58, 968, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 977, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 991, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 1030, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 1038, 8, 58, 5, 58, 1040, 8, 58, 10, 58, 12, 58, 1043, 9, 58, 1, 59, 1, 59, 1, 59, 5, 59, 1048, 8, 59, 10, 59, 12, 59, 1051, 9, 59, 1, 59, 3, 59, 1054, 8, 59, 1, 60, 1, 60, 3, 60, 1058, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 1064, 8, 61, 10, 61, 12, 61, 1067, 9, 61, 1, 61, 3, 61, 1070, 8, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 1077, 8, 61, 10, 61, 12, 61, 1080, 9, 61, 1, 61, 3, 61, 1083, 8, 61, 3, 61, 1085, 8, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 5, 62, 1093, 8, 62, 10, 62, 12, 62, 1096, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 5, 62, 1104, 8, 62, 10, 62, 12, 62, 1107, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 1115, 8, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 1122, 8, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 1135, 8, 63, 1, 64, 1, 64, 1, 64, 5, 64, 1140, 8, 64, 10, 64, 12, 64, 1143, 9, 64, 1, 64, 3, 64, 1146, 8, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 1158, 8, 65, 1, 66, 1, 66, 1, 66, 1, 66, 3, 66, 1164, 8, 66, 1, 66, 3, 66, 1167, 8, 66, 1, 67, 1, 67, 1, 67, 5, 67, 1172, 8, 67, 10, 67, 12, 67, 1175, 9, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1186, 8, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 1192, 8, 68, 5, 68, 1194, 8, 68, 10, 68, 12, 68, 1197, 9, 68, 1, 69, 1, 69, 1, 69, 3, 69, 1202, 8, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 3, 70, 1209, 8, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 5, 71, 1216, 8, 71, 10, 71, 12, 71, 1219, 9, 71, 1, 71, 3, 71, 1222, 8, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 3, 73, 1232, 8, 73, 3, 73, 1234, 8, 73, 1, 74, 3, 74, 1237, 8, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 3, 74, 1245, 8, 74, 1, 75, 1, 75, 1, 75, 3, 75, 1250, 8, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 3, 79, 1260, 8, 79, 1, 80, 1, 80, 1, 80, 3, 80, 1265, 8, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 3, 83, 1277, 8, 83, 1, 84, 1, 84, 5, 84, 1281, 8, 84, 10, 84, 12, 84, 1284, 9, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 3, 85, 1293, 8, 85, 1, 86, 1, 86, 5, 86, 1297, 8, 86, 10, 86, 12, 86, 1300, 9, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 3, 87, 1309, 8, 87, 1, 87, 0, 3, 78, 116, 136, 88, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 0, 16, 2, 0, 18, 18, 74, 74, 2, 0, 44, 44, 51, 51, 3, 0, 1, 1, 4, 4, 8, 8, 4, 0, 1, 1, 3, 4, 8, 8, 80, 80, 2, 0, 51, 51, 73, 73, 2, 0, 1, 1, 4, 4, 2, 0, 7, 7, 22, 23, 2, 0, 30, 30, 49, 49, 2, 0, 71, 71, 76, 76, 3, 0, 10, 10, 50, 50, 90, 90, 2, 0, 41, 41, 53, 53, 1, 0, 107, 108, 2, 0, 118, 118, 139, 139, 7, 0, 21, 21, 38, 38, 55, 56, 70, 70, 78, 78, 97, 97, 103, 103, 16, 0, 1, 13, 15, 20, 22, 28, 30, 30, 32, 37, 39, 42, 44, 51, 53, 54, 58, 58, 60, 69, 71, 77, 79, 83, 85, 92, 94, 96, 98, 99, 101, 102, 4, 0, 20, 20, 30, 30, 39, 39, 48, 48, 1479, 0, 179, 1, 0, 0, 0, 2, 186, 1, 0, 0, 0, 4, 188, 1, 0, 0, 0, 6, 190, 1, 0, 0, 0, 8, 197, 1, 0, 0, 0, 10, 220, 1, 0, 0, 0, 12, 222, 1, 0, 0, 0, 14, 229, 1, 0, 0, 0, 16, 236, 1, 0, 0, 0, 18, 249, 1, 0, 0, 0, 20, 261, 1, 0, 0, 0, 22, 270, 1, 0, 0, 0, 24, 278, 1, 0, 0, 0, 26, 300, 1, 0, 0, 0, 28, 315, 1, 0, 0, 0, 30, 324, 1, 0, 0, 0, 32, 329, 1, 0, 0, 0, 34, 333, 1, 0, 0, 0, 36, 335, 1, 0, 0, 0, 38, 344, 1, 0, 0, 0, 40, 348, 1, 0, 0, 0, 42, 362, 1, 0, 0, 0, 44, 366, 1, 0, 0, 0, 46, 381, 1, 0, 0, 0, 48, 384, 1, 0, 0, 0, 50, 433, 1, 0, 0, 0, 52, 436, 1, 0, 0, 0, 54, 442, 1, 0, 0, 0, 56, 446, 1, 0, 0, 0, 58, 452, 1, 0, 0, 0, 60, 470, 1, 0, 0, 0, 62, 473, 1, 0, 0, 0, 64, 476, 1, 0, 0, 0, 66, 486, 1, 0, 0, 0, 68, 489, 1, 0, 0, 0, 70, 493, 1, 0, 0, 0, 72, 526, 1, 0, 0, 0, 74, 528, 1, 0, 0, 0, 76, 531, 1, 0, 0, 0, 78, 546, 1, 0, 0, 0, 80, 608, 1, 0, 0, 0, 82, 613, 1, 0, 0, 0, 84, 624, 1, 0, 0, 0, 86, 626, 1, 0, 0, 0, 88, 632, 1, 0, 0, 0, 90, 640, 1, 0, 0, 0, 92, 658, 1, 0, 0, 0, 94, 660, 1, 0, 0, 0, 96, 668, 1, 0, 0, 0, 98, 673, 1, 0, 0, 0, 100, 681, 1, 0, 0, 0, 102, 685, 1, 0, 0, 0, 104, 689, 1, 0, 0, 0, 106, 698, 1, 0, 0, 0, 108, 712, 1, 0, 0, 0, 110, 714, 1, 0, 0, 0, 112, 773, 1, 0, 0, 0, 114, 775, 1, 0, 0, 0, 116, 935, 1, 0, 0, 0, 118, 1044, 1, 0, 0, 0, 120, 1057, 1, 0, 0, 0, 122, 1084, 1, 0, 0, 0, 124, 1121, 1, 0, 0, 0, 126, 1134, 1, 0, 0, 0, 128, 1136, 1, 0, 0, 0, 130, 1157, 1, 0, 0, 0, 132, 1166, 1, 0, 0, 0, 134, 1168, 1, 0, 0, 0, 136, 1185, 1, 0, 0, 0, 138, 1198, 1, 0, 0, 0, 140, 1208, 1, 0, 0, 0, 142, 1212, 1, 0, 0, 0, 144, 1223, 1, 0, 0, 0, 146, 1233, 1, 0, 0, 0, 148, 1236, 1, 0, 0, 0, 150, 1249, 1, 0, 0, 0, 152, 1251, 1, 0, 0, 0, 154, 1253, 1, 0, 0, 0, 156, 1255, 1, 0, 0, 0, 158, 1259, 1, 0, 0, 0, 160, 1264, 1, 0, 0, 0, 162, 1266, 1, 0, 0, 0, 164, 1270, 1, 0, 0, 0, 166, 1276, 1, 0, 0, 0, 168, 1278, 1, 0, 0, 0, 170, 1292, 1, 0, 0, 0, 172, 1294, 1, 0, 0, 0, 174, 1308, 1, 0, 0, 0, 176, 178, 3, 2, 1, 0, 177, 176, 1, 0, 0, 0, 178, 181, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 182, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 182, 183, 5, 0, 0, 1, 183, 1, 1, 0, 0, 0, 184, 187, 3, 6, 3, 0, 185, 187, 3, 10, 5, 0, 186, 184, 1, 0, 0, 0, 186, 185, 1, 0, 0, 0, 187, 3, 1, 0, 0, 0, 188, 189, 3, 116, 58, 0, 189, 5, 1, 0, 0, 0, 190, 191, 5, 52, 0, 0, 191, 195, 3, 160, 80, 0, 192, 193, 5, 115, 0, 0, 193, 194, 5, 122, 0, 0, 194, 196, 3, 4, 2, 0, 195, 192, 1, 0, 0, 0, 195, 196, 1, 0, 0, 0, 196, 7, 1, 0, 0, 0, 197, 202, 3, 160, 80, 0, 198, 199, 5, 116, 0, 0, 199, 201, 3, 160, 80, 0, 200, 198, 1, 0, 0, 0, 201, 204, 1, 0, 0, 0, 202, 200, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 203, 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 205, 207, 5, 116, 0, 0, 206, 205, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 9, 1, 0, 0, 0, 208, 221, 3, 12, 6, 0, 209, 221, 3, 14, 7, 0, 210, 221, 3, 18, 9, 0, 211, 221, 3, 20, 10, 0, 212, 221, 3, 22, 11, 0, 213, 221, 3, 26, 13, 0, 214, 221, 3, 24, 12, 0, 215, 221, 3, 28, 14, 0, 216, 221, 3, 30, 15, 0, 217, 221, 3, 36, 18, 0, 218, 221, 3, 32, 16, 0, 219, 221, 3, 34, 17, 0, 220, 208, 1, 0, 0, 0, 220, 209, 1, 0, 0, 0, 220, 210, 1, 0, 0, 0, 220, 211, 1, 0, 0, 0, 220, 212, 1, 0, 0, 0, 220, 213, 1, 0, 0, 0, 220, 214, 1, 0, 0, 0, 220, 215, 1, 0, 0, 0, 220, 216, 1, 0, 0, 0, 220, 217, 1, 0, 0, 0, 220, 218, 1, 0, 0, 0, 220, 219, 1, 0, 0, 0, 221, 11, 1, 0, 0, 0, 222, 224, 5, 72, 0, 0, 223, 225, 3, 4, 2, 0, 224, 223, 1, 0, 0, 0, 224, 225, 1, 0, 0, 0, 225, 227, 1, 0, 0, 0, 226, 228, 5, 150, 0, 0, 227, 226, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 13, 1, 0, 0, 0, 229, 231, 5, 84, 0, 0, 230, 232, 3, 4, 2, 0, 231, 230, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 234, 1, 0, 0, 0, 233, 235, 5, 150, 0, 0, 234, 233, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 15, 1, 0, 0, 0, 236, 245, 5, 14, 0, 0, 237, 238, 5, 130, 0, 0, 238, 241, 3, 160, 80, 0, 239, 240, 5, 115, 0, 0, 240, 242, 3, 160, 80, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 243, 1, 0, 0, 0, 243, 244, 5, 149, 0, 0, 244, 246, 1, 0, 0, 0, 245, 237, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 248, 3, 36, 18, 0, 248, 17, 1, 0, 0, 0, 249, 250, 5, 93, 0, 0, 250, 254, 3, 36, 18, 0, 251, 253, 3, 16, 8, 0, 252, 251, 1, 0, 0, 0, 253, 256, 1, 0, 0, 0, 254, 252, 1, 0, 0, 0, 254, 255, 1, 0, 0, 0, 255, 259, 1, 0, 0, 0, 256, 254, 1, 0, 0, 0, 257, 258, 5, 29, 0, 0, 258, 260, 3, 36, 18, 0, 259, 257, 1, 0, 0, 0, 259, 260, 1, 0, 0, 0, 260, 19, 1, 0, 0, 0, 261, 262, 5, 40, 0, 0, 262, 263, 5, 130, 0, 0, 263, 264, 3, 4, 2, 0, 264, 265, 5, 149, 0, 0, 265, 268, 3, 10, 5, 0, 266, 267, 5, 25, 0, 0, 267, 269, 3, 10, 5, 0, 268, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 21, 1, 0, 0, 0, 270, 271, 5, 100, 0, 0, 271, 272, 5, 130, 0, 0, 272, 273, 3, 4, 2, 0, 273, 274, 5, 149, 0, 0, 274, 276, 3, 10, 5, 0, 275, 277, 5, 150, 0, 0, 276, 275, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 23, 1, 0, 0, 0, 278, 279, 5, 33, 0, 0, 279, 283, 5, 130, 0, 0, 280, 284, 3, 6, 3, 0, 281, 284, 3, 30, 15, 0, 282, 284, 3, 4, 2, 0, 283, 280, 1, 0, 0, 0, 283, 281, 1, 0, 0, 0, 283, 282, 1, 0, 0, 0, 283, 284, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287, 5, 150, 0, 0, 286, 288, 3, 4, 2, 0, 287, 286, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 293, 5, 150, 0, 0, 290, 294, 3, 6, 3, 0, 291, 294, 3, 30, 15, 0, 292, 294, 3, 4, 2, 0, 293, 290, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 293, 292, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 296, 5, 149, 0, 0, 296, 298, 3, 10, 5, 0, 297, 299, 5, 150, 0, 0, 298, 297, 1, 0, 0, 0, 298, 299, 1, 0, 0, 0, 299, 25, 1, 0, 0, 0, 300, 301, 5, 33, 0, 0, 301, 302, 5, 130, 0, 0, 302, 303, 5, 52, 0, 0, 303, 306, 3, 160, 80, 0, 304, 305, 5, 116, 0, 0, 305, 307, 3, 160, 80, 0, 306, 304, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 309, 5, 42, 0, 0, 309, 310, 3, 4, 2, 0, 310, 311, 5, 149, 0, 0, 311, 313, 3, 10, 5, 0, 312, 314, 5, 150, 0, 0, 313, 312, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 27, 1, 0, 0, 0, 315, 316, 5, 31, 0, 0, 316, 317, 3, 160, 80, 0, 317, 319, 5, 130, 0, 0, 318, 320, 3, 8, 4, 0, 319, 318, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 322, 5, 149, 0, 0, 322, 323, 3, 36, 18, 0, 323, 29, 1, 0, 0, 0, 324, 325, 3, 4, 2, 0, 325, 326, 5, 115, 0, 0, 326, 327, 5, 122, 0, 0, 327, 328, 3, 4, 2, 0, 328, 31, 1, 0, 0, 0, 329, 331, 3, 4, 2, 0, 330, 332, 5, 150, 0, 0, 331, 330, 1, 0, 0, 0, 331, 332, 1, 0, 0, 0, 332, 33, 1, 0, 0, 0, 333, 334, 5, 150, 0, 0, 334, 35, 1, 0, 0, 0, 335, 339, 5, 128, 0, 0, 336, 338, 3, 2, 1, 0, 337, 336, 1, 0, 0, 0, 338, 341, 1, 0, 0, 0, 339, 337, 1, 0, 0, 0, 339, 340, 1, 0, 0, 0, 340, 342, 1, 0, 0, 0, 341, 339, 1, 0, 0, 0, 342, 343, 5, 147, 0, 0, 343, 37, 1, 0, 0, 0, 344, 345, 3, 4, 2, 0, 345, 346, 5, 115, 0, 0, 346, 347, 3, 4, 2, 0, 347, 39, 1, 0, 0, 0, 348, 353, 3, 38, 19, 0, 349, 350, 5, 116, 0, 0, 350, 352, 3, 38, 19, 0, 351, 349, 1, 0, 0, 0, 352, 355, 1, 0, 0, 0, 353, 351, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 357, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, 358, 5, 116, 0, 0, 357, 356, 1, 0, 0, 0, 357, 358, 1, 0, 0, 0, 358, 41, 1, 0, 0, 0, 359, 363, 3, 44, 22, 0, 360, 363, 3, 48, 24, 0, 361, 363, 3, 124, 62, 0, 362, 359, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 362, 361, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 365, 5, 0, 0, 1, 365, 43, 1, 0, 0, 0, 366, 372, 3, 46, 23, 0, 367, 368, 5, 95, 0, 0, 368, 369, 5, 1, 0, 0, 369, 371, 3, 46, 23, 0, 370, 367, 1, 0, 0, 0, 371, 374, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 372, 373, 1, 0, 0, 0, 373, 45, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 375, 382, 3, 48, 24, 0, 376, 377, 5, 130, 0, 0, 377, 378, 3, 44, 22, 0, 378, 379, 5, 149, 0, 0, 379, 382, 1, 0, 0, 0, 380, 382, 3, 164, 82, 0, 381, 375, 1, 0, 0, 0, 381, 376, 1, 0, 0, 0, 381, 380, 1, 0, 0, 0, 382, 47, 1, 0, 0, 0, 383, 385, 3, 50, 25, 0, 384, 383, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 386, 1, 0, 0, 0, 386, 388, 5, 79, 0, 0, 387, 389, 5, 24, 0, 0, 388, 387, 1, 0, 0, 0, 388, 389, 1, 0, 0, 0, 389, 391, 1, 0, 0, 0, 390, 392, 3, 52, 26, 0, 391, 390, 1, 0, 0, 0, 391, 392, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 395, 3, 114, 57, 0, 394, 396, 3, 54, 27, 0, 395, 394, 1, 0, 0, 0, 395, 396, 1, 0, 0, 0, 396, 398, 1, 0, 0, 0, 397, 399, 3, 56, 28, 0, 398, 397, 1, 0, 0, 0, 398, 399, 1, 0, 0, 0, 399, 401, 1, 0, 0, 0, 400, 402, 3, 60, 30, 0, 401, 400, 1, 0, 0, 0, 401, 402, 1, 0, 0, 0, 402, 404, 1, 0, 0, 0, 403, 405, 3, 62, 31, 0, 404, 403, 1, 0, 0, 0, 404, 405, 1, 0, 0, 0, 405, 407, 1, 0, 0, 0, 406, 408, 3, 64, 32, 0, 407, 406, 1, 0, 0, 0, 407, 408, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 410, 5, 102, 0, 0, 410, 412, 7, 0, 0, 0, 411, 409, 1, 0, 0, 0, 411, 412, 1, 0, 0, 0, 412, 415, 1, 0, 0, 0, 413, 414, 5, 102, 0, 0, 414, 416, 5, 89, 0, 0, 415, 413, 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 418, 1, 0, 0, 0, 417, 419, 3, 66, 33, 0, 418, 417, 1, 0, 0, 0, 418, 419, 1, 0, 0, 0, 419, 421, 1, 0, 0, 0, 420, 422, 3, 58, 29, 0, 421, 420, 1, 0, 0, 0, 421, 422, 1, 0, 0, 0, 422, 424, 1, 0, 0, 0, 423, 425, 3, 68, 34, 0, 424, 423, 1, 0, 0, 0, 424, 425, 1, 0, 0, 0, 425, 428, 1, 0, 0, 0, 426, 429, 3, 72, 36, 0, 427, 429, 3, 74, 37, 0, 428, 426, 1, 0, 0, 0, 428, 427, 1, 0, 0, 0, 428, 429, 1, 0, 0, 0, 429, 431, 1, 0, 0, 0, 430, 432, 3, 76, 38, 0, 431, 430, 1, 0, 0, 0, 431, 432, 1, 0, 0, 0, 432, 49, 1, 0, 0, 0, 433, 434, 5, 102, 0, 0, 434, 435, 3, 128, 64, 0, 435, 51, 1, 0, 0, 0, 436, 437, 5, 88, 0, 0, 437, 440, 5, 108, 0, 0, 438, 439, 5, 102, 0, 0, 439, 441, 5, 85, 0, 0, 440, 438, 1, 0, 0, 0, 440, 441, 1, 0, 0, 0, 441, 53, 1, 0, 0, 0, 442, 443, 5, 34, 0, 0, 443, 444, 3, 78, 39, 0, 444, 55, 1, 0, 0, 0, 445, 447, 7, 1, 0, 0, 446, 445, 1, 0, 0, 0, 446, 447, 1, 0, 0, 0, 447, 448, 1, 0, 0, 0, 448, 449, 5, 5, 0, 0, 449, 450, 5, 47, 0, 0, 450, 451, 3, 114, 57, 0, 451, 57, 1, 0, 0, 0, 452, 453, 5, 101, 0, 0, 453, 454, 3, 160, 80, 0, 454, 455, 5, 6, 0, 0, 455, 456, 5, 130, 0, 0, 456, 457, 3, 98, 49, 0, 457, 467, 5, 149, 0, 0, 458, 459, 5, 116, 0, 0, 459, 460, 3, 160, 80, 0, 460, 461, 5, 6, 0, 0, 461, 462, 5, 130, 0, 0, 462, 463, 3, 98, 49, 0, 463, 464, 5, 149, 0, 0, 464, 466, 1, 0, 0, 0, 465, 458, 1, 0, 0, 0, 466, 469, 1, 0, 0, 0, 467, 465, 1, 0, 0, 0, 467, 468, 1, 0, 0, 0, 468, 59, 1, 0, 0, 0, 469, 467, 1, 0, 0, 0, 470, 471, 5, 69, 0, 0, 471, 472, 3, 116, 58, 0, 472, 61, 1, 0, 0, 0, 473, 474, 5, 99, 0, 0, 474, 475, 3, 116, 58, 0, 475, 63, 1, 0, 0, 0, 476, 477, 5, 36, 0, 0, 477, 484, 5, 11, 0, 0, 478, 479, 7, 0, 0, 0, 479, 480, 5, 130, 0, 0, 480, 481, 3, 114, 57, 0, 481, 482, 5, 149, 0, 0, 482, 485, 1, 0, 0, 0, 483, 485, 3, 114, 57, 0, 484, 478, 1, 0, 0, 0, 484, 483, 1, 0, 0, 0, 485, 65, 1, 0, 0, 0, 486, 487, 5, 37, 0, 0, 487, 488, 3, 116, 58, 0, 488, 67, 1, 0, 0, 0, 489, 490, 5, 64, 0, 0, 490, 491, 5, 11, 0, 0, 491, 492, 3, 88, 44, 0, 492, 69, 1, 0, 0, 0, 493, 494, 5, 64, 0, 0, 494, 495, 5, 11, 0, 0, 495, 496, 3, 114, 57, 0, 496, 71, 1, 0, 0, 0, 497, 498, 5, 54, 0, 0, 498, 501, 3, 116, 58, 0, 499, 500, 5, 116, 0, 0, 500, 502, 3, 116, 58, 0, 501, 499, 1, 0, 0, 0, 501, 502, 1, 0, 0, 0, 502, 507, 1, 0, 0, 0, 503, 504, 5, 102, 0, 0, 504, 508, 5, 85, 0, 0, 505, 506, 5, 11, 0, 0, 506, 508, 3, 114, 57, 0, 507, 503, 1, 0, 0, 0, 507, 505, 1, 0, 0, 0, 507, 508, 1, 0, 0, 0, 508, 527, 1, 0, 0, 0, 509, 510, 5, 54, 0, 0, 510, 513, 3, 116, 58, 0, 511, 512, 5, 102, 0, 0, 512, 514, 5, 85, 0, 0, 513, 511, 1, 0, 0, 0, 513, 514, 1, 0, 0, 0, 514, 515, 1, 0, 0, 0, 515, 516, 5, 61, 0, 0, 516, 517, 3, 116, 58, 0, 517, 527, 1, 0, 0, 0, 518, 519, 5, 54, 0, 0, 519, 520, 3, 116, 58, 0, 520, 521, 5, 61, 0, 0, 521, 524, 3, 116, 58, 0, 522, 523, 5, 11, 0, 0, 523, 525, 3, 114, 57, 0, 524, 522, 1, 0, 0, 0, 524, 525, 1, 0, 0, 0, 525, 527, 1, 0, 0, 0, 526, 497, 1, 0, 0, 0, 526, 509, 1, 0, 0, 0, 526, 518, 1, 0, 0, 0, 527, 73, 1, 0, 0, 0, 528, 529, 5, 61, 0, 0, 529, 530, 3, 116, 58, 0, 530, 75, 1, 0, 0, 0, 531, 532, 5, 81, 0, 0, 532, 533, 3, 94, 47, 0, 533, 77, 1, 0, 0, 0, 534, 535, 6, 39, -1, 0, 535, 537, 3, 136, 68, 0, 536, 538, 5, 28, 0, 0, 537, 536, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 540, 1, 0, 0, 0, 539, 541, 3, 86, 43, 0, 540, 539, 1, 0, 0, 0, 540, 541, 1, 0, 0, 0, 541, 547, 1, 0, 0, 0, 542, 543, 5, 130, 0, 0, 543, 544, 3, 78, 39, 0, 544, 545, 5, 149, 0, 0, 545, 547, 1, 0, 0, 0, 546, 534, 1, 0, 0, 0, 546, 542, 1, 0, 0, 0, 547, 562, 1, 0, 0, 0, 548, 549, 10, 3, 0, 0, 549, 550, 3, 82, 41, 0, 550, 551, 3, 78, 39, 4, 551, 561, 1, 0, 0, 0, 552, 554, 10, 4, 0, 0, 553, 555, 3, 80, 40, 0, 554, 553, 1, 0, 0, 0, 554, 555, 1, 0, 0, 0, 555, 556, 1, 0, 0, 0, 556, 557, 5, 47, 0, 0, 557, 558, 3, 78, 39, 0, 558, 559, 3, 84, 42, 0, 559, 561, 1, 0, 0, 0, 560, 548, 1, 0, 0, 0, 560, 552, 1, 0, 0, 0, 561, 564, 1, 0, 0, 0, 562, 560, 1, 0, 0, 0, 562, 563, 1, 0, 0, 0, 563, 79, 1, 0, 0, 0, 564, 562, 1, 0, 0, 0, 565, 567, 7, 2, 0, 0, 566, 565, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 568, 1, 0, 0, 0, 568, 575, 5, 44, 0, 0, 569, 571, 5, 44, 0, 0, 570, 572, 7, 2, 0, 0, 571, 570, 1, 0, 0, 0, 571, 572, 1, 0, 0, 0, 572, 575, 1, 0, 0, 0, 573, 575, 7, 2, 0, 0, 574, 566, 1, 0, 0, 0, 574, 569, 1, 0, 0, 0, 574, 573, 1, 0, 0, 0, 575, 609, 1, 0, 0, 0, 576, 578, 7, 3, 0, 0, 577, 576, 1, 0, 0, 0, 577, 578, 1, 0, 0, 0, 578, 579, 1, 0, 0, 0, 579, 581, 7, 4, 0, 0, 580, 582, 5, 65, 0, 0, 581, 580, 1, 0, 0, 0, 581, 582, 1, 0, 0, 0, 582, 591, 1, 0, 0, 0, 583, 585, 7, 4, 0, 0, 584, 586, 5, 65, 0, 0, 585, 584, 1, 0, 0, 0, 585, 586, 1, 0, 0, 0, 586, 588, 1, 0, 0, 0, 587, 589, 7, 3, 0, 0, 588, 587, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 591, 1, 0, 0, 0, 590, 577, 1, 0, 0, 0, 590, 583, 1, 0, 0, 0, 591, 609, 1, 0, 0, 0, 592, 594, 7, 5, 0, 0, 593, 592, 1, 0, 0, 0, 593, 594, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, 595, 597, 5, 35, 0, 0, 596, 598, 5, 65, 0, 0, 597, 596, 1, 0, 0, 0, 597, 598, 1, 0, 0, 0, 598, 607, 1, 0, 0, 0, 599, 601, 5, 35, 0, 0, 600, 602, 5, 65, 0, 0, 601, 600, 1, 0, 0, 0, 601, 602, 1, 0, 0, 0, 602, 604, 1, 0, 0, 0, 603, 605, 7, 5, 0, 0, 604, 603, 1, 0, 0, 0, 604, 605, 1, 0, 0, 0, 605, 607, 1, 0, 0, 0, 606, 593, 1, 0, 0, 0, 606, 599, 1, 0, 0, 0, 607, 609, 1, 0, 0, 0, 608, 574, 1, 0, 0, 0, 608, 590, 1, 0, 0, 0, 608, 606, 1, 0, 0, 0, 609, 81, 1, 0, 0, 0, 610, 611, 5, 17, 0, 0, 611, 614, 5, 47, 0, 0, 612, 614, 5, 116, 0, 0, 613, 610, 1, 0, 0, 0, 613, 612, 1, 0, 0, 0, 614, 83, 1, 0, 0, 0, 615, 616, 5, 62, 0, 0, 616, 625, 3, 114, 57, 0, 617, 618, 5, 96, 0, 0, 618, 619, 5, 130, 0, 0, 619, 620, 3, 114, 57, 0, 620, 621, 5, 149, 0, 0, 621, 625, 1, 0, 0, 0, 622, 623, 5, 96, 0, 0, 623, 625, 3, 114, 57, 0, 624, 615, 1, 0, 0, 0, 624, 617, 1, 0, 0, 0, 624, 622, 1, 0, 0, 0, 625, 85, 1, 0, 0, 0, 626, 627, 5, 77, 0, 0, 627, 630, 3, 92, 46, 0, 628, 629, 5, 61, 0, 0, 629, 631, 3, 92, 46, 0, 630, 628, 1, 0, 0, 0, 630, 631, 1, 0, 0, 0, 631, 87, 1, 0, 0, 0, 632, 637, 3, 90, 45, 0, 633, 634, 5, 116, 0, 0, 634, 636, 3, 90, 45, 0, 635, 633, 1, 0, 0, 0, 636, 639, 1, 0, 0, 0, 637, 635, 1, 0, 0, 0, 637, 638, 1, 0, 0, 0, 638, 89, 1, 0, 0, 0, 639, 637, 1, 0, 0, 0, 640, 642, 3, 116, 58, 0, 641, 643, 7, 6, 0, 0, 642, 641, 1, 0, 0, 0, 642, 643, 1, 0, 0, 0, 643, 646, 1, 0, 0, 0, 644, 645, 5, 60, 0, 0, 645, 647, 7, 7, 0, 0, 646, 644, 1, 0, 0, 0, 646, 647, 1, 0, 0, 0, 647, 650, 1, 0, 0, 0, 648, 649, 5, 16, 0, 0, 649, 651, 5, 110, 0, 0, 650, 648, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 91, 1, 0, 0, 0, 652, 659, 3, 164, 82, 0, 653, 656, 3, 148, 74, 0, 654, 655, 5, 151, 0, 0, 655, 657, 3, 148, 74, 0, 656, 654, 1, 0, 0, 0, 656, 657, 1, 0, 0, 0, 657, 659, 1, 0, 0, 0, 658, 652, 1, 0, 0, 0, 658, 653, 1, 0, 0, 0, 659, 93, 1, 0, 0, 0, 660, 665, 3, 96, 48, 0, 661, 662, 5, 116, 0, 0, 662, 664, 3, 96, 48, 0, 663, 661, 1, 0, 0, 0, 664, 667, 1, 0, 0, 0, 665, 663, 1, 0, 0, 0, 665, 666, 1, 0, 0, 0, 666, 95, 1, 0, 0, 0, 667, 665, 1, 0, 0, 0, 668, 669, 3, 160, 80, 0, 669, 670, 5, 122, 0, 0, 670, 671, 3, 150, 75, 0, 671, 97, 1, 0, 0, 0, 672, 674, 3, 100, 50, 0, 673, 672, 1, 0, 0, 0, 673, 674, 1, 0, 0, 0, 674, 676, 1, 0, 0, 0, 675, 677, 3, 102, 51, 0, 676, 675, 1, 0, 0, 0, 676, 677, 1, 0, 0, 0, 677, 679, 1, 0, 0, 0, 678, 680, 3, 104, 52, 0, 679, 678, 1, 0, 0, 0, 679, 680, 1, 0, 0, 0, 680, 99, 1, 0, 0, 0, 681, 682, 5, 67, 0, 0, 682, 683, 5, 11, 0, 0, 683, 684, 3, 114, 57, 0, 684, 101, 1, 0, 0, 0, 685, 686, 5, 64, 0, 0, 686, 687, 5, 11, 0, 0, 687, 688, 3, 88, 44, 0, 688, 103, 1, 0, 0, 0, 689, 690, 7, 8, 0, 0, 690, 691, 3, 106, 53, 0, 691, 105, 1, 0, 0, 0, 692, 699, 3, 108, 54, 0, 693, 694, 5, 9, 0, 0, 694, 695, 3, 108, 54, 0, 695, 696, 5, 2, 0, 0, 696, 697, 3, 108, 54, 0, 697, 699, 1, 0, 0, 0, 698, 692, 1, 0, 0, 0, 698, 693, 1, 0, 0, 0, 699, 107, 1, 0, 0, 0, 700, 701, 5, 19, 0, 0, 701, 713, 5, 75, 0, 0, 702, 703, 5, 94, 0, 0, 703, 713, 5, 68, 0, 0, 704, 705, 5, 94, 0, 0, 705, 713, 5, 32, 0, 0, 706, 707, 3, 148, 74, 0, 707, 708, 5, 68, 0, 0, 708, 713, 1, 0, 0, 0, 709, 710, 3, 148, 74, 0, 710, 711, 5, 32, 0, 0, 711, 713, 1, 0, 0, 0, 712, 700, 1, 0, 0, 0, 712, 702, 1, 0, 0, 0, 712, 704, 1, 0, 0, 0, 712, 706, 1, 0, 0, 0, 712, 709, 1, 0, 0, 0, 713, 109, 1, 0, 0, 0, 714, 715, 3, 116, 58, 0, 715, 716, 5, 0, 0, 1, 716, 111, 1, 0, 0, 0, 717, 774, 3, 160, 80, 0, 718, 719, 3, 160, 80, 0, 719, 720, 5, 130, 0, 0, 720, 721, 3, 160, 80, 0, 721, 728, 3, 112, 56, 0, 722, 723, 5, 116, 0, 0, 723, 724, 3, 160, 80, 0, 724, 725, 3, 112, 56, 0, 725, 727, 1, 0, 0, 0, 726, 722, 1, 0, 0, 0, 727, 730, 1, 0, 0, 0, 728, 726, 1, 0, 0, 0, 728, 729, 1, 0, 0, 0, 729, 732, 1, 0, 0, 0, 730, 728, 1, 0, 0, 0, 731, 733, 5, 116, 0, 0, 732, 731, 1, 0, 0, 0, 732, 733, 1, 0, 0, 0, 733, 734, 1, 0, 0, 0, 734, 735, 5, 149, 0, 0, 735, 774, 1, 0, 0, 0, 736, 737, 3, 160, 80, 0, 737, 738, 5, 130, 0, 0, 738, 743, 3, 162, 81, 0, 739, 740, 5, 116, 0, 0, 740, 742, 3, 162, 81, 0, 741, 739, 1, 0, 0, 0, 742, 745, 1, 0, 0, 0, 743, 741, 1, 0, 0, 0, 743, 744, 1, 0, 0, 0, 744, 747, 1, 0, 0, 0, 745, 743, 1, 0, 0, 0, 746, 748, 5, 116, 0, 0, 747, 746, 1, 0, 0, 0, 747, 748, 1, 0, 0, 0, 748, 749, 1, 0, 0, 0, 749, 750, 5, 149, 0, 0, 750, 774, 1, 0, 0, 0, 751, 752, 3, 160, 80, 0, 752, 753, 5, 130, 0, 0, 753, 758, 3, 112, 56, 0, 754, 755, 5, 116, 0, 0, 755, 757, 3, 112, 56, 0, 756, 754, 1, 0, 0, 0, 757, 760, 1, 0, 0, 0, 758, 756, 1, 0, 0, 0, 758, 759, 1, 0, 0, 0, 759, 762, 1, 0, 0, 0, 760, 758, 1, 0, 0, 0, 761, 763, 5, 116, 0, 0, 762, 761, 1, 0, 0, 0, 762, 763, 1, 0, 0, 0, 763, 764, 1, 0, 0, 0, 764, 765, 5, 149, 0, 0, 765, 774, 1, 0, 0, 0, 766, 767, 3, 160, 80, 0, 767, 769, 5, 130, 0, 0, 768, 770, 3, 114, 57, 0, 769, 768, 1, 0, 0, 0, 769, 770, 1, 0, 0, 0, 770, 771, 1, 0, 0, 0, 771, 772, 5, 149, 0, 0, 772, 774, 1, 0, 0, 0, 773, 717, 1, 0, 0, 0, 773, 718, 1, 0, 0, 0, 773, 736, 1, 0, 0, 0, 773, 751, 1, 0, 0, 0, 773, 766, 1, 0, 0, 0, 774, 113, 1, 0, 0, 0, 775, 780, 3, 116, 58, 0, 776, 777, 5, 116, 0, 0, 777, 779, 3, 116, 58, 0, 778, 776, 1, 0, 0, 0, 779, 782, 1, 0, 0, 0, 780, 778, 1, 0, 0, 0, 780, 781, 1, 0, 0, 0, 781, 784, 1, 0, 0, 0, 782, 780, 1, 0, 0, 0, 783, 785, 5, 116, 0, 0, 784, 783, 1, 0, 0, 0, 784, 785, 1, 0, 0, 0, 785, 115, 1, 0, 0, 0, 786, 787, 6, 58, -1, 0, 787, 789, 5, 12, 0, 0, 788, 790, 3, 116, 58, 0, 789, 788, 1, 0, 0, 0, 789, 790, 1, 0, 0, 0, 790, 796, 1, 0, 0, 0, 791, 792, 5, 98, 0, 0, 792, 793, 3, 116, 58, 0, 793, 794, 5, 83, 0, 0, 794, 795, 3, 116, 58, 0, 795, 797, 1, 0, 0, 0, 796, 791, 1, 0, 0, 0, 797, 798, 1, 0, 0, 0, 798, 796, 1, 0, 0, 0, 798, 799, 1, 0, 0, 0, 799, 802, 1, 0, 0, 0, 800, 801, 5, 25, 0, 0, 801, 803, 3, 116, 58, 0, 802, 800, 1, 0, 0, 0, 802, 803, 1, 0, 0, 0, 803, 804, 1, 0, 0, 0, 804, 805, 5, 26, 0, 0, 805, 936, 1, 0, 0, 0, 806, 807, 5, 13, 0, 0, 807, 808, 5, 130, 0, 0, 808, 809, 3, 116, 58, 0, 809, 810, 5, 6, 0, 0, 810, 811, 3, 112, 56, 0, 811, 812, 5, 149, 0, 0, 812, 936, 1, 0, 0, 0, 813, 814, 5, 20, 0, 0, 814, 936, 5, 110, 0, 0, 815, 816, 5, 45, 0, 0, 816, 817, 3, 116, 58, 0, 817, 818, 3, 152, 76, 0, 818, 936, 1, 0, 0, 0, 819, 820, 5, 82, 0, 0, 820, 821, 5, 130, 0, 0, 821, 822, 3, 116, 58, 0, 822, 823, 5, 34, 0, 0, 823, 826, 3, 116, 58, 0, 824, 825, 5, 33, 0, 0, 825, 827, 3, 116, 58, 0, 826, 824, 1, 0, 0, 0, 826, 827, 1, 0, 0, 0, 827, 828, 1, 0, 0, 0, 828, 829, 5, 149, 0, 0, 829, 936, 1, 0, 0, 0, 830, 831, 5, 86, 0, 0, 831, 936, 5, 110, 0, 0, 832, 833, 5, 91, 0, 0, 833, 834, 5, 130, 0, 0, 834, 835, 7, 9, 0, 0, 835, 836, 3, 166, 83, 0, 836, 837, 5, 34, 0, 0, 837, 838, 3, 116, 58, 0, 838, 839, 5, 149, 0, 0, 839, 936, 1, 0, 0, 0, 840, 841, 3, 160, 80, 0, 841, 843, 5, 130, 0, 0, 842, 844, 3, 114, 57, 0, 843, 842, 1, 0, 0, 0, 843, 844, 1, 0, 0, 0, 844, 845, 1, 0, 0, 0, 845, 846, 5, 149, 0, 0, 846, 855, 1, 0, 0, 0, 847, 849, 5, 130, 0, 0, 848, 850, 5, 24, 0, 0, 849, 848, 1, 0, 0, 0, 849, 850, 1, 0, 0, 0, 850, 852, 1, 0, 0, 0, 851, 853, 3, 118, 59, 0, 852, 851, 1, 0, 0, 0, 852, 853, 1, 0, 0, 0, 853, 854, 1, 0, 0, 0, 854, 856, 5, 149, 0, 0, 855, 847, 1, 0, 0, 0, 855, 856, 1, 0, 0, 0, 856, 857, 1, 0, 0, 0, 857, 858, 5, 66, 0, 0, 858, 859, 5, 130, 0, 0, 859, 860, 3, 98, 49, 0, 860, 861, 5, 149, 0, 0, 861, 936, 1, 0, 0, 0, 862, 863, 3, 160, 80, 0, 863, 865, 5, 130, 0, 0, 864, 866, 3, 114, 57, 0, 865, 864, 1, 0, 0, 0, 865, 866, 1, 0, 0, 0, 866, 867, 1, 0, 0, 0, 867, 868, 5, 149, 0, 0, 868, 877, 1, 0, 0, 0, 869, 871, 5, 130, 0, 0, 870, 872, 5, 24, 0, 0, 871, 870, 1, 0, 0, 0, 871, 872, 1, 0, 0, 0, 872, 874, 1, 0, 0, 0, 873, 875, 3, 118, 59, 0, 874, 873, 1, 0, 0, 0, 874, 875, 1, 0, 0, 0, 875, 876, 1, 0, 0, 0, 876, 878, 5, 149, 0, 0, 877, 869, 1, 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 879, 1, 0, 0, 0, 879, 880, 5, 66, 0, 0, 880, 881, 3, 160, 80, 0, 881, 936, 1, 0, 0, 0, 882, 888, 3, 160, 80, 0, 883, 885, 5, 130, 0, 0, 884, 886, 3, 114, 57, 0, 885, 884, 1, 0, 0, 0, 885, 886, 1, 0, 0, 0, 886, 887, 1, 0, 0, 0, 887, 889, 5, 149, 0, 0, 888, 883, 1, 0, 0, 0, 888, 889, 1, 0, 0, 0, 889, 890, 1, 0, 0, 0, 890, 892, 5, 130, 0, 0, 891, 893, 5, 24, 0, 0, 892, 891, 1, 0, 0, 0, 892, 893, 1, 0, 0, 0, 893, 895, 1, 0, 0, 0, 894, 896, 3, 118, 59, 0, 895, 894, 1, 0, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897, 1, 0, 0, 0, 897, 898, 5, 149, 0, 0, 898, 936, 1, 0, 0, 0, 899, 936, 3, 124, 62, 0, 900, 936, 3, 168, 84, 0, 901, 936, 3, 150, 75, 0, 902, 903, 5, 118, 0, 0, 903, 936, 3, 116, 58, 19, 904, 905, 5, 58, 0, 0, 905, 936, 3, 116, 58, 13, 906, 907, 3, 140, 70, 0, 907, 908, 5, 120, 0, 0, 908, 910, 1, 0, 0, 0, 909, 906, 1, 0, 0, 0, 909, 910, 1, 0, 0, 0, 910, 911, 1, 0, 0, 0, 911, 936, 5, 112, 0, 0, 912, 913, 5, 130, 0, 0, 913, 914, 3, 44, 22, 0, 914, 915, 5, 149, 0, 0, 915, 936, 1, 0, 0, 0, 916, 917, 5, 130, 0, 0, 917, 918, 3, 116, 58, 0, 918, 919, 5, 149, 0, 0, 919, 936, 1, 0, 0, 0, 920, 921, 5, 130, 0, 0, 921, 922, 3, 114, 57, 0, 922, 923, 5, 149, 0, 0, 923, 936, 1, 0, 0, 0, 924, 926, 5, 129, 0, 0, 925, 927, 3, 114, 57, 0, 926, 925, 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, 927, 928, 1, 0, 0, 0, 928, 936, 5, 148, 0, 0, 929, 931, 5, 128, 0, 0, 930, 932, 3, 40, 20, 0, 931, 930, 1, 0, 0, 0, 931, 932, 1, 0, 0, 0, 932, 933, 1, 0, 0, 0, 933, 936, 5, 147, 0, 0, 934, 936, 3, 132, 66, 0, 935, 786, 1, 0, 0, 0, 935, 806, 1, 0, 0, 0, 935, 813, 1, 0, 0, 0, 935, 815, 1, 0, 0, 0, 935, 819, 1, 0, 0, 0, 935, 830, 1, 0, 0, 0, 935, 832, 1, 0, 0, 0, 935, 840, 1, 0, 0, 0, 935, 862, 1, 0, 0, 0, 935, 882, 1, 0, 0, 0, 935, 899, 1, 0, 0, 0, 935, 900, 1, 0, 0, 0, 935, 901, 1, 0, 0, 0, 935, 902, 1, 0, 0, 0, 935, 904, 1, 0, 0, 0, 935, 909, 1, 0, 0, 0, 935, 912, 1, 0, 0, 0, 935, 916, 1, 0, 0, 0, 935, 920, 1, 0, 0, 0, 935, 924, 1, 0, 0, 0, 935, 929, 1, 0, 0, 0, 935, 934, 1, 0, 0, 0, 936, 1041, 1, 0, 0, 0, 937, 941, 10, 18, 0, 0, 938, 942, 5, 112, 0, 0, 939, 942, 5, 151, 0, 0, 940, 942, 5, 138, 0, 0, 941, 938, 1, 0, 0, 0, 941, 939, 1, 0, 0, 0, 941, 940, 1, 0, 0, 0, 942, 943, 1, 0, 0, 0, 943, 1040, 3, 116, 58, 19, 944, 948, 10, 17, 0, 0, 945, 949, 5, 139, 0, 0, 946, 949, 5, 118, 0, 0, 947, 949, 5, 117, 0, 0, 948, 945, 1, 0, 0, 0, 948, 946, 1, 0, 0, 0, 948, 947, 1, 0, 0, 0, 949, 950, 1, 0, 0, 0, 950, 1040, 3, 116, 58, 18, 951, 976, 10, 16, 0, 0, 952, 977, 5, 121, 0, 0, 953, 977, 5, 122, 0, 0, 954, 977, 5, 133, 0, 0, 955, 977, 5, 131, 0, 0, 956, 977, 5, 132, 0, 0, 957, 977, 5, 123, 0, 0, 958, 977, 5, 124, 0, 0, 959, 961, 5, 58, 0, 0, 960, 959, 1, 0, 0, 0, 960, 961, 1, 0, 0, 0, 961, 962, 1, 0, 0, 0, 962, 964, 5, 42, 0, 0, 963, 965, 5, 15, 0, 0, 964, 963, 1, 0, 0, 0, 964, 965, 1, 0, 0, 0, 965, 977, 1, 0, 0, 0, 966, 968, 5, 58, 0, 0, 967, 966, 1, 0, 0, 0, 967, 968, 1, 0, 0, 0, 968, 969, 1, 0, 0, 0, 969, 977, 7, 10, 0, 0, 970, 977, 5, 145, 0, 0, 971, 977, 5, 146, 0, 0, 972, 977, 5, 135, 0, 0, 973, 977, 5, 126, 0, 0, 974, 977, 5, 127, 0, 0, 975, 977, 5, 134, 0, 0, 976, 952, 1, 0, 0, 0, 976, 953, 1, 0, 0, 0, 976, 954, 1, 0, 0, 0, 976, 955, 1, 0, 0, 0, 976, 956, 1, 0, 0, 0, 976, 957, 1, 0, 0, 0, 976, 958, 1, 0, 0, 0, 976, 960, 1, 0, 0, 0, 976, 967, 1, 0, 0, 0, 976, 970, 1, 0, 0, 0, 976, 971, 1, 0, 0, 0, 976, 972, 1, 0, 0, 0, 976, 973, 1, 0, 0, 0, 976, 974, 1, 0, 0, 0, 976, 975, 1, 0, 0, 0, 977, 978, 1, 0, 0, 0, 978, 1040, 3, 116, 58, 17, 979, 980, 10, 14, 0, 0, 980, 981, 5, 137, 0, 0, 981, 1040, 3, 116, 58, 15, 982, 983, 10, 12, 0, 0, 983, 984, 5, 2, 0, 0, 984, 1040, 3, 116, 58, 13, 985, 986, 10, 11, 0, 0, 986, 987, 5, 63, 0, 0, 987, 1040, 3, 116, 58, 12, 988, 990, 10, 10, 0, 0, 989, 991, 5, 58, 0, 0, 990, 989, 1, 0, 0, 0, 990, 991, 1, 0, 0, 0, 991, 992, 1, 0, 0, 0, 992, 993, 5, 9, 0, 0, 993, 994, 3, 116, 58, 0, 994, 995, 5, 2, 0, 0, 995, 996, 3, 116, 58, 11, 996, 1040, 1, 0, 0, 0, 997, 998, 10, 9, 0, 0, 998, 999, 5, 140, 0, 0, 999, 1000, 3, 116, 58, 0, 1000, 1001, 5, 115, 0, 0, 1001, 1002, 3, 116, 58, 9, 1002, 1040, 1, 0, 0, 0, 1003, 1004, 10, 25, 0, 0, 1004, 1005, 5, 129, 0, 0, 1005, 1006, 3, 116, 58, 0, 1006, 1007, 5, 148, 0, 0, 1007, 1040, 1, 0, 0, 0, 1008, 1009, 10, 24, 0, 0, 1009, 1010, 5, 120, 0, 0, 1010, 1040, 5, 108, 0, 0, 1011, 1012, 10, 23, 0, 0, 1012, 1013, 5, 120, 0, 0, 1013, 1040, 3, 160, 80, 0, 1014, 1015, 10, 22, 0, 0, 1015, 1016, 5, 136, 0, 0, 1016, 1017, 5, 129, 0, 0, 1017, 1018, 3, 116, 58, 0, 1018, 1019, 5, 148, 0, 0, 1019, 1040, 1, 0, 0, 0, 1020, 1021, 10, 21, 0, 0, 1021, 1022, 5, 136, 0, 0, 1022, 1040, 5, 108, 0, 0, 1023, 1024, 10, 20, 0, 0, 1024, 1025, 5, 136, 0, 0, 1025, 1040, 3, 160, 80, 0, 1026, 1027, 10, 15, 0, 0, 1027, 1029, 5, 46, 0, 0, 1028, 1030, 5, 58, 0, 0, 1029, 1028, 1, 0, 0, 0, 1029, 1030, 1, 0, 0, 0, 1030, 1031, 1, 0, 0, 0, 1031, 1040, 5, 59, 0, 0, 1032, 1037, 10, 8, 0, 0, 1033, 1034, 5, 6, 0, 0, 1034, 1038, 3, 160, 80, 0, 1035, 1036, 5, 6, 0, 0, 1036, 1038, 5, 110, 0, 0, 1037, 1033, 1, 0, 0, 0, 1037, 1035, 1, 0, 0, 0, 1038, 1040, 1, 0, 0, 0, 1039, 937, 1, 0, 0, 0, 1039, 944, 1, 0, 0, 0, 1039, 951, 1, 0, 0, 0, 1039, 979, 1, 0, 0, 0, 1039, 982, 1, 0, 0, 0, 1039, 985, 1, 0, 0, 0, 1039, 988, 1, 0, 0, 0, 1039, 997, 1, 0, 0, 0, 1039, 1003, 1, 0, 0, 0, 1039, 1008, 1, 0, 0, 0, 1039, 1011, 1, 0, 0, 0, 1039, 1014, 1, 0, 0, 0, 1039, 1020, 1, 0, 0, 0, 1039, 1023, 1, 0, 0, 0, 1039, 1026, 1, 0, 0, 0, 1039, 1032, 1, 0, 0, 0, 1040, 1043, 1, 0, 0, 0, 1041, 1039, 1, 0, 0, 0, 1041, 1042, 1, 0, 0, 0, 1042, 117, 1, 0, 0, 0, 1043, 1041, 1, 0, 0, 0, 1044, 1049, 3, 120, 60, 0, 1045, 1046, 5, 116, 0, 0, 1046, 1048, 3, 120, 60, 0, 1047, 1045, 1, 0, 0, 0, 1048, 1051, 1, 0, 0, 0, 1049, 1047, 1, 0, 0, 0, 1049, 1050, 1, 0, 0, 0, 1050, 1053, 1, 0, 0, 0, 1051, 1049, 1, 0, 0, 0, 1052, 1054, 5, 116, 0, 0, 1053, 1052, 1, 0, 0, 0, 1053, 1054, 1, 0, 0, 0, 1054, 119, 1, 0, 0, 0, 1055, 1058, 3, 122, 61, 0, 1056, 1058, 3, 116, 58, 0, 1057, 1055, 1, 0, 0, 0, 1057, 1056, 1, 0, 0, 0, 1058, 121, 1, 0, 0, 0, 1059, 1060, 5, 130, 0, 0, 1060, 1065, 3, 160, 80, 0, 1061, 1062, 5, 116, 0, 0, 1062, 1064, 3, 160, 80, 0, 1063, 1061, 1, 0, 0, 0, 1064, 1067, 1, 0, 0, 0, 1065, 1063, 1, 0, 0, 0, 1065, 1066, 1, 0, 0, 0, 1066, 1069, 1, 0, 0, 0, 1067, 1065, 1, 0, 0, 0, 1068, 1070, 5, 116, 0, 0, 1069, 1068, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 1071, 1, 0, 0, 0, 1071, 1072, 5, 149, 0, 0, 1072, 1085, 1, 0, 0, 0, 1073, 1078, 3, 160, 80, 0, 1074, 1075, 5, 116, 0, 0, 1075, 1077, 3, 160, 80, 0, 1076, 1074, 1, 0, 0, 0, 1077, 1080, 1, 0, 0, 0, 1078, 1076, 1, 0, 0, 0, 1078, 1079, 1, 0, 0, 0, 1079, 1082, 1, 0, 0, 0, 1080, 1078, 1, 0, 0, 0, 1081, 1083, 5, 116, 0, 0, 1082, 1081, 1, 0, 0, 0, 1082, 1083, 1, 0, 0, 0, 1083, 1085, 1, 0, 0, 0, 1084, 1059, 1, 0, 0, 0, 1084, 1073, 1, 0, 0, 0, 1085, 1086, 1, 0, 0, 0, 1086, 1087, 5, 111, 0, 0, 1087, 1088, 3, 116, 58, 0, 1088, 123, 1, 0, 0, 0, 1089, 1090, 5, 132, 0, 0, 1090, 1094, 3, 160, 80, 0, 1091, 1093, 3, 126, 63, 0, 1092, 1091, 1, 0, 0, 0, 1093, 1096, 1, 0, 0, 0, 1094, 1092, 1, 0, 0, 0, 1094, 1095, 1, 0, 0, 0, 1095, 1097, 1, 0, 0, 0, 1096, 1094, 1, 0, 0, 0, 1097, 1098, 5, 151, 0, 0, 1098, 1099, 5, 124, 0, 0, 1099, 1122, 1, 0, 0, 0, 1100, 1101, 5, 132, 0, 0, 1101, 1105, 3, 160, 80, 0, 1102, 1104, 3, 126, 63, 0, 1103, 1102, 1, 0, 0, 0, 1104, 1107, 1, 0, 0, 0, 1105, 1103, 1, 0, 0, 0, 1105, 1106, 1, 0, 0, 0, 1106, 1108, 1, 0, 0, 0, 1107, 1105, 1, 0, 0, 0, 1108, 1114, 5, 124, 0, 0, 1109, 1115, 3, 124, 62, 0, 1110, 1111, 5, 128, 0, 0, 1111, 1112, 3, 116, 58, 0, 1112, 1113, 5, 147, 0, 0, 1113, 1115, 1, 0, 0, 0, 1114, 1109, 1, 0, 0, 0, 1114, 1110, 1, 0, 0, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1116, 1, 0, 0, 0, 1116, 1117, 5, 132, 0, 0, 1117, 1118, 5, 151, 0, 0, 1118, 1119, 3, 160, 80, 0, 1119, 1120, 5, 124, 0, 0, 1120, 1122, 1, 0, 0, 0, 1121, 1089, 1, 0, 0, 0, 1121, 1100, 1, 0, 0, 0, 1122, 125, 1, 0, 0, 0, 1123, 1124, 3, 160, 80, 0, 1124, 1125, 5, 122, 0, 0, 1125, 1126, 3, 166, 83, 0, 1126, 1135, 1, 0, 0, 0, 1127, 1128, 3, 160, 80, 0, 1128, 1129, 5, 122, 0, 0, 1129, 1130, 5, 128, 0, 0, 1130, 1131, 3, 116, 58, 0, 1131, 1132, 5, 147, 0, 0, 1132, 1135, 1, 0, 0, 0, 1133, 1135, 3, 160, 80, 0, 1134, 1123, 1, 0, 0, 0, 1134, 1127, 1, 0, 0, 0, 1134, 1133, 1, 0, 0, 0, 1135, 127, 1, 0, 0, 0, 1136, 1141, 3, 130, 65, 0, 1137, 1138, 5, 116, 0, 0, 1138, 1140, 3, 130, 65, 0, 1139, 1137, 1, 0, 0, 0, 1140, 1143, 1, 0, 0, 0, 1141, 1139, 1, 0, 0, 0, 1141, 1142, 1, 0, 0, 0, 1142, 1145, 1, 0, 0, 0, 1143, 1141, 1, 0, 0, 0, 1144, 1146, 5, 116, 0, 0, 1145, 1144, 1, 0, 0, 0, 1145, 1146, 1, 0, 0, 0, 1146, 129, 1, 0, 0, 0, 1147, 1148, 3, 160, 80, 0, 1148, 1149, 5, 6, 0, 0, 1149, 1150, 5, 130, 0, 0, 1150, 1151, 3, 44, 22, 0, 1151, 1152, 5, 149, 0, 0, 1152, 1158, 1, 0, 0, 0, 1153, 1154, 3, 116, 58, 0, 1154, 1155, 5, 6, 0, 0, 1155, 1156, 3, 160, 80, 0, 1156, 1158, 1, 0, 0, 0, 1157, 1147, 1, 0, 0, 0, 1157, 1153, 1, 0, 0, 0, 1158, 131, 1, 0, 0, 0, 1159, 1167, 3, 164, 82, 0, 1160, 1161, 3, 140, 70, 0, 1161, 1162, 5, 120, 0, 0, 1162, 1164, 1, 0, 0, 0, 1163, 1160, 1, 0, 0, 0, 1163, 1164, 1, 0, 0, 0, 1164, 1165, 1, 0, 0, 0, 1165, 1167, 3, 134, 67, 0, 1166, 1159, 1, 0, 0, 0, 1166, 1163, 1, 0, 0, 0, 1167, 133, 1, 0, 0, 0, 1168, 1173, 3, 160, 80, 0, 1169, 1170, 5, 120, 0, 0, 1170, 1172, 3, 160, 80, 0, 1171, 1169, 1, 0, 0, 0, 1172, 1175, 1, 0, 0, 0, 1173, 1171, 1, 0, 0, 0, 1173, 1174, 1, 0, 0, 0, 1174, 135, 1, 0, 0, 0, 1175, 1173, 1, 0, 0, 0, 1176, 1177, 6, 68, -1, 0, 1177, 1186, 3, 140, 70, 0, 1178, 1186, 3, 138, 69, 0, 1179, 1180, 5, 130, 0, 0, 1180, 1181, 3, 44, 22, 0, 1181, 1182, 5, 149, 0, 0, 1182, 1186, 1, 0, 0, 0, 1183, 1186, 3, 124, 62, 0, 1184, 1186, 3, 164, 82, 0, 1185, 1176, 1, 0, 0, 0, 1185, 1178, 1, 0, 0, 0, 1185, 1179, 1, 0, 0, 0, 1185, 1183, 1, 0, 0, 0, 1185, 1184, 1, 0, 0, 0, 1186, 1195, 1, 0, 0, 0, 1187, 1191, 10, 3, 0, 0, 1188, 1192, 3, 158, 79, 0, 1189, 1190, 5, 6, 0, 0, 1190, 1192, 3, 160, 80, 0, 1191, 1188, 1, 0, 0, 0, 1191, 1189, 1, 0, 0, 0, 1192, 1194, 1, 0, 0, 0, 1193, 1187, 1, 0, 0, 0, 1194, 1197, 1, 0, 0, 0, 1195, 1193, 1, 0, 0, 0, 1195, 1196, 1, 0, 0, 0, 1196, 137, 1, 0, 0, 0, 1197, 1195, 1, 0, 0, 0, 1198, 1199, 3, 160, 80, 0, 1199, 1201, 5, 130, 0, 0, 1200, 1202, 3, 142, 71, 0, 1201, 1200, 1, 0, 0, 0, 1201, 1202, 1, 0, 0, 0, 1202, 1203, 1, 0, 0, 0, 1203, 1204, 5, 149, 0, 0, 1204, 139, 1, 0, 0, 0, 1205, 1206, 3, 144, 72, 0, 1206, 1207, 5, 120, 0, 0, 1207, 1209, 1, 0, 0, 0, 1208, 1205, 1, 0, 0, 0, 1208, 1209, 1, 0, 0, 0, 1209, 1210, 1, 0, 0, 0, 1210, 1211, 3, 160, 80, 0, 1211, 141, 1, 0, 0, 0, 1212, 1217, 3, 116, 58, 0, 1213, 1214, 5, 116, 0, 0, 1214, 1216, 3, 116, 58, 0, 1215, 1213, 1, 0, 0, 0, 1216, 1219, 1, 0, 0, 0, 1217, 1215, 1, 0, 0, 0, 1217, 1218, 1, 0, 0, 0, 1218, 1221, 1, 0, 0, 0, 1219, 1217, 1, 0, 0, 0, 1220, 1222, 5, 116, 0, 0, 1221, 1220, 1, 0, 0, 0, 1221, 1222, 1, 0, 0, 0, 1222, 143, 1, 0, 0, 0, 1223, 1224, 3, 160, 80, 0, 1224, 145, 1, 0, 0, 0, 1225, 1234, 5, 106, 0, 0, 1226, 1227, 5, 120, 0, 0, 1227, 1234, 7, 11, 0, 0, 1228, 1229, 5, 108, 0, 0, 1229, 1231, 5, 120, 0, 0, 1230, 1232, 7, 11, 0, 0, 1231, 1230, 1, 0, 0, 0, 1231, 1232, 1, 0, 0, 0, 1232, 1234, 1, 0, 0, 0, 1233, 1225, 1, 0, 0, 0, 1233, 1226, 1, 0, 0, 0, 1233, 1228, 1, 0, 0, 0, 1234, 147, 1, 0, 0, 0, 1235, 1237, 7, 12, 0, 0, 1236, 1235, 1, 0, 0, 0, 1236, 1237, 1, 0, 0, 0, 1237, 1244, 1, 0, 0, 0, 1238, 1245, 3, 146, 73, 0, 1239, 1245, 5, 107, 0, 0, 1240, 1245, 5, 108, 0, 0, 1241, 1245, 5, 109, 0, 0, 1242, 1245, 5, 43, 0, 0, 1243, 1245, 5, 57, 0, 0, 1244, 1238, 1, 0, 0, 0, 1244, 1239, 1, 0, 0, 0, 1244, 1240, 1, 0, 0, 0, 1244, 1241, 1, 0, 0, 0, 1244, 1242, 1, 0, 0, 0, 1244, 1243, 1, 0, 0, 0, 1245, 149, 1, 0, 0, 0, 1246, 1250, 3, 148, 74, 0, 1247, 1250, 5, 110, 0, 0, 1248, 1250, 5, 59, 0, 0, 1249, 1246, 1, 0, 0, 0, 1249, 1247, 1, 0, 0, 0, 1249, 1248, 1, 0, 0, 0, 1250, 151, 1, 0, 0, 0, 1251, 1252, 7, 13, 0, 0, 1252, 153, 1, 0, 0, 0, 1253, 1254, 7, 14, 0, 0, 1254, 155, 1, 0, 0, 0, 1255, 1256, 7, 15, 0, 0, 1256, 157, 1, 0, 0, 0, 1257, 1260, 5, 105, 0, 0, 1258, 1260, 3, 156, 78, 0, 1259, 1257, 1, 0, 0, 0, 1259, 1258, 1, 0, 0, 0, 1260, 159, 1, 0, 0, 0, 1261, 1265, 5, 105, 0, 0, 1262, 1265, 3, 152, 76, 0, 1263, 1265, 3, 154, 77, 0, 1264, 1261, 1, 0, 0, 0, 1264, 1262, 1, 0, 0, 0, 1264, 1263, 1, 0, 0, 0, 1265, 161, 1, 0, 0, 0, 1266, 1267, 3, 166, 83, 0, 1267, 1268, 5, 122, 0, 0, 1268, 1269, 3, 148, 74, 0, 1269, 163, 1, 0, 0, 0, 1270, 1271, 5, 128, 0, 0, 1271, 1272, 3, 134, 67, 0, 1272, 1273, 5, 147, 0, 0, 1273, 165, 1, 0, 0, 0, 1274, 1277, 5, 110, 0, 0, 1275, 1277, 3, 168, 84, 0, 1276, 1274, 1, 0, 0, 0, 1276, 1275, 1, 0, 0, 0, 1277, 167, 1, 0, 0, 0, 1278, 1282, 5, 142, 0, 0, 1279, 1281, 3, 170, 85, 0, 1280, 1279, 1, 0, 0, 0, 1281, 1284, 1, 0, 0, 0, 1282, 1280, 1, 0, 0, 0, 1282, 1283, 1, 0, 0, 0, 1283, 1285, 1, 0, 0, 0, 1284, 1282, 1, 0, 0, 0, 1285, 1286, 5, 144, 0, 0, 1286, 169, 1, 0, 0, 0, 1287, 1288, 5, 157, 0, 0, 1288, 1289, 3, 116, 58, 0, 1289, 1290, 5, 147, 0, 0, 1290, 1293, 1, 0, 0, 0, 1291, 1293, 5, 156, 0, 0, 1292, 1287, 1, 0, 0, 0, 1292, 1291, 1, 0, 0, 0, 1293, 171, 1, 0, 0, 0, 1294, 1298, 5, 143, 0, 0, 1295, 1297, 3, 174, 87, 0, 1296, 1295, 1, 0, 0, 0, 1297, 1300, 1, 0, 0, 0, 1298, 1296, 1, 0, 0, 0, 1298, 1299, 1, 0, 0, 0, 1299, 1301, 1, 0, 0, 0, 1300, 1298, 1, 0, 0, 0, 1301, 1302, 5, 0, 0, 1, 1302, 173, 1, 0, 0, 0, 1303, 1304, 5, 159, 0, 0, 1304, 1305, 3, 116, 58, 0, 1305, 1306, 5, 147, 0, 0, 1306, 1309, 1, 0, 0, 0, 1307, 1309, 5, 158, 0, 0, 1308, 1303, 1, 0, 0, 0, 1308, 1307, 1, 0, 0, 0, 1309, 175, 1, 0, 0, 0, 168, 179, 186, 195, 202, 206, 220, 224, 227, 231, 234, 241, 245, 254, 259, 268, 276, 283, 287, 293, 298, 306, 313, 319, 331, 339, 353, 357, 362, 372, 381, 384, 388, 391, 395, 398, 401, 404, 407, 411, 415, 418, 421, 424, 428, 431, 440, 446, 467, 484, 501, 507, 513, 524, 526, 537, 540, 546, 554, 560, 562, 566, 571, 574, 577, 581, 585, 588, 590, 593, 597, 601, 604, 606, 608, 613, 624, 630, 637, 642, 646, 650, 656, 658, 665, 673, 676, 679, 698, 712, 728, 732, 743, 747, 758, 762, 769, 773, 780, 784, 789, 798, 802, 826, 843, 849, 852, 855, 865, 871, 874, 877, 885, 888, 892, 895, 909, 926, 931, 935, 941, 948, 960, 964, 967, 976, 990, 1029, 1037, 1039, 1041, 1049, 1053, 1057, 1065, 1069, 1078, 1082, 1084, 1094, 1105, 1114, 1121, 1134, 1141, 1145, 1157, 1163, 1166, 1173, 1185, 1191, 1195, 1201, 1208, 1217, 1221, 1231, 1233, 1236, 1244, 1249, 1259, 1264, 1276, 1282, 1292, 1298, 1308] \ No newline at end of file diff --git a/posthog/hogql/grammar/HogQLParser.py b/posthog/hogql/grammar/HogQLParser.py index 6865c4c553220..f3a1844f404d3 100644 --- a/posthog/hogql/grammar/HogQLParser.py +++ b/posthog/hogql/grammar/HogQLParser.py @@ -513,7 +513,7 @@ def serializedATN(): 76,0,1263,1265,3,154,77,0,1264,1261,1,0,0,0,1264,1262,1,0,0,0,1264, 1263,1,0,0,0,1265,161,1,0,0,0,1266,1267,3,166,83,0,1267,1268,5,122, 0,0,1268,1269,3,148,74,0,1269,163,1,0,0,0,1270,1271,5,128,0,0,1271, - 1272,3,160,80,0,1272,1273,5,147,0,0,1273,165,1,0,0,0,1274,1277,5, + 1272,3,134,67,0,1272,1273,5,147,0,0,1273,165,1,0,0,0,1274,1277,5, 110,0,0,1275,1277,3,168,84,0,1276,1274,1,0,0,0,1276,1275,1,0,0,0, 1277,167,1,0,0,0,1278,1282,5,142,0,0,1279,1281,3,170,85,0,1280,1279, 1,0,0,0,1281,1284,1,0,0,0,1282,1280,1,0,0,0,1282,1283,1,0,0,0,1283, @@ -9725,8 +9725,8 @@ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): def LBRACE(self): return self.getToken(HogQLParser.LBRACE, 0) - def identifier(self): - return self.getTypedRuleContext(HogQLParser.IdentifierContext,0) + def nestedIdentifier(self): + return self.getTypedRuleContext(HogQLParser.NestedIdentifierContext,0) def RBRACE(self): @@ -9753,7 +9753,7 @@ def placeholder(self): self.state = 1270 self.match(HogQLParser.LBRACE) self.state = 1271 - self.identifier() + self.nestedIdentifier() self.state = 1272 self.match(HogQLParser.RBRACE) except RecognitionException as re: diff --git a/posthog/hogql/parser.py b/posthog/hogql/parser.py index a056d9fc682f6..96afe5ae15bc5 100644 --- a/posthog/hogql/parser.py +++ b/posthog/hogql/parser.py @@ -1120,8 +1120,8 @@ def visitHogqlxTagAttribute(self, ctx: HogQLParser.HogqlxTagAttributeContext): return ast.HogQLXAttribute(name=name, value=ast.Constant(value=True)) def visitPlaceholder(self, ctx: HogQLParser.PlaceholderContext): - name = self.visit(ctx.identifier()) - return ast.Placeholder(field=name) + nested = self.visit(ctx.nestedIdentifier()) if ctx.nestedIdentifier() else [] + return ast.Placeholder(chain=nested) def visitColumnExprTemplateString(self, ctx: HogQLParser.ColumnExprTemplateStringContext): return self.visit(ctx.templateString()) diff --git a/posthog/hogql/query.py b/posthog/hogql/query.py index 23b8c52b5f0a2..885801870df02 100644 --- a/posthog/hogql/query.py +++ b/posthog/hogql/query.py @@ -76,9 +76,17 @@ def execute_hogql_query( raise ValueError( f"Query contains 'filters' placeholder, yet filters are also provided as a standalone query parameter." ) - if "filters" in placeholders_in_query: + if "filters" in placeholders_in_query or any( + placeholder.startswith("filters.") for placeholder in placeholders_in_query + ): select_query = replace_filters(select_query, filters, team) - placeholders_in_query.remove("filters") + + leftover_placeholders: list[str] = [] + for placeholder in placeholders_in_query: + if placeholder != "filters" and not placeholder.startswith("filters."): + leftover_placeholders.append(placeholder) + + placeholders_in_query = leftover_placeholders if len(placeholders_in_query) > 0: if len(placeholders) == 0: diff --git a/posthog/hogql/test/_test_parser.py b/posthog/hogql/test/_test_parser.py index e612a156762e6..7d59d71a13657 100644 --- a/posthog/hogql/test/_test_parser.py +++ b/posthog/hogql/test/_test_parser.py @@ -643,7 +643,7 @@ def test_expr_with_ignored_sql_comment(self): def test_placeholders(self): self.assertEqual( self._expr("{foo}"), - ast.Placeholder(field="foo"), + ast.Placeholder(chain=["foo"]), ) self.assertEqual( self._expr("{foo}", {"foo": ast.Constant(value="bar")}), @@ -854,7 +854,7 @@ def test_select_from_placeholder(self): self._select("select 1 from {placeholder}"), ast.SelectQuery( select=[ast.Constant(value=1)], - select_from=ast.JoinExpr(table=ast.Placeholder(field="placeholder")), + select_from=ast.JoinExpr(table=ast.Placeholder(chain=["placeholder"])), ), ) self.assertEqual( @@ -1244,7 +1244,7 @@ def test_select_placeholders(self): where=ast.CompareOperation( op=ast.CompareOperationOp.Eq, left=ast.Constant(value=1), - right=ast.Placeholder(field="hogql_val_1"), + right=ast.Placeholder(chain=["hogql_val_1"]), ), ), ) diff --git a/posthog/hogql/test/test_placeholders.py b/posthog/hogql/test/test_placeholders.py index 53fcec12d9048..c19409dfb90b5 100644 --- a/posthog/hogql/test/test_placeholders.py +++ b/posthog/hogql/test/test_placeholders.py @@ -15,7 +15,7 @@ def test_replace_placeholders_simple(self): expr = parse_expr("{foo}") self.assertEqual( expr, - ast.Placeholder(field="foo", start=0, end=5), + ast.Placeholder(chain=["foo"], start=0, end=5), ) expr2 = replace_placeholders(expr, {"foo": ast.Constant(value="bar")}) self.assertEqual( @@ -24,7 +24,7 @@ def test_replace_placeholders_simple(self): ) def test_replace_placeholders_error(self): - expr = ast.Placeholder(field="foo") + expr = ast.Placeholder(chain=["foo"]) with self.assertRaises(QueryError) as context: replace_placeholders(expr, {}) self.assertEqual( @@ -47,7 +47,7 @@ def test_replace_placeholders_comparison(self): end=23, op=ast.CompareOperationOp.Lt, left=ast.Field(chain=["timestamp"], start=0, end=9), - right=ast.Placeholder(field="timestamp", start=12, end=23), + right=ast.Placeholder(chain=["timestamp"], start=12, end=23), ), ) expr2 = replace_placeholders(expr, {"timestamp": ast.Constant(value=123)}) @@ -63,7 +63,7 @@ def test_replace_placeholders_comparison(self): ) def test_assert_no_placeholders(self): - expr = ast.Placeholder(field="foo") + expr = ast.Placeholder(chain=["foo"]) with self.assertRaises(QueryError) as context: replace_placeholders(expr, None) self.assertEqual( diff --git a/posthog/hogql/test/test_visitor.py b/posthog/hogql/test/test_visitor.py index 96bb69233b2fd..acaa7a083e541 100644 --- a/posthog/hogql/test/test_visitor.py +++ b/posthog/hogql/test/test_visitor.py @@ -58,7 +58,7 @@ def test_everything_visitor(self): args=[ ast.Alias( alias="d", - expr=ast.Placeholder(field="e"), + expr=ast.Placeholder(chain=["e"]), ), ast.OrderExpr( expr=ast.Field(chain=["c"]), diff --git a/posthog/hogql/visitor.py b/posthog/hogql/visitor.py index 00eb6723d1071..025ecc5f52e92 100644 --- a/posthog/hogql/visitor.py +++ b/posthog/hogql/visitor.py @@ -493,7 +493,7 @@ def visit_placeholder(self, node: ast.Placeholder): start=None if self.clear_locations else node.start, end=None if self.clear_locations else node.end, type=None if self.clear_types else node.type, - field=node.field, + chain=node.chain, ) def visit_call(self, node: ast.Call): diff --git a/posthog/hogql_queries/error_tracking_query_runner.py b/posthog/hogql_queries/error_tracking_query_runner.py index 6631972fc3da2..95f5b4a7577ad 100644 --- a/posthog/hogql_queries/error_tracking_query_runner.py +++ b/posthog/hogql_queries/error_tracking_query_runner.py @@ -128,7 +128,7 @@ def where(self): left=ast.Field(chain=["event"]), right=ast.Constant(value="$exception"), ), - ast.Placeholder(field="filters"), + ast.Placeholder(chain=["filters"]), ] if self.query.fingerprint: diff --git a/posthog/hogql_queries/insights/trends/aggregation_operations.py b/posthog/hogql_queries/insights/trends/aggregation_operations.py index 03bff00e2aaf2..908f3b7464cae 100644 --- a/posthog/hogql_queries/insights/trends/aggregation_operations.py +++ b/posthog/hogql_queries/insights/trends/aggregation_operations.py @@ -175,9 +175,9 @@ def select_aggregation(self) -> ast.Expr: actor = "e.distinct_id" if self.team.aggregate_users_by_distinct_id else "e.person_id" return parse_expr(f"count(DISTINCT {actor})") elif self.series.math == "weekly_active": - return ast.Placeholder(field="replaced") # This gets replaced when doing query orchestration + return ast.Placeholder(chain=["replaced"]) # This gets replaced when doing query orchestration elif self.series.math == "monthly_active": - return ast.Placeholder(field="replaced") # This gets replaced when doing query orchestration + return ast.Placeholder(chain=["replaced"]) # This gets replaced when doing query orchestration elif self.series.math == "unique_session": return parse_expr('count(DISTINCT e."$session_id")') elif self.series.math == "unique_group" and self.series.math_group_type_index is not None: diff --git a/posthog/hogql_queries/insights/trends/having.sql b/posthog/hogql_queries/insights/trends/having.sql deleted file mode 100644 index ed8045610a9a7..0000000000000 --- a/posthog/hogql_queries/insights/trends/having.sql +++ /dev/null @@ -1,11 +0,0 @@ -SELECT - toStartOfDay(min(timestamp)) as day_start, - argMin(ifNull(nullIf(toString(person.properties.email), ''), '$$_posthog_breakdown_null_$$'), timestamp) AS breakdown_value -FROM - events AS e SAMPLE 1 -WHERE - lessOrEquals(timestamp, assumeNotNull(toDateTime('2024-07-23 23:59:59'))) and event = '$pageview' -GROUP BY - person_id -HAVING - equals(properties.$browser, 'Safari') diff --git a/posthog/hogql_queries/web_analytics/stats_table.py b/posthog/hogql_queries/web_analytics/stats_table.py index 38a2a58706afa..889cceab5e22b 100644 --- a/posthog/hogql_queries/web_analytics/stats_table.py +++ b/posthog/hogql_queries/web_analytics/stats_table.py @@ -515,6 +515,10 @@ def where_breakdown(self): return parse_expr("TRUE") # actually show null values case WebStatsBreakdown.INITIAL_UTM_CONTENT: return parse_expr("TRUE") # actually show null values + case WebStatsBreakdown.INITIAL_CHANNEL_TYPE: + return parse_expr( + "breakdown_value IS NOT NULL AND breakdown_value != ''" + ) # we need to check for empty strings as well due to how the left join works case _: return parse_expr("breakdown_value IS NOT NULL") diff --git a/posthog/hogql_queries/web_analytics/test/test_web_stats_table.py b/posthog/hogql_queries/web_analytics/test/test_web_stats_table.py index 088942335c7eb..953e94319de4f 100644 --- a/posthog/hogql_queries/web_analytics/test/test_web_stats_table.py +++ b/posthog/hogql_queries/web_analytics/test/test_web_stats_table.py @@ -951,3 +951,42 @@ def test_same_user_multiple_sessions(self): include_scroll_depth=True, ).results assert [["/path", 1, 2, None, None, None]] == results_event + + def test_no_session_id(self): + d1 = "d1" + _create_person( + team_id=self.team.pk, + distinct_ids=[d1], + properties={ + "name": d1, + }, + ) + _create_event( + team=self.team, + event="$pageview", + distinct_id=d1, + timestamp="2024-07-30", + properties={"utm_source": "google", "$pathname": "/path"}, + ) + + # Don't show session property breakdowns type of sessions with no session id + results = self._run_web_stats_table_query( + "all", + "2024-07-31", + breakdown_by=WebStatsBreakdown.INITIAL_CHANNEL_TYPE, + ).results + assert [] == results + results = self._run_web_stats_table_query( + "all", + "2024-07-31", + breakdown_by=WebStatsBreakdown.INITIAL_PAGE, + ).results + assert [] == results + + # Do show event property breakdowns of events of events with no session id + results = self._run_web_stats_table_query( + "all", + "2024-07-31", + breakdown_by=WebStatsBreakdown.PAGE, + ).results + assert [["/path", 1, 1]] == results diff --git a/posthog/management/commands/change_plugin_config_referenced_plugin.py b/posthog/management/commands/change_plugin_config_referenced_plugin.py index 32b1984e5c593..3c275bb4db9e3 100644 --- a/posthog/management/commands/change_plugin_config_referenced_plugin.py +++ b/posthog/management/commands/change_plugin_config_referenced_plugin.py @@ -51,4 +51,4 @@ def handle(self, *args, **options): updated = found_configs.update(plugin=new_plugin) print(f"Updated {updated} rows") # noqa T201 else: - print(f"Would update {len(target_ids)} rows") # noqa T201 + print(f"Would update {len(found_configs)} rows") # noqa T201 diff --git a/posthog/models/cohort/sql.py b/posthog/models/cohort/sql.py index 74674487f69bb..a84394bae94a8 100644 --- a/posthog/models/cohort/sql.py +++ b/posthog/models/cohort/sql.py @@ -46,7 +46,7 @@ SELECT person_id, cohort_id, team_id, -1, version FROM cohortpeople WHERE team_id = %(team_id)s AND cohort_id = %(cohort_id)s AND version < %(new_version)s AND sign = 1 -SETTINGS optimize_aggregation_in_order = 1 +SETTINGS optimize_aggregation_in_order = 1, join_algorithm = 'auto' """ # NOTE: Group by version id to ensure that signs are summed between corresponding rows. diff --git a/posthog/schema.py b/posthog/schema.py index 68a009d5e910a..0e81729b65f8a 100644 --- a/posthog/schema.py +++ b/posthog/schema.py @@ -146,13 +146,6 @@ class StatusItem(BaseModel): value: str -class ChartAxis(BaseModel): - model_config = ConfigDict( - extra="forbid", - ) - column: str - - class ChartDisplayType(StrEnum): ACTIONS_LINE_GRAPH = "ActionsLineGraph" ACTIONS_BAR = "ActionsBar" @@ -166,6 +159,22 @@ class ChartDisplayType(StrEnum): WORLD_MAP = "WorldMap" +class Style(StrEnum): + NONE = "none" + NUMBER = "number" + PERCENT = "percent" + + +class ChartSettingsFormatting(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + decimalPlaces: Optional[float] = None + prefix: Optional[str] = None + style: Optional[Style] = None + suffix: Optional[str] = None + + class ClickhouseQueryProgress(BaseModel): model_config = ConfigDict( extra="forbid", @@ -1851,6 +1860,30 @@ class CachedWebTopClicksQueryResponse(BaseModel): types: Optional[list] = None +class Settings(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + formatting: Optional[ChartSettingsFormatting] = None + + +class ChartAxis(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + column: str + settings: Optional[Settings] = None + + +class ChartSettings(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + goalLines: Optional[list[GoalLine]] = None + xAxis: Optional[ChartAxis] = None + yAxis: Optional[list[ChartAxis]] = None + + class Response(BaseModel): model_config = ConfigDict( extra="forbid", @@ -2009,15 +2042,6 @@ class Response7(BaseModel): ) -class ChartSettings(BaseModel): - model_config = ConfigDict( - extra="forbid", - ) - goalLines: Optional[list[GoalLine]] = None - xAxis: Optional[ChartAxis] = None - yAxis: Optional[list[ChartAxis]] = None - - class DataWarehousePersonPropertyFilter(BaseModel): model_config = ConfigDict( extra="forbid", diff --git a/posthog/settings/web.py b/posthog/settings/web.py index 0a88799f33375..01b2211b1e6e1 100644 --- a/posthog/settings/web.py +++ b/posthog/settings/web.py @@ -380,3 +380,6 @@ def add_recorder_js_headers(headers, path, url): PROXY_BASE_CNAME = get_from_env("PROXY_BASE_CNAME", "") LOGO_DEV_TOKEN = get_from_env("LOGO_DEV_TOKEN", "") + +# disables frontend side navigation hooks to make hot-reload work seamlessly +DEV_DISABLE_NAVIGATION_HOOKS = get_from_env("DEV_DISABLE_NAVIGATION_HOOKS", False, type_cast=bool) diff --git a/posthog/views.py b/posthog/views.py index 76a823762b656..139da5bbea4f8 100644 --- a/posthog/views.py +++ b/posthog/views.py @@ -130,6 +130,9 @@ def preflight_check(request: HttpRequest) -> JsonResponse: if settings.DEBUG or settings.E2E_TESTING: response["is_debug"] = True + if settings.DEV_DISABLE_NAVIGATION_HOOKS: + response["dev_disable_navigation_hooks"] = True + if request.user.is_authenticated: response = { **response, diff --git a/requirements.in b/requirements.in index a55aaac74941d..6bfca0b23f82f 100644 --- a/requirements.in +++ b/requirements.in @@ -96,7 +96,7 @@ phonenumberslite==8.13.6 openai==1.10.0 tiktoken==0.6.0 nh3==0.2.14 -hogql-parser==1.0.32 +hogql-parser==1.0.35 zxcvbn==4.4.28 zstd==1.5.5.1 xmlsec==1.3.13 # Do not change this version - it will break SAML diff --git a/requirements.txt b/requirements.txt index 0586b8631f540..89b328f6ccc45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -275,7 +275,7 @@ h11==0.13.0 # wsproto hexbytes==1.0.0 # via dlt -hogql-parser==1.0.32 +hogql-parser==1.0.35 # via -r requirements.in httpcore==1.0.2 # via httpx